2010-07-16 71 views
3

我現在有看起來有點像這樣:如何在LINQ中創建動態選擇表達式?

if(userLikesBananas) 
{ 
    return from fruit in basket 
      select new Fruit 
      { 
       AteBanana = Bowl.Any(b => b.OwnedBy == user && b.Contains(fruit) && fruit.Type == FruitType.Banana), 
       ... 
       ... 
       //lots of properties 
       ... 
      } 
} 
else 
{ 
    return from fruit in basket 
      select new Fruit 
      { 
       AteBanana = Bowl.Any(b => b.Contains(fruit)), 
       ... 
       ... 
       //lots of properties 
       ... 
      } 
} 

不可否認的例子,使絕對沒有任何意義,但原則是,我想改變基於任意條件的性質選擇的條件。現在選擇語句重複。

現在是時候了,我需要添加依賴於標準的依賴器。我不想在4個不同的情況下,財產狀況稍有不同。

我想要做的,是這樣的:

Func<Fruit, bool> fruitFunc = f => false; 

if(userLikesBananas) 
{ 
    fruitFunc = f => Bowl.Any(b => b.OwnedBy == user && b.Contains(f) && f.Type == FruitType.Banana); 
} 
else 
{ 
    fruitFunc = f => Bowl.Any(b => b.Contains(f)); 
} 

return from fruit in basket 
     select new Fruit 
     { 
      AteBanana = fruitFunc(fruit) 
      ... 
      ... 
      //lots of properties 
      ... 
     }; 

麻煩的是,是表達不能轉換爲SQL,因爲它包含一個動態調用。我曾嘗試在Expression中包裝Func,但似乎出現了同樣的問題。

所以問題是,我該如何避免複製和粘貼?

回答

3

...我的英語不是很好,但我會試着解釋如何輕鬆地解決這個問題: - )

動態的LINQ是壞的類型的控制 - 它很容易使用,但您無法瀏覽生成的對象(x.Name,x.Surname等)

有(痘痘noob-喜歡)技巧來解決這個問題(我使用它和它的工作fain):

  1. 創建enum,其中包含要從中選擇的對象的屬性。

    公共枚舉MyAtrs {ID,名字,姓}

  2. 創建Dictionary<MyAtrs,bool>(並填寫)條件(設置true如果你想獲得該屬性)

    公衆解釋迪科=新詞典( ); Dic.Add(MyAtrs.ID,true); Dic.Add(MyAtrs.Firstname,false); Dic.Add(MyAtrs.Surname,true);

  3. 內置查詢:

    變種查詢= DBContext.MyDBTable.Where(謂詞)。選擇(E =>新的{ ID =迪科[MyAtrs.ID] e.dbID:0, 姓= Dic [MyAtrs.Firstname]?e.dbFirstname:null, Surname = Dic [MyAtrs.Surname]?e。dbSurname:null, });

在這種情況下,SQL Select語句中將有全部3列,但它只是幾個字節(誰負責......)。 SQL Server爲您提供了所有3列,但在這種情況下,Firstname將爲空(類似{ID = 123,Firstname =,Surname =「Jobs」})。 這不是很精彩,但它很容易的方法如何建立「動態」選擇表達式而不會丟失類型控制:)

0

我可以建議以不同的方式寫Func(也許是這樣的):

fruitFunc = f => Bowl.Any(b => ((f.Type == FruitType.Banana && b.OwnedBy == user && userLikesBananas) || !userLikesBananas) && b.Contains(f)); 

我沒有測試它是否正常工作,但是這可能是寫來覆蓋更多的情況下功能的方法(不僅2)。該方法是某種類似於布爾我記得代數...

乾杯......

+0

這種方法將意味着整個表達式將被轉換爲SQL,'userLikesBananas'將被傳入。我正在尋找這意味着表達式在被轉換爲sql之前被調整。使用if語句將會產生一個更清晰的查詢,但是這是個好主意,謝謝。 – SteadyEddi 2010-07-16 13:29:09

相關問題