私は1つのFilterメソッドを使用して、ほとんどが汎用的なアプリケーションに取り組んでいます。
IQueryable<T> Filter<T>(IQueryable<T> query, Filter filter) where T : IDataBaseEntity
渡されるフィルターオブジェクトは次のとおりです。
{
Field: "Header.Title",
Operator: "contains",
Value: "asdf"
}
演算子(contains、<、>、==など)がそれぞれを異なる方法で処理するためのスイッチがありますが、この例では「contains」にのみ焦点を当てます。
渡される「クエリ」変数は、インターフェイスの一般的なリストであり、200のエンティティすべてが継承するインターフェイスです。この名前空間からエンティティタイプにアクセスすることすらできません。
この例では、「query」パラメーターはエンティティ「Page」のIQueryableです。 ContainsのDynamicLinqの典型的な例は次のとおりです。
Expression<Func<Page, bool>> exp = l => l.Contains(filter.Value);
query = query.Where("@0(it)", exp);
ただし、アプリケーションのこの部分は厳密に型指定されておらず、ドメインは「ページ」が何であるかを認識していません。代わりに、Func <>の最初の型として継承されたIDataBaseEntityを使用しています。 「タイプ 'IDataBaseEntity'にプロパティまたはフィールド 'Header'が存在しないため」という例外が発生します。他のさまざまなオプションを試しましたが、これが主な問題でした。
注:これをIQueryableにしておく必要があり、パフォーマンス上の理由から、いつでもIEnumerableに変換したくありません。クエリは、フィルタリング、並べ替え、およびページングの後にのみ実行される(.AsEnumerable())ように意図されています。
実際のエンティティタイプについて何も知らない名前空間のインターフェイスタイプを使用して、IQueryableに対して動的linqを実行することはできますか?
インターフェースをまったく使用しないのはどうですか?Dynamic Linqはとにかく遅いバインディングです。動的Where
on IQueryable<T>
を適用すると、結果はIQueryable<T>
ます。
文字列述語を正しく構築できるとすぐに、以下が機能するはずです。
query = query.Where("Header.Title.Contains(@0)", filter.Value);