2010-05-25 90 views
9

我有代碼這樣的事情在LINQ的一個IRepository實施SQL:使用委託Linq中投影到SQL

var newlist = from h in list where h.StringProp1 == "1" 
         select new MyBusinessBO{ 
          firstProp = h.StringProp1, 
          secondProp = h.StringProp2 
         }; 

投影到MyBusinessBO不difificult但是當業務對象有許多屬性投影代碼變得非常冗長。此外,由於投影可能發生在Repository中的多個位置,我們打破了DRY原則。

有沒有什麼辦法來抽象出投影或用代表來替代它?

I.e.替換代碼

      firstProp = h.StringProp1, 
          secondProp = h.StringProp2 

可重複使用的東西?

回答

5

Queryable.Select要求Expression<Func<T, U>>。你可以編寫一個方法來返回它,並在你進行轉換的任何地方使用該方法。

public Expression<Func<DataObj, BusiObj>> GetExpr() 
{ 
    return h => new BusiObj() 
    { 
    firstProp = h.StringProp1, 
    secondProp = h.StringProp2 
    }; 
} 


//get a local variable holding the expression. 
Expression<Func<DataObj, BusiObj>> toBusiObj = GetExpr(); 

//use it thusly 
var newList = (from h in list where h.StringProp1 == "1" select h) 
    .Select(toBusiObj) 
    .ToList(); 

//or 
List<BusiObj> newList = list 
    .Where(h => h.StringProp1 == "1") 
    .Select(toBusiObj) 
    .ToList(); 
+0

與上面的ckknight非常類似,但是這看起來可能會更好,因爲它可以創建更清晰的代碼。它有一個單獨的可重用函數的投影,可以傳遞。凱克奈特得到了答案,但是大衛B,你的工作方式讓我到了我想成爲的地方。我已經提出了ckknight的答案並接受了這個答案。 – Redeemed1 2010-06-03 12:17:49

+0

被警告:使用'GetExpr()'函數在這裏顯示的確切語法是非常重要的。如果你有一個已經在幾個地方使用的DTE轉換方法,例如'public DTE Con​​vert(Entity entity)',你試圖轉換爲一個可重用的表達式,那麼你必須刪除'entity'參數並創建lambda,如下所示 - 否則將檢索該表中的每一列。 – 2013-07-12 10:54:53

0

看看AutoMapper和類似的工具

+0

是的,實際上已經廣泛使用automapper,在這種情況下,它不是最好的方法 – Redeemed1 2010-06-03 12:12:53

0

也許使用常規的非默認的構造函數,而不是對象初始化。或者,如果您可以開始使用C#4.0,請嘗試將可選/默認參數添加到組合中。

7

你可以通過使用點語法而不是LINQ風格的語法來解決這個問題。

您當前的:

list 
    .Where(h => h.StringProp1 == "1") 
    .Select(h => new MyBusinessBO 
    { 
     firstProp = h.StringProp1, 
     secondProp = h.StringProp2 
    }); 

潛在的解決方案:

Func<MyType, MyBusinessBO> selector = h => new MyBusinessBO 
{ 
    firstProp = h.StringProp1, 
    secondProp = h.StringProp2 
}; 
list 
    .Where(h => h.StringProp1 == "1") 
    .Select(selector); 

而且你可以在選擇通過某處或產生它的即時或類似的規定。

+0

好的答案。我甚至會更進一步,並將'Func'定義爲一種真正的方法。 OP想要重用該投影邏輯。 – Steven 2010-05-25 16:52:49

+0

你打敗了我。 +1 – 2010-05-25 16:55:05

+0

使用這個答案之前的一個考慮是'Func '不能用Entity Framework投影到SQL中。我意識到這個問題是針對'Linq-to-SQL',它可能能夠做投影,但是要寫更多的時間驗證代碼,使你的變量爲'Expression >'可能會更好。 – ErikE 2015-11-25 02:30:25