使用DateDiff和Linq.动态库获取今天的记录
本文关键字:获取 今天 记录 动态 DateDiff Linq 使用 | 更新日期: 2023-09-27 18:27:06
我正试图通过MVC 5/Entity Framework 6应用程序中的Linq表达式,使用DateDiff SQL语法获取今天添加的所有记录。DateDiff函数抛出运行时错误
实际上,我想用linqdynamics 解析下面的linqWHERE子句
.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.动态表达式-如何编写where子句
LINQ 中的动态WHERE子句
使用DbFunctions
.Where(p => DbFunctions.DiffDays(p.AddedDate, DateTime.Now) == 0)
编辑:
如果您想动态调用它,则需要修改动态LINQ的代码。
- 下载包含DynamicLibrary.cs的示例项目。该文件位于App_Code文件夹下
- 找到
predefinedTypes
的静态定义,并在最后添加typeof(DbFunctions)
现在你将能够做到这一点:
.Where("DbFunctions.DiffDays(AddedDate, DateTime.Now) = 0")
它将被翻译成SQL:
WHERE 0 = (DATEDIFF (day, [Extent1].[AddedDate], SysDateTime()))
flindeberg说System.Linq.Dynamic解析的表达式是C#,而不是SQL,这是正确的。
然而,EntityFramework定义了类"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#表达式中使用的类型。
您的代码从未在数据库中执行,"问题"是Linq.Dynamic
试图将其解析为C#
代码,但失败了。据我所知,用动态linq调用SQL
是不可能的。
我相信您正在寻找的是使用原始SQL
,而不是Linq.Dynamic
所使用的.NET
代码,MSDN上的此页面将为您提供有关使用原始SQL
的更多信息。
在对实体使用LINQ时,不需要运行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。
下面发布的代码帮助我解决了问题。
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);
//指定日期范围(无时间)
DateTime currentDate = System.DateTime.Now.Date;
query = query.Where(p => p.added_date == currentDate);