Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use delegate for Projection in Linq to SQL

I have code something like this in an IRepository implementation in Linq 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?

like image 711
Redeemed1 Avatar asked May 25 '10 16:05

Redeemed1


People also ask

Does LINQ use delegates?

It is still supported but generally the modern C# programmers understand Predicate as a special kind of Func delegate. This kind of func delegate returns a bool. This is mostly used in expressions and LINQ.

How does a LINQ query transform to a SQL query?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

What is projection in LINQ?

In LINQ, projection is an operation which converts an object into the new form which holds only those properties that will be subsequently used. By using projection, a developer can create a new type which is built from each object.

Is LINQ to SQL deprecated?

While it is not dead or dying, it is deprecated. That is the main question. There are articles from Microsoft saying the move is to push their flagship ORM - EF. L2S is Fully Supported, and critical for everyone to know / learn...


2 Answers

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.

like image 108
ckknight Avatar answered Jan 01 '23 19:01

ckknight


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();
like image 23
Amy B Avatar answered Jan 01 '23 19:01

Amy B