Use delegate for Projection in Linq to SQL
I have code something like this in an IRepository implementation in Lin开发者_如何学Goq to Sql:
var newlist = from h in list where h.StringProp1 == "1"
select new MyBusinessBO{
firstProp = h.StringProp1,
secondProp = h.StringProp2
};
The projection into MyBusinessBO is not difificult but when the Business Object has many properties the projection code becomes very lengthy. Also, as the projection can occur in several places in the Repository we break the DRY principle.
Is there any way to abstract out the projection or replace it with a delegate?
I.e. replace the code
firstProp = h.StringProp1,
secondProp = h.StringProp2
with something reusable?
You could solve this by using the dot syntax rather than the LINQ-style syntax.
Your current:
list
.Where(h => h.StringProp1 == "1")
.Select(h => new MyBusinessBO
{
firstProp = h.StringProp1,
secondProp = h.StringProp2
});
Potential solution:
Func<MyType, MyBusinessBO> selector = h => new MyBusinessBO
{
firstProp = h.StringProp1,
secondProp = h.StringProp2
};
list
.Where(h => h.StringProp1 == "1")
.Select(selector);
And you could pass in the selector somewhere or generate it on-the-fly or something along those lines.
Queryable.Select
requires an Expression<Func<T, U>>
. You can write a method that returns this and use that method everywhere you do the transformation.
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();
Take a look at AutoMapper and similar tools
Perhaps use regular non-default constructors, rather than object initializers. Or, if you can start using C# 4.0, try to add optional/default parameters to the mix.
精彩评论