使用DateDiff与Linq.Dynamic库获取今天的记录

时间:2014-10-19 12:57:46

标签: c# linq entity-framework entity-framework-6

我正在尝试通过MVC 5 / Entity Framework 6应用程序中的Linq表达式使用DateDiff SQL语法获取今天添加的所有记录。 DateDiff函数抛出运行时错误

实际上我想用以下linq WHERE子句来解析linq dynamics

.Where(p => DbFunctions.DiffDays(p.added_date, DateTime.Now) == 0)

为了获取今天添加的记录。我正在使用的示例代码如下所示

var _list = new vsk_error_log();
using (var entities = new vskdbEntities())
{
   _list = entities.vsk_error_log
  //.Where("DateDiff(DAY,added_date,getdate())=0")
  .Where(p => DbFunctions.DiffDays(p.added_date, DateTime.Now) == 0)
  .ToList();
}
return _list;

关于Linq.Dynamic表达式 - 如何编写where子句

Dynamic WHERE clause in LINQ

6 个答案:

答案 0 :(得分:20)

使用DbFunctions

.Where(p => DbFunctions.DiffDays(p.AddedDate, DateTime.Now) == 0)

修改

如果要动态调用它,则需要修改Dynamic LINQ的代码。

  1. 下载sample project containing DynamicLibrary.cs。该文件位于App_Code文件夹下。
  2. 找到predefinedTypes的静态定义,并在最后添加typeof(DbFunctions)
  3. 现在你可以这样做了:

    .Where("DbFunctions.DiffDays(AddedDate, DateTime.Now) = 0")
    

    它将被翻译成这个SQL:

    WHERE 0 = (DATEDIFF (day, [Extent1].[AddedDate], SysDateTime()))
    

答案 1 :(得分:2)

当flindeberg说System.Linq.Dynamic解析你作为C#提供的表达式而不是SQL时,flindeberg是正确的。

但是,实体框架定义了“DbFunctions”类,它允许您在Linq查询中调用sql函数。

DbFunctions.DiffDays是您正在寻找的方法。有了这个,您也不需要使用System.Linq.Dynamic。

我认为你的代码看起来像这样:

     var _list = new vsk_error_log();
     using ( var entities = new vskdbEntities() )
     {
        _list = entities.vsk_error_log
          .Where( entry => DbFunctions.DiffDays( entry.added_date, DateTime.UtcNow ) == 0 )
          .ToList();
     }
     return _list;

如果你想在System.Linq.Dynamic中使用这个功能,它看起来像这样:

     var _list = new vsk_error_log();
     using ( var entities = new vskdbEntities() )
     {
        _list = entities.vsk_error_log
          .Where( "DbFunctions.DiffDays( added_date, DateTime.UtcNow ) == 0" )
          .ToList();
     }
     return _list;

无论其! System.Linq.Dynamic将无法识别类DbFunctions,因此,这不会开箱即用。但是,我们可以使用一些反射“修补”这个功能,虽然它可能有点难看:

     var type = typeof( DynamicQueryable ).Assembly.GetType( "System.Linq.Dynamic.ExpressionParser" );

     FieldInfo field = type.GetField( "predefinedTypes", BindingFlags.Static | BindingFlags.NonPublic );

     Type[] predefinedTypes = (Type[])field.GetValue( null );

     Array.Resize( ref predefinedTypes, predefinedTypes.Length + 1 );
     predefinedTypes[ predefinedTypes.Length - 1 ] = typeof( DbFunctions );

     field.SetValue( null, predefinedTypes );

通过运行此代码,System.Linq.Dynamic现在将DbFunctions识别为可在解析的C#表达式中使用的类型。

答案 2 :(得分:0)

您的代码永远不会在数据库中执行,“问题”是Linq.Dynamic尝试将其解析为C#代码,它失败了。据我所知,用动态linq调用SQL是不可能的。

我认为您正在寻找的是使用原始SQL,而非.NET代码Linq.Dynamicthis page at MSDN will give you more information关于使用原始SQL

答案 3 :(得分:0)

使用LINQ to实体时,不需要运行SQL字符串。正如其他人所指出的那样,我甚至不确定它是否可行。正确的语法类似于:

var _list = new List<vsk_error_log>();
using (var entities = new vskdbEntities())
{
   _list = entities.vsk_error_log
  .Where(log => log.added_date >= DateTime.Now.AddDays(-1))
  .ToList();
}
return _list;
然后

实体框架会将其编译为SQL

答案 4 :(得分:0)

下面发布的代码帮助我解决了我的问题。

var _list = new List<vsk_error_log>();
using (var entities = new vskdbEntities())
{
    _list = entities.vsk_error_log
         .Where("added_date >= @0", DateTime.Now.AddDays(-1))
         .OrderBy(entity.Order)
         .Skip(entity.PageSize * (entity.PageNumber - 1))
         .Take(entity.PageSize)
         .ToList();
 }

//使用动态linq

在两个日期之间获取数据
.Where("added_date >= @0 AND added_date < @1", DateTime.Now.AddDays(-7), DateTime.Now);

答案 5 :(得分:0)

//指定日期范围(没有时间)

   DateTime currentDate = System.DateTime.Now.Date;
   query = query.Where(p => p.added_date == currentDate);