2012-01-26 10 views
0

このメソッドはうまく動作し、1つのクエリのみを生成します(熱心な負荷に.Includes()を使用します)。 しかし、AbleToDeleteコードをより再利用できるようにリファクタリングしたいと思います。 (EF4を使用)代理人または式を使用するLINQクエリをリファクタリングする方法<Func <T, bool>>

 public override IEnumerable<AffectProjection> SelectAll(SearchAffects page) 
     { 
      IQueryable<Affect> query = BuildSearchQuery(page); 

      IEnumerable<AffectProjection> results = query.Select(entity => new AffectProjection() 
      { 
       AffectID = entity.AffectID, 
       AffectCode = entity.AffectCode, 
       AffectName = entity.AffectName, 

       AbleToDelete = !((entity.Foo1s.Any(pa => !pa.Inactive)) 
           || (entity.Foo2s.Any(ea => !ea.Inactive)) 
           || (entity.Foo3s.Any(sa => !sa.Inactive)) 
           || (entity.Foo4s.Any(spa => !spa.Inactive))) 
      }).ToArray(); 

      return results; 
     } 

私は式のFunc構造にコードを移動しますがAbleToDeleteプロパティを設定している私のコードを交換する方法を見つけ出すことはできません。助言?なく、少なくとも

public Expression<Func<Affect, bool>> DelegateExpression = entity => 
      !((entity.Foo1s.Any(pa => !pa.Inactive)) 
       || (entity.Foo2s.Any(ea => !ea.Inactive)) 
       || (entity.Foo3s.Any(sa => !sa.Inactive)) 
       || (entity.Foo4s.Any(spa => !spa.Inactive))); 

最後に、このソリューションは、コンパイルが、エラーと実行時に失敗:「非サポート例外 - LINQ式ノードタイプの 『起動』はエンティティへのLINQでサポートされていません。」サポートされていない代理人を使用しようとしています:

 public override IEnumerable<AffectProjection> SelectAll(SearchAffects page) 
     { 
      IQueryable<Affect> query = BuildSearchQuery(page); 

      //Create delegate instance and register method -- single statement 
      var deleteAbilityAllowed = new CanDelete(GetAbleToDelete); 

      IEnumerable<AffectProjection> results = query.Select(entity => new AffectProjection() 
      { 
       AffectID = entity.AffectID, 
       AffectCode = entity.AffectCode, 
       AffectName = entity.AffectName, 

       AbleToDelete = deleteAbilityAllowed(entity) 
      }).ToArray(); 

      return results; 
     } 

     public delegate bool CanDelete(Affect entity); 

     public bool GetAbleToDelete(Affect entity) 
     { 
      return !((entity.Foo1s.Any(pa => !pa.Inactive)) 
       || (entity.Foo2s.Any(ea => !ea.Inactive)) 
       || (entity.Foo3s.Any(sa => !sa.Inactive)) 
       || (entity.Foo4s.Any(spa => !spa.Inactive))); 
     } 

事前にご連絡いただきありがとうございます。

+4

'? false:true'は '!'と等価です。 – SLaks

+0

上記のコードを提案ごとに切り替えました。ありがとう! – AdventurGurl

答えて

2

LINQKitには、これを可能にする方法が含まれています。それで、あなたはDelegateExpressionを使うことができます。これを行うには、クエリのソースにAsExpandable()を追加し、Invoke()を使用して式を呼び出します。

var expression = DelegateExpression; 

var results = query.AsExpandable().Select(entity => new AffectProjection() 
{ 
    AffectID = entity.AffectID, 
    AffectCode = entity.AffectCode, 
    AffectName = entity.AffectName, 
    AbleToDelete = expression.Invoke(entity) 
}).ToArray(); 

はしかし注意してください、それはあなたがフィールドから直接表現を使用することはできませんようだ、それがからにする必要がありローカル変数。

+0

実際にはアドオンが見つかりましたが、実装方法は不明でした。理にかなって、試してみましょう - 期待どおりに動くなら答えとしてマークしてください。ありがとう! – AdventurGurl

+0

それは魅力のように働いた!どうもありがとうございます :) – AdventurGurl

関連する問題