I have some events in a database for my event registrations application, where the dates may be set by
public DateTime? DateStart { get; set; }
public DateTime? DateEnd { get; set; }
Both fields are nullable, and I want to get ongoing events if eiter
1) DateStart is same date as today, or
2) Now is between DateStart and DateEnd
public async Task<List<EventInfo>> GetOngoingEventsAsync()
{
return await _db.EventInfos
.Where(i =>
i.Published &&
i.DateStart.Value.Date == DateTime.Now.Date ||
i.DateStart.Value.Date <= DateTime.Now.Date <= i.DateEnd.Value.Date)
.OrderBy(s => s.DateStart)
.ToListAsync();
}
However my code above returns: Operator '<=' cannot be applied to operands of type 'bool' and 'DateTime'
The reason behind the error was the first part of the condition i.DateStart.Value.Date <= DateTime.Now.Date will be validated and will be converted to Boolean. After that you were trying to compare Boolean with DateTime like so <= i.DateEnd.Value.Date. So that's why I separate the two conditions with && operator.
(DateTime.Now.Date >= i.DateStart.Value.Date && DateTime.Now.Date <= i.DateEnd.Value.Date)
This should be the correct form of your code:
(DateTime.Now.Date >= i.DateStart.Value.Date && DateTime.Now.Date <= i.DateEnd.Value.Date)
Related
I have a table in my entity model called prices. It has several fields named value0, value1, value2, value3, value4... (these are their literal names, sigh..). I cannot rename them or in any way change them.
What I would like is to use an extended entity to create a new property called values. This would be a collection containing value1, value2 etc...
To get access to the values I would then simply need to write prices.values[1]
I need property changed notification for this.
So far I have tried this;
public partial class Prices
{
private ObservableCollection<double?> values = null;
public ObservableCollection<double?> Values
{
get
{
if (values != null)
values.CollectionChanged -= values_CollectionChanged;
else
values = new ObservableCollection<double?>(new double?[14]);
values[0] = value0;
values[1] = value1;
values[2] = value2;
values.CollectionChanged += values_CollectionChanged;
return values;
}
private set
{
value0 = value[0];
value1 = value[1];
value2 = value[2];
}
}
private void values_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Values = values;
}
}
The issue comes when trying to set values. if I try to set a value by writing
prices.values[0] = someValue;
The new value is not always reflected in the collection (i.e. when I have previously set value and then try to overwrite the value).
I am willing to try any approach that would achieve my goal, I am not precious about having my solution fixed (although if anyone can explain what I'm missing that would be great!)
You could implement an indexer on Prices class without using a collection.
You can use switch to select the property to write or you can use reflection.
In this case I use reflection.
public double? this[int index]
{
get
{
if (index < 0 || index > 13) throw new ArgumentOutOfRangeException("index");
string propertyName = "Value" + index;
return (double?)GetType().GetProperty(propertyName).GetValue(this);
}
set
{
if (index < 0 || index > 13) throw new ArgumentOutOfRangeException("index");
string propertyName = "Value" + index;
GetType().GetProperty(propertyName).SetValue(this, value);
// Raise your event here
}
}
I have a couple of Entity Framework functions that only differ in operators, e.g.
public int GetCountEqual(int i)
{
return Context.Entity.Where(e => e.Value == i).Count();
}
public int GetCountLess(int i)
{
return Context.Entity.Where(e => e.Value < i).Count();
}
public int GetCountLessOrEqual(int i)
{
return Context.Entity.Where(e => e.Value <= i).Count();
}
and so on. Obviously, this is a dumbed down version of my real program...
I guess it must be possible to somehow pass the operator as a parameter / lambda expression (since they're sort of canonical), but whatever I've tried so far along those lines results in the infamous
"The LINQ expression node type 'Invoke' is not supported in LINQ to Entities."
error.
Any hints as to how to pass a comparison function as a parameter so that it can be translated into SQL? The query needs to run at the database level, I can't load the entities into memory and then run a lambda there...
public int GetCount(Expression<Func<Entity, bool>> whereExpression)
{
return Context.Entity.Where(whereExpression).Count();
}
int countEqual = GetCountEqual(e => e.Value == i);
int countLess = GetCountEqual(e => e.Value < i);
int countLessOrEqual = GetCountEqual(e => e.Value <= i);
I am using Drools 4 and when I am comparing two hashmap values with == it is not working. All other operators like >=,<=,<,>,!= are working fine. I am comparing as below. I am using map as . Is there any thing wrong with the statement. The map values will be updated in actions of the rules. I am able to see the updated values in map but comparison of the values is failing. I am using update(abc) to update the values.
eval((abc.getValue("123")).intValue() == (abc.getValue("456")).intValue())
Rule:
rule "008"
salience -18
agenda-group "CAP"
auto-focus true
when
testObj: TestObj(eval(fireNextPriority==true), categoryCount==18,
eval(!firedRules.contains(Integer.valueOf(23449)))
&& (date >= 1263925800000)
&& (date <= 4102338600000) && (date >= 1263925800000) && (date <= 4102338600000)
&& eval(1 == 1)
&& eval(testObj.getVariableValue("C1TC") == testObj.getVariableValue("Y1TC")))
then
System.out.println("Firing rule: CAP - 008");
testObj.setStatus(true);
testObj.setPriority(1);
testObj.addToFiredRules(23449);
update(testObj);
testObj.addVariableValue("C1PC", testObj.getVariableValue("C1PC")-
testObj.getVariableValue("C1OF"));
end
Object which we are using:
public class TestObj{
Long date;
Integer categoryCount;
boolean status = false;
boolean executeFinalRule = false;
boolean executeFinalRuleForCatg = true;
boolean fireNextPriority = true;
Set<Integer> firedRules = new HashSet<Integer>();
private int priority;
Map<String, Integer> variableValues = new HashMap<String, Integer>();
public Integer getCategoryCount() {
return categoryCount;
}
public void setCategoryCount(Integer categoryCount) {
this.categoryCount = categoryCount;
}
public void increaseCategoryCount(){
this.categoryCount++;
}
public void addVariableValue(String variableCode, Integer count){
if (count < 0) count = 0;
this.variableValues.put(variableCode, count);
}
public Integer getVariableValue(String variableCode){
Integer value = this.variableValues.get(variableCode);
return value == null? 0 : value;
}
public boolean isStatus() {
return status;
}
public Set<Integer> getFiredRules() {
return firedRules;
}
public void setFiredRules(Set<Integer> firedRules) {
this.firedRules = firedRules;
}
public void addToFiredRules(int l){
this.firedRules.add(l);
}
}
Thanks in advance.
I've never used Drools 4.x, so these are observations based of my (old) knowledge of 5.1.1 - they may not be accurate in your case.
eval(fireNextPriority==true)
It's remarkable that this works. eval does not maintain the context of the enclosing pattern (fact), so normally you'd have to write
eval(!firedRules.contains(Integer.valueOf(23449))
Same thing.
eval(testObj.getVariableValue("C1TC") == testObj.getVariableValue("Y1TC"))
This is as I'd write it from 5.1 onwards.
The strange thing is
testObj.addVariableValue("C1PC", testObj.getVariableValue("C1PC")
testObj.getVariableValue("C1OF"));
(DID I MESS THIS UP WHILE EDITING?) These changes are after the update call, which means that they won't be seen by the engine. Has the update of map entries "C1TC" and/or "Y1TC" been done likewise in another rule? Then they won't be equal to Drools, even if they are to Java...
In my MVC web application I am creating a search function where i need to compare a search string with objects in my product repository - But how do I make sure that the search is not case sensitive?
I can use ToLower() on my search string - but the repository?
Controller:
public ActionResult Search(string q, int page = 1)
{
string search = q.ToLower();
int productCounter = repository.Products.Where(p => p.Name.Contains(search) || p.Description.Contains(search)).Count();
ProductsListViewModel model = new ProductsListViewModel
{
Products = repository.Products
.Where(p => p.Name.Contains(search) || p.Description.Contains(search))
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = productCounter == 0 ? 0 : productCounter
}
};
return View("List", model);
}
You can replace this:
p.Name.Contains(search)
with this:
p.Name.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0
You can use IndexOf to get access to IgnoreCase in In memory collections.
You may be disappointed when you apply this to EF provider scenarios.
Is this correctly tagged EF ?
EF Provider specification does not use IndexOf.
For that matter the Contains(str,comparer) is also not supported.
Supported Linq to Entities features
If using SQLServer with EF the original issue is governed by the column collation property. eg SQL_Latin1_General_CP1_CI_AS case insensitive latin.
If you have DB first, you control the collation sequence at DB level.
All explained here nicely ... LINQ to Entities case sensitive comparison
If using code first the DEFAULT sql server db collation is used.
more info on default collation Set database collation in Entity Framework Code-First Initializer
You can use Invariant Culture and enhance the query a bit by using Length as well:
public ActionResult Search(string q, int page = 1)
{
string s;
string search = q.ToUpperInvariant();
int productCounter = repository.Products.Where(p => p.Name.ToUpperInvariant().Contains(search) || p.Description.ToUpperInvariant().Contains(search)).Count();
int searchlength = search.Length;
ProductsListViewModel model = new ProductsListViewModel
{
Products = repository.Products
.Where(p => (p.Name.Length >= searchlength && p.Name.ToUpperInvariant().Contains(search)) || (p.Description.Length >= searchlength && p.Description.ToUpperInvariant().Contains(search)))
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = productCounter == 0 ? 0 : productCounter
}
};
return View("List", model);
}
I know such questions are repeated but I did not get any result.I must change helical date to Gregorian date and this is my method
public static DateTime ShamsiToMiladi(string shmasi)
{
DateTime? Dt = null;
if (shmasi != "")
{
System.Globalization.PersianCalendar persian = new System.Globalization.PersianCalendar();
char[] spChar = { '/' };
string[] splited_shamsi = shmasi.Split(spChar, 3);
Dt = persian.ToDateTime(int.Parse(splited_shamsi[0]), int.Parse(splited_shamsi[1]), int.Parse(splited_shamsi[2]), 12, 12, 12, 12);
}
return Dt;
}
sahmsi is a parameter that comes from a textbox.what do i return Dt?
thanks for help
Since DateTime is actually a structure built upon a long integer, it cannot be assigned a null value.
But if you need to have that option, declare it as a nullable DateTime thusly:
DateTime? ThisDate = null;
If you do return a nullable DateTime, your caller will have to check for a null value before using as a regular DateTime in expressions.
As a general rule, a newly-declared regular DateTime has a value of DateTime.MinValue ('01/01/0000'), and you can test for that, instead.