如何只比较EF中DateTime的日期组件?

时间:2009-09-25 16:08:00

标签: c# linq entity-framework linq-to-entities datetime-comparison

我有两个日期值,一个已经存储在数据库中,另一个是用户使用DatePicker选择的。用例是从数据库中搜索特定日期。

先前在数据库中输入的值始终具有12:00:00的时间分量,其中从选择器输入的日期具有不同的时间分量。

我只对日期组件感兴趣,并且想要忽略时间组件。

在C#中进行此比较的方法是什么?

另外,如何在LINQ中执行此操作?

更新: 在LINQ to Entities上,以下工作正常。

e => DateTime.Compare(e.FirstDate.Value, SecondDate) >= 0

15 个答案:

答案 0 :(得分:129)

使用班级EntityFunctions修剪时间部分。

using System.Data.Objects;    

var bla = (from log in context.Contacts
           where EntityFunctions.TruncateTime(log.ModifiedDate) ==  EntityFunctions.TruncateTime(today.Date)
           select log).FirstOrDefault();

来源:http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/84d4e18b-7545-419b-9826-53ff1a0e2a62/

<强>更新

从EF 6.0及更高版本开始,EntityFunctions被DbFunctions替换。

答案 1 :(得分:119)

注意:在撰写此答案时,EF关系不明确(在编写完成后编辑成了问题)。要使用EF进行正确处理,请检查Mandeeps answer


您可以使用DateTime.Date属性执行仅限日期的比较。

DateTime a = GetFirstDate();
DateTime b = GetSecondDate();

if (a.Date.Equals(b.Date))
{
    // the dates are equal
}

答案 2 :(得分:24)

我认为这可以帮到你。

我做了一个扩展,因为我必须比较填充了EF数据的存储库中的日期,所以.Date不是一个选项,因为它没有在LinqToEntities翻译中实现。

以下是代码:

        /// <summary>
    /// Check if two dates are same
    /// </summary>
    /// <typeparam name="TElement">Type</typeparam>
    /// <param name="valueSelector">date field</param>
    /// <param name="value">date compared</param>
    /// <returns>bool</returns>
    public Expression<Func<TElement, bool>> IsSameDate<TElement>(Expression<Func<TElement, DateTime>> valueSelector, DateTime value)
    {
        ParameterExpression p = valueSelector.Parameters.Single();

        var antes = Expression.GreaterThanOrEqual(valueSelector.Body, Expression.Constant(value.Date, typeof(DateTime)));

        var despues = Expression.LessThan(valueSelector.Body, Expression.Constant(value.AddDays(1).Date, typeof(DateTime)));

        Expression body = Expression.And(antes, despues);

        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }

然后你可以这样使用它。

 var today = DateTime.Now;
 var todayPosts = from t in turnos.Where(IsSameDate<Turno>(t => t.MyDate, today))
                                      select t);

答案 3 :(得分:10)

如果对数据库实体使用Date属性,则会出现异常:

"The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

您可以使用以下内容:

  DateTime date = DateTime.Now.Date;

  var result = from client in context.clients
               where client.BirthDate >= date
                     && client.BirthDate < date.AddDays(1)
               select client;

答案 4 :(得分:8)

要在LINQ to Entities中执行此操作,您必须使用supported methods

var year = someDate.Year;
var month = ...
var q = from r in Context.Records
        where Microsoft.VisualBasic.DateAndTime.Year(r.SomeDate) == year 
              && // month and day

很丑,但它确实有效,而且已在数据库服务器上完成。

答案 5 :(得分:8)

这是一种不同的方法,但只有当SecondDate是你传入的变量时它才有用:

DateTime startDate = SecondDate.Date;
DateTime endDate = startDate.AddDays(1).AddTicks(-1);
...
e => e.FirstDate.Value >= startDate && e.FirstDate.Value <= endDate

我认为应该有效

答案 6 :(得分:6)

您也可以使用:

DbFunctions.DiffDays(date1, date2) == 0

答案 7 :(得分:4)

你可以使用DbFunctions.TruncateTime()方法。

e => DbFunctions.TruncateTime(e.FirstDate.Value) == DbFunctions.TruncateTime(SecondDate);

答案 8 :(得分:3)

只需总是比较DateTime的Date属性,而不是完整的日期时间。

进行LINQ查询时,请在查询中使用date.Date,即:

var results = from c in collection
              where c.Date == myDateTime.Date
              select c;

答案 9 :(得分:3)

我就是这样做的。

DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
                EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));

答案 10 :(得分:2)

答案 11 :(得分:2)

// Linq用户/编码器的注释

这应该为您提供准确的比较,以便在处理来自用户的输入时检查日期是否在范围内 - 例如日期选择器:

((DateTime)ri.RequestX.DateSatisfied).Date >= startdate.Date &&
        ((DateTime)ri.RequestX.DateSatisfied).Date <= enddate.Date

其中startdate和enddate是日期选择器中的值。

答案 12 :(得分:1)

没有时间,请尝试这样:

TimeSpan ts = new TimeSpan(23, 59, 59);
toDate = toDate.Add(ts);
List<AuditLog> resultLogs = 
    _dbContext.AuditLogs
    .Where(al => al.Log_Date >= fromDate && al.Log_Date <= toDate)
    .ToList();
return resultLogs;

答案 13 :(得分:1)

您可以通过以下链接用户比较2个日期而无需时间:

private bool DateGreaterOrEqual(DateTime dt1, DateTime dt2)
        {
            return DateTime.Compare(dt1.Date, dt2.Date) >= 0;
        }

private bool DateLessOrEqual(DateTime dt1, DateTime dt2)
        {
            return DateTime.Compare(dt1.Date, dt2.Date) <= 0;
        }

比较函数返回3个不同的值:-1 0 1表示dt1&gt; dt2,dt1 = dt2,dt1

答案 14 :(得分:0)

试试这个...它可以比较两个DateTimes类型之间的Date属性:

PS。这是一个权宜之计,一个非常糟糕的做法,当你知道数据库可以带来数以千计的记录时,永远不应该使用它......

query = query.ToList()
             .Where(x => x.FirstDate.Date == SecondDate.Date)
             .AsQueryable();