web-dev-qa-db-ja.com

今日のレコードをフェッチするためのLinq.DynamicライブラリでDateDiffを使用する

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句の記述方法

LINQの動的WHERE句

7
irfanmcsd

DbFunctionsを使用します

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

編集:

これを動的に呼び出す場合は、動的LINQのコードを変更する必要があります。

  1. DynamicLibrary.csを含むサンプルプロジェクト をダウンロードします。このファイルはApp_Codeフォルダーの下にあります。
  2. predefinedTypesの静的定義を見つけて、最後にtypeof(DbFunctions)を追加します。

これで、これを実行できるようになります。

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

そしてそれはこのSQLに翻訳されます:

_WHERE 0 = (DATEDIFF (day, [Extent1].[AddedDate], SysDateTime()))
_
25
Alaa Masoud

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を認識するようになりました。

2
Mikael Guldborg

エンティティに対して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にコンパイルします

0
Anduril

以下に投稿されたコードは、問題を解決するのに役立ちました。

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

コードがデータベースで実行されることはありません。「問題」は、Linq.DynamicがコードをC#コードとして解析しようとし、失敗することです。私の知る限り、動的linqでSQLを呼び出すことはできません。

あなたが探しているのは、.NETであるLinq.Dynamicコードではなく、raw SQLを使用していると思います MSDNのこのページで詳細を確認できます rawの使用についてSQL

0
flindeberg

//日付範囲を指定します(時間なし)

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