How to compare only date components from DateTime in EF?

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

以前在数据库中输入的值总是具有12:00:00的时间分量,其中从 picker 输入的日期具有不同的时间分量。

我只对日期成分感兴趣,并且希望忽略时间成分。

在 C # 中进行这种比较的方法有哪些?

还有,如何在 LINQ 中做到这一点?

UPDATE: 在 LINQtoEntity 上,以下工作正常。

e => DateTime.Compare(e.FirstDate.Value, SecondDate) >= 0
146989 次浏览

注意: 在写这个答案的时候,EF-关系是不清楚的(在写这个问题之后被编辑进去)。对于正确的方法与 EF,检查 曼迪普斯回答


You can use the DateTime.Date property to perform a date-only comparison.

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


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

Just always compare the 日期 property of DateTime, instead of the full date time.

当您进行 LINQ 查询时,请使用日期。查询中的日期,即:

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

要在 LINQtoEntity 中执行,必须使用 支持的方法:

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

很丑,但很有效,而且是在数据库服务器上完成的。

我觉得这个能帮到你。

我做了一个扩展,因为我必须比较填充 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);
}

then you can use it in this way.

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

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

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

我觉得应该可以

//Linq 用户/编码员须知

这将为您提供精确的比较,以便在使用用户日期选择器的输入时检查日期是否在范围之内,例如:

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

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

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

附言。这是一个权宜之计的解决方案,是一个非常糟糕的做法,当你知道数据库可以带来成千上万的记录时,千万不要使用..。

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

Without time than try like this:

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;

使用类 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/

更新

As of EF 6.0 and later EntityFunctions is replaced by 数据库函数.

你可以用下面的链接来比较两个没有时间的日期:

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;
}

Compare 函数返回3个不同的值: -101表示 dt1 > dt2,dt1 = dt2,dt1

如果对 DB 实体使用 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;

我就是这么做的。

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

你也可以这样做:

DbFunctions.DiffDays(date1, date2) == 0

可以为此使用 DbFunction.TruncateTime ()方法。

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

我已经使用 EffCore来自 SqlRaw方法解决了错误。

 var sql =
$"select * from \"ProgressBooks\" where date(\"Date\") = date('{today.Date.ToString("yyyy-MM-dd")}') and \"GroupId\" = {groupId}";
var todayProgressBook = _context.ProgressBooks.FromSqlRaw(sql).FirstOrDefault();