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

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

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

.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子句

LINQ中的动态WHERE子句

使用DbFunctions

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

编辑:

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

  1. 下载包含DynamicLibrary.cs的示例项目 。 该文件位于App_Code文件夹下。
  2. 找到typeof(DbFunctions)的静态定义,并在最后添加typeof(DbFunctions)

现在你可以这样做了:

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

它将被翻译成这个SQL:

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

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

但是,entity framework定义了类“DbFunctions”,它允许您调用sql函数作为Linq查询的一部分。

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,因此,这不会开箱即用。 但是,我们可以使用一些reflection“修补”这个function,虽然它可能有点难看:

  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#表达式中使用的类型。

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

我相信您正在寻找的是使用原始SQL ,而不是Linq.Dynamic所使用的.NET代码, MSDN上的这个页面将为您提供有关使用原始SQL 更多信息 。

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

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

然后,entity framework将为您编译为SQL

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

 var _list = new List(); 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); 

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

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