MVC 5/Entity Framework6アプリケーションのLinq式を介してDateDiffSQL構文を使用して、今日追加されたすべてのレコードをフェッチしようとしています。 DateDiff関数はランタイムエラーをスローします
実際には、次のlinqWHERE句を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句の記述方法
DbFunctions
を使用します
_.Where(p => DbFunctions.DiffDays(p.AddedDate, DateTime.Now) == 0)
_
編集:
これを動的に呼び出す場合は、動的LINQのコードを変更する必要があります。
predefinedTypes
の静的定義を見つけて、最後にtypeof(DbFunctions)
を追加します。これで、これを実行できるようになります。
_.Where("DbFunctions.DiffDays(AddedDate, DateTime.Now) = 0")
_
そしてそれはこのSQLに翻訳されます:
_WHERE 0 = (DATEDIFF (day, [Extent1].[AddedDate], SysDateTime()))
_
flindebergは、System.Linq.DynamicがSQLではなくC#として指定した式を解析すると言ったときに正しいです。
ただし、Entity Frameworkは、Linqクエリの一部としてSQL関数を呼び出すことができるクラス「DbFunctions」を定義しています。
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は、解析されたC#式で使用できる型としてDbFunctionsを認識するようになりました。
エンティティに対して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();
}
//動的言語クエリを使用して2つの日付の間のデータをフェッチします
.Where("added_date >= @0 AND added_date < @1", DateTime.Now.AddDays(-7), DateTime.Now);
コードがデータベースで実行されることはありません。「問題」は、Linq.Dynamic
がコードをC#
コードとして解析しようとし、失敗することです。私の知る限り、動的linqでSQL
を呼び出すことはできません。
あなたが探しているのは、.NET
であるLinq.Dynamic
コードではなく、raw SQL
を使用していると思います MSDNのこのページで詳細を確認できます rawの使用についてSQL
。
//日付範囲を指定します(時間なし)
DateTime currentDate = System.DateTime.Now.Date;
query = query.Where(p => p.added_date == currentDate);