开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜