【问题标题】:Linq where clause compare only date value without time valueLinq where 子句只比较没有时间值的日期值
【发布时间】:2012-11-10 17:48:58
【问题描述】:
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 中仅检查日期值。

【问题讨论】:

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


    【解决方案1】:

    不要简化代码以避免“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();
    

    【讨论】:

      【解决方案2】:

      EF 6.0 中还有EntityFunctions.TruncateTimeDbFunctions.TruncateTime

      【讨论】:

      • 如果由于 EntitiyFunction 已弃用而出现错误,请将 EntityFunctions 替换为 DbFunctions。
      • 这很好用。请注意,您可以(实际上必须)在数据库列和 C# DateTime.Now 上使用 TruncateTime。这是我使用的 LINQ 语句:mydata.Where(t =&gt; t.ExpirationDate == null || (t.ExpirationDate != null &amp;&amp; DbFunctions.TruncateTime(t.ExpirationDate.Value) &gt; DbFunctions.TruncateTime(DateTime.Now)));
      • DbFunctions.TruncateTime(DateTime.Now) = DateTime.Today ?
      • 如果它包含使用这些功能的示例,或者至少参考一些包含示例的资源,我会更感激这个答案
      • EF Core 1.0 怎么样?
      【解决方案3】:

      试试这个,

      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");
      

      【讨论】:

        【解决方案4】:

        工作代码:

             {
                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))
             }
        

        【讨论】:

        • 请将您的代码示例包装成代码块格式以便于阅读。
        • 我正在考虑查询性能,因为您使用的是字符串值进行比较。
        • 谢谢你...此代码可以将日期组合为字符串,并有助于将日期从数据库中搜索到列表...
        • 什么类型的错误?你能解释一下吗...@habib
        • @Soharab 您查询肯定会与 lEnumberable 一起使用,但不会与 IQueryable 一起使用,因为实体框架会说哦,我不知道.Month 或 Value.Day 是什么意思,因为实体框架首先将其转换为查询然后运行。进一步请尝试这个你会知道可能是什么错误。
        【解决方案5】:
         result = from r in result where (r.Reserchflag == true && 
            (r.ResearchDate.Value.Date >= FromDate.Date && 
             r.ResearchDate.Value.Date <= ToDate.Date)) select r;
        

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            &amp;&amp; x.DateTimeValueColumn &lt;= DateTime.Now

            只要您的架构正确,就支持此功能

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

            【讨论】:

            • 除非它不是。他使用的是 Linq to Entities,而不是普通的 linq。
            【解决方案8】:

            编辑

            为避免此错误:LINQ to Entities 不支持指定的类型成员“日期”。仅支持初始化程序、实体成员和实体导航属性。

            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 Property - 获取此实例的日期部分。

            为您编写代码

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

            【讨论】:

            • 很抱歉告诉你异常返回The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
            • 感谢您的努力,但没有任何改变。
            • @Frank - 感谢您的回复..只是忘记包含 ToList() 函数...所以在添加列表函数 var _My_ResetSet_Array = _DB .tbl_MyTable .Where( x => x.Active == true) .Select(x => x).ToList()
            • @Frank- 我还提供了一种解决方法,尝试一下这可能对您有用...
            • -1 for "First fetch the data and then compare",假设一个 1TB 的数据库有活动记录,你将下载所有只是为了删除 700GB(在时间范围内)。
            【解决方案9】:

            解决此问题的简单解决方法,仅比较日期部分

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

            因为 linq to entity 不支持 'Date' 数据类型,其中 Year、Month 和 Day 是 'int' 数据类型并且受支持。

            【讨论】:

            • 它检查 ==,而不是
            • 拜托,你没听说过 DbFunctions.TruncateTime?
            • 如果您需要使用比较器“”检查日期,这将变得冗长。
            • TruncateOffset 函数中是否有获取 DateTimeOffset 的 DateTime 部分?似乎不可能使用实体框架引用 DateTimeOffset 的 DateTime 部分,这使得它非常无用。
            • 嗨,你能把它包装在一个 EF 扩展中,这样它就可以被重用了吗?
            【解决方案10】:

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

            【讨论】:

            • 在我的回答中查看解决方案 ...Date 属性在 linq to entity 中不起作用
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-09-16
            • 2012-01-02
            • 1970-01-01
            • 2012-12-29
            • 2017-04-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多