データアクセスレイヤーのEntity FrameworkオブジェクトのLINQ to Entitiesを使用しています。
私の目標は、メモリ内の結果にフィルタリングロジックを適用せずに、データベースからできる限りフィルタリングすることです。
そのために、ビジネスロジック層は述語をデータアクセス層に渡します。
というのは
Func<MyEntity, bool>
したがって、この述部を直接使用すると、
public IQueryable<MyEntity> GetAllMatchedEntities(Func<MyEntity, Boolean> isMatched)
{
return qry = _Context.MyEntities.Where(x => isMatched(x));
}
例外が発生しています
[System.NotSupportedException] --- {「LINQ式ノードタイプ「Invoke」は、LINQ to Entitiesではサポートされていません。」}
の解決策は、question が からAsExpandable()メソッドを使用することを示唆していることLINQKit ライブラリ。
しかし、再び、使用して
public IQueryable<MyEntity> GetAllMatchedEntities(Func<MyEntity, Boolean> isMatched)
{
return qry = _Context.MyEntities.AsExpandable().Where(x => isMatched(x));
}
例外が発生しています
タイプ 'System.Linq.Expressions.FieldExpression'のオブジェクトをタイプ 'System.Linq.Expressions.LambdaExpression'にキャストできません
エンティティフレームワークオブジェクトのLINQ to Entitiesクエリで述語を使用して、SQLステートメントに正しく変換する方法はありますか。
ありがとうございました。
これを行うためにLinqKitは必要ありません。使用することを忘れないでください
Expression<Func<MyEntity, bool>>
の代わりに
Func<MyEntity, bool>
このようなもの:
public IQueryable<MyEntity> GetAllMatchedEntities(Expression<Func<MyEntity, Boolean>> predicate)
{
return _Context.MyEntities.Where(predicate);
}
Linq to EntitiesはラムダをSQLに変換する必要があるため、Expressionを使用する必要があります。
Funcを使用すると、ラムダはILにコンパイルされますが、Expressionを使用すると、Linq to Entitiesが横断および変換できる式ツリーになります。
これは、Linq to Entitiesが理解できる式で機能します。
失敗し続ける場合、式は、Linq to EntitiesがSQLに変換できないことを行います。その場合、LinqKitが役立つとは思わない。
変換は必要ありません。 ExpressionパラメーターでメソッドGetAllMatchedEntitiesを定義し、Funcパラメーターで使用するのと同じ方法で使用します。コンパイラが残りを行います。
GetAllMatchedEntitiesを使用できる方法は3つあります。
1)インラインラムダ式の場合:
this.GetAllMatchedEntities(x => x.Age > 18)
2)式をフィールドとして定義します(変数にすることもできます)
private readonly Expression<Func<MyEntity, bool>> IsMatch = x => x.Age > 18;
...then use it
this.GetAllMatchedEntities(IsMatch)
3)式を手動で作成できます。ダウンサイズはより多くのコードであり、コンパイル時のチェックを見逃します。
public Expression<Func<MyEntity, bool>> IsMatchedExpression()
{
var parameterExpression = Expression.Parameter(typeof (MyEntity));
var propertyOrField = Expression.PropertyOrField(parameterExpression, "Age");
var binaryExpression = Expression.GreaterThan(propertyOrField, Expression.Constant(18));
return Expression.Lambda<Func<MyEntity, bool>>(binaryExpression, parameterExpression);
}
Linq to Entitiesで使用されるメソッドは、動作するためにLinqプロバイダーによって正規にマッピングされる必要があります。 Linqプロバイダー(あなたの場合はEF)は、述語を内部メソッドにマップできなかったため、エラーをスローしました。
LINQシナリオの場合、Entity Frameworkに対するクエリには、標準関数を介して特定のCLRメソッドを基になるデータソースのメソッドにマッピングすることが含まれます。正規関数に明示的にマップされていないLINQ to Entitiesクエリでメソッドを呼び出すと、ランタイムNotSupportedException例外がスローされます
ソース:CLR Method to Canonical Function Mapping( http://msdn.Microsoft.com/en-us/library/bb738681.aspx )
[〜#〜] [〜#〜](-#〜]にマッピングされているメソッドを取得してLinq式にチェーンするか、または手順。ただし、EFがすべてのCLRをサポートするまで、回避策を見つける必要があります。
プラス面として、各リリースは正規リストにもう少し追加するようです。
回避策として読む価値がある: http://msdn.Microsoft.com/en-us/library/dd456857.aspx