2012-01-26 47 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))); 

最後但並非最不重要的,這個解決方案編譯,但在與錯誤運行時失敗:「NotSupportedException異常 - 的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

相關問題