我需要构建一个“between”函数来检查日期是否包含在2个日期的范围内。我写了这个,但它不起作用:
private static Expression<Func<TElement, bool>> IsDateBetween<TElement>(Expression<Func<TElement, object>> valueSelector, DateTime date)
{
var p = valueSelector.Parameters.Single();
var after = Expression.LessThanOrEqual(
Expression.Property(valueSelector.Body, "FromDate"), Expression.Constant(date.Date, typeof(DateTime)));
var before = Expression.GreaterThanOrEqual(
Expression.Property(valueSelector.Body, "ToDate"), Expression.Constant(date.Date, typeof(DateTime)));
Expression body = Expression.And(after, before);
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
我这样称呼它:
DataContext.EventHistories.Where(IsDateBetween<EventHistory>(h => new { h.FromDate, h.ToDate }, dateInTheMiddle))
我必须使用这种方式,因为linq实体不支持日期。
由于
答案 0 :(得分:3)
你可以尝试类似的东西
public static IQueryable<TElement> IsDateBetween<TElement>(this IQueryable<TElement> queryable,
Expression<Func<TElement, DateTime>> fromDate,
Expression<Func<TElement, DateTime>> toDate,
DateTime date)
{
var p = fromDate.Parameters.Single();
Expression member = p;
Expression fromExpression = Expression.Property(member, (fromDate.Body as MemberExpression).Member.Name);
Expression toExpression = Expression.Property(member, (toDate.Body as MemberExpression).Member.Name);
var after = Expression.LessThanOrEqual(fromExpression,
Expression.Constant(date, typeof(DateTime)));
var before = Expression.GreaterThanOrEqual(
toExpression, Expression.Constant(date, typeof(DateTime)));
Expression body = Expression.And(after, before);
var predicate = Expression.Lambda<Func<TElement, bool>>(body, p);
return queryable.Where(predicate);
}
使用
DataContext.EventHistories.WhereDateBetween(h => h.FromDate, h => h.ToDate, dateInTheMiddle));
但做起来很复杂
var myDate = DateTime.Now();
var result = DataContext.EventHistories.Where(m => m.FromDate >= myDate && m.ToDate<=myDate );
修改强>
好吧,要模拟DateTime.Date
,你可以这样做:
var myDate = DateTime.Now.Date();
var res = histories.AsQueryable()
.Where(m =>
EntityFunctions.CreateDateTime(m.FromDate.Year, m.FromDate.Month, m.FromDate.Day, 0, 0, 0) >= DateTime.Now &&
EntityFunctions.CreateDateTime(m.ToDate.Year, m.ToDate.Month, m.ToDate.Day, 0, 0, 0) <= DateTime.Now)
或创建界面
public interface IFromDateToDate
{
DateTime FromDate { get; set; }
DateTime ToDate { get; set; }
}
和扩展方法
public static IQueryable<T> WhereDatesBetween<T>(this IQueryable<T> queryable, DateTime myDate) where T : IFromDateToDate
{
myDate = myDate.Date;
return queryable.Where(m =>
EntityFunctions.CreateDateTime(m.FromDate.Year, m.FromDate.Month, m.FromDate.Day, 0, 0, 0) >= myDate &&
EntityFunctions.CreateDateTime(m.FromDate.Year, m.FromDate.Month, m.FromDate.Day, 0, 0, 0) <= myDate);
}
用法:
DataContext.EventHistories.WhereDatesBetween(dateInTheMiddle));
答案 1 :(得分:1)
LinQ to Entities DOES支持DateTime - 我在项目中使用它并且没有问题:
var now = DateTime.Now;
var expiredEntities = entities.Repositories.Where(repository => repository.ExpiryDate < now).ToList();
答案 2 :(得分:0)
现在,如果我遵循这一点,你真的想写:
from item in MyTable
where FromDate <= Item.Somedate.Date
&& Item.Somedate.Date <= ToDate
select item
但是,你不能,因为LINQ to实体不支持DateTime的Date
属性。
同样,你不能写:
from item in MyTable
where FromDate <= Item.SomeDate
&& Item.SomeDate <= ToDate
select item
因为,我认为,ToDate
设置为午夜,如果Item.SomeDate
有时间,则会在ToDate
之后,即使它在ToDate上。
如果是这种情况,那么通常的做法就是将上限设为独占值(即首先不)部分内容)。因此:
toDate = toDate.Date.AddDay(1);
from item in MyTable
where FromDate <= Item.SomeDate
&& Item.SomeDate < ToDate
select item
答案 3 :(得分:-1)
为什么要烦恼所有的魔力?为什么不这样做?
if (date >= startDate and date <= endDate) {
}