我在Linq to Sql的IRepository实现中有类似的代码:
var newlist = from h in list where h.StringProp1 == "1"
select new MyBusinessBO{
firstProp = h.StringProp1,
secondProp = h.StringProp2
};
对MyBusinessBO的投影并不重要,但是当业务对象具有许多属性时,投影代码变得非常冗长。此外,由于投影可能发生在存储库中的几个地方,我们打破了DRY原则。
有没有办法抽象出预测或用代表替换它?
即。替换代码
firstProp = h.StringProp1,
secondProp = h.StringProp2
有可重复使用的东西吗?
答案 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);
你可以在某处传递选择器,或者即时生成它或者沿着这些线生成它。
答案 1 :(得分: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();
答案 2 :(得分:0)
查看AutoMapper及类似工具
答案 3 :(得分:0)
也许使用常规的非默认构造函数,而不是对象初始值设定项。或者,如果您可以开始使用C#4.0,请尝试在混合中添加可选/默认参数。