在Linq到SQL中使用委托进行投影

在Linq到SQL中使用委托进行投影,linq,linq-to-sql,Linq,Linq To Sql,我在Linq to Sql的IRepository实现中有类似的代码: var newlist = from h in list where h.StringProp1 == "1" select new MyBusinessBO{ firstProp = h.StringProp1, secondProp = h.StringProp2

我在Linq to Sql的IRepository实现中有类似的代码:

var newlist = from h in list where h.StringProp1 == "1"
                      select new MyBusinessBO{
                          firstProp = h.StringProp1,
                          secondProp = h.StringProp2
                      };
到MyBusinessBO的投影并不困难,但当业务对象具有许多属性时,投影代码会变得非常冗长。此外,由于投影可能发生在存储库中的多个位置,因此我们打破了干燥原则

有没有办法抽象出投影或用委托替换它

即替换代码

                          firstProp = h.StringProp1,
                          secondProp = h.StringProp2

有了可重用的东西?

看看,类似的工具可能会使用常规的非默认构造函数,而不是对象初始值设定项。或者,如果您可以开始使用C4.0,尝试向混合中添加可选/默认参数。

您可以使用点语法而不是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);
您可以将选择器传入某个位置,或动态生成选择器,或沿这些行生成选择器。

Queryable.Select需要一个表达式。您可以编写一个方法来返回该值,并在执行转换的任何地方使用该方法

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();

回答得好。我甚至会更进一步,将Func定义为一个真正的方法。OP希望重用该投影逻辑。在使用此答案之前,需要考虑的一个问题是Func不能用实体框架投影到SQL中。我意识到问题的目标是Linq to SQL,它可能能够进行投影,但是要编写更多的时间证明代码,使变量成为表达式可能会更好。是的,实际上已经广泛使用automapper,在这种情况下,它不是最好的方法与上面的ckknight非常相似,然而,这似乎是一种更好的方法来创建更清晰的代码。它在一个单独的可重用函数中具有投影,该函数可以被传递。克奈特得到了答案,但是大卫B,你以一种让我到达我想要的地方的方式解决了这个问题。我已经对ckknight的答案进行了投票,并接受了这个答案。请注意:对于GetExpr函数,使用此处显示的确切语法是非常重要的。如果您有一个预先存在的DTE转换方法,您已经在多个地方使用过,例如您正试图转换为可重用表达式的public DTE ConvertEntity实体,则必须删除实体参数并创建lambda,如图所示,否则将检索该表中的每一列。