2010-05-25 57 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