Linq查询中仅比较日期值而不考虑时间值的where子句

64
var _My_ResetSet_Array = _DB
    .tbl_MyTable
    .Where(x => x.Active == true
        && x.DateTimeValueColumn <= DateTime.Now)
    .Select(x => x);

上述查询语句是正确的。
但是我只想检查日期值。
而上述查询语句检查的是日期+时间的值。

在传统的mssql中,我可以像下面这样编写查询语句。

SELECT * FROM dbo.tbl_MyTable
WHERE 
CAST(CONVERT(CHAR(10), DateTimeValueColumn, 102) AS DATE) <= 
            CAST(CONVERT(CHAR(10),GETDATE(),102) AS DATE)
AND
Active = 1

有人能给我建议吗?如何在 Linq 中仅检查日期值。

10个回答

140

在EF 6.0或更高版本中,还有EntityFunctions.TruncateTimeDbFunctions.TruncateTime


3
如果你遇到了EntityFunctions已经过时的错误,请使用DbFunctions进行替换。 - Avi
6
这个方法很有效。需要注意的是,你必须对数据库列以及 C# 的 DateTime.Now 使用 TruncateTime 方法。这里是我使用的 LINQ 语句:mydata.Where(t => t.ExpirationDate == null || (t.ExpirationDate != null && DbFunctions.TruncateTime(t.ExpirationDate.Value) > DbFunctions.TruncateTime(DateTime.Now))); - Mark
1
DbFunctions.TruncateTime(DateTime.Now) = DateTime.Today ? - Johann Blais
3
如果这个答案包含了使用这些函数的示例,或者至少提到一些包含示例的资源,我会更加感激。 - Hakan Fıstık
1
EF Core 1.0怎么样? - Afshar Mohebi
指定的类型成员“Date”在LINQ to Entities中不受支持。仅支持初始化程序、实体成员和实体导航属性。 - SAR

20

比较日期部分的简单解决方法

var _My_ResetSet_Array = _DB
                    .tbl_MyTable
                    .Where(x => x.Active == true && 
                               x.DateTimeValueColumn.Year == DateTime.Now.Year
                            && x.DateTimeValueColumn.Month == DateTime.Now.Month
                            && x.DateTimeValueColumn.Day == DateTime.Now.Day);

'Date' 数据类型不受 linq to entity 支持,而 'Year'、'Month' 和 'Day' 是 'int' 数据类型且受支持。


它检查“==”,而不是“<=”。当然,还可以实现一些其他条件。 - Tilak
来吧,你从没听说过DbFunctions.TruncateTime吗? - Toolkit
如果你需要使用比较运算符'<'或'>'来检查日期,这将变得冗长。 - Force444
2
是否有TruncateOffset函数可以获取DateTimeOffset的DateTime部分?似乎无法使用实体框架引用DateTimeOffset的DateTime部分,这使得它相当无用。 - Triynko
你好,你能把这个封装成EF扩展,以便可以在各处重用吗? - aggie
这会很快变得混乱。 - Noldy

4

编辑

为了避免这个错误: 在LINQ to Entities中不支持指定的类型成员"Date"。只支持初始化器、实体成员和实体导航属性。

var _My_ResetSet_Array = _DB
                .tbl_MyTable
                .Where(x => x.Active == true)
                         .Select(x => x).ToList();

 var filterdata = _My_ResetSet_Array
        .Where(x=>DateTime.Compare(x.DateTimeValueColumn.Date, DateTime.Now.Date)  <= 0 );

第二行是必需的,因为LINQ to Entity无法将日期属性转换为SQL查询。因此最好先获取数据,然后再应用日期筛选器。

编辑

如果您只想比较日期时间的日期值,那么可以使用

DateTime.Date 属性 - 获取此实例的日期组件。

您的代码:

var _My_ResetSet_Array = _DB
                .tbl_MyTable
                .Where(x => x.Active == true
     && DateTime.Compare(x.DateTimeValueColumn.Date, DateTime.Now.Date)  <= 0 )
                         .Select(x => x);

如果是这样,那么使用:

DateTime.Compare Method - 比较两个 DateTime 实例并返回一个整数,指示第一个实例是早于、相同还是晚于第二个实例。

给你的代码:
var _My_ResetSet_Array = _DB
                .tbl_MyTable
                .Where(x => x.Active == true
                  && DateTime.Compare(x.DateTimeValueColumn, DateTime.Now)  <= 0 )
                         .Select(x => x);

例子

DateTime date1 = new DateTime(2009, 8, 1, 0, 0, 0);
DateTime date2 = new DateTime(2009, 8, 1, 12, 0, 0);
int result = DateTime.Compare(date1, date2);
string relationship;

if (result < 0)
   relationship = "is earlier than";
else if (result == 0)
   relationship = "is the same time as";         
else
   relationship = "is later than";

很抱歉告诉您,异常返回指定的类型成员'Date'在LINQ to Entities中不受支持。仅支持初始化程序、实体成员和实体导航属性。 - Frank Myat Thu
我很感激你的努力,但是什么都没有改变。 - Frank Myat Thu
@Frank - 感谢回复...我只是忘记包含ToList()函数了...所以在答案中更新代码后,它看起来像这样:添加列表函数后,_My_ResetSet_Array变量如下所示:_DB.tbl_MyTable.Where(x => x.Active == true).Select(x => x).ToList() - Pranay Rana
@Frank- 我也提供了一个解决方法,试试看这个可能适合你... - Pranay Rana
3
假设有一个1TB的数据库,其中包含活跃记录。对于“首先获取数据,然后进行比较”的操作,你会下载全部数据,只为删除其中700GB(在时间范围内)。 - Rafael Herscovici
指定的类型成员“Date”在LINQ to Entities中不受支持。仅支持初始化程序、实体成员和实体导航属性。!!!!!! - NoWar

2
 result = from r in result where (r.Reserchflag == true && 
    (r.ResearchDate.Value.Date >= FromDate.Date && 
     r.ResearchDate.Value.Date <= ToDate.Date)) select r;

1

&& x.DateTimeValueColumn <= DateTime.Now

只要您的架构正确,就支持此操作。

&& x.DateTimeValueColumn.Value.Date <=DateTime.Now

除非不是这样的。他正在使用Linq to Entities,而不是普通的Linq。 - Slight

1
在类似情况下,我使用了以下代码:

DateTime upperBound = DateTime.Today.AddDays(1); // If today is October 9, then upperBound is set to 2012-10-10 00:00:00
return var _My_ResetSet_Array = _DB
    .tbl_MyTable
    .Where(x => x.Active == true
        && x.DateTimeValueColumn < upperBound) // Accepts all dates earlier than October 10, time of day doesn't matter here
    .Select(x => x);

0

工作代码:

     {
        DataBaseEntity db = new DataBaseEntity (); //This is EF entity
        string dateCheck="5/21/2018";
        var list= db.tbl
        .where(x=>(x.DOE.Value.Month
              +"/"+x.DOE.Value.Day
              +"/"+x.DOE.Value.Year)
             .ToString()
             .Contains(dateCheck))
     }

1
请使用代码块格式包装您的代码示例,以便于阅读。 - Collin Barrett
我考虑查询性能,因为您正在使用字符串值进行比较。 - Frank Myat Thu
谢谢,这段代码可以将日期合并为一个字符串,帮助从数据库中搜索日期到列表中。 - Soharab Shaikh
什么类型的错误?你能解释一下吗? @habib - Soharab Shaikh
@Soharab,你的查询肯定可以使用lEnumberable,但不能使用IQueryable,因为实体框架会说:“我不知道.Month或.Value.Day是什么意思”,因为实体框架首先将其转换为查询,然后再运行。如果需要进一步了解,请尝试此操作,您将知道可能出现的错误。 - habib

0

试试这个,

var _My_ResetSet_Array = _DB
    .tbl_MyTable
    .Where(x => x.Active == true
         && x.DateTimeValueColumn <= DateTime.Now)
    .Select(x => x.DateTimeValueColumn)
    .AsEnumerable()
    .select(p=>p.DateTimeValueColumn.value.toString("YYYY-MMM-dd");

0
不要简化代码以避免“linq翻译错误”:测试包括从时间为0:0:0的日期到同一日期的时间为23:59:59。
        iFilter.MyDate1 = DateTime.Today;  // or DateTime.MinValue

        // GET 
        var tempQuery = ctx.MyTable.AsQueryable();

        if (iFilter.MyDate1 != DateTime.MinValue)
        {
            TimeSpan temp24h = new TimeSpan(23,59,59);
            DateTime tempEndMyDate1 = iFilter.MyDate1.Add(temp24h);

            // DO not change the code below, you need 2 date variables...
            tempQuery = tempQuery.Where(w => w.MyDate2 >= iFilter.MyDate1
                                          && w.MyDate2 <= tempEndMyDate1);
        }

        List<MyTable> returnObject = tempQuery.ToList();

-4
使用mydate.Date仅处理DateTime类的日期部分。

3
日期属性在Linq to Entity中无法工作。 - Pranay Rana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接