[ACCEPTED]-Using Function in Select Clause of Entity Framework Query-entity-framework

Accepted answer
Score: 13

The simplest way is probably to just "move" the 8 execution to the client to perform the transformation. In 7 this case you'd just use:

var items = myContext.Select(item => new { item.Value1, item.Value2 })
                     .AsEnumerable()
                     .Select(item => new {
                                 Value1 = TweakValue(item.Value1),
                                 Value2 = TweakValue(item.Value2)
                             });

Note that you don't 6 have to reuse the names for Value1 and Value2 - it's just 5 easiest to do so.

If you really want to use 4 query expressions:

var query = from item in myContext
            select new { item.Value1, item.Value2 };

var items = from item in query.AsEnumerable()
            select new {
                Value1 = TweakValue(item.Value1),
                Value2 = TweakValue(item.Value2)
            };

If you want to perform 3 filtering first, you can get that to occur in 2 the database by putting the filtering, ordering 1 etc before the call to AsEnumerable(). For example:

var query = from item in myContext
            where item.Foo == bar
            orderby item.Something
            select new { item.Value1, item.Value2 };

var items = from item in query.AsEnumerable()
            select new {
                Value1 = TweakValue(item.Value1),
                Value2 = TweakValue(item.Value2)
            };
Score: 5

You don't need a loop, just another projection:

var items =  myContext.Select(i => new {
                 Value1 = item.Value1,
                 Value2 = item.Value2
             })
             .AsEnumerable()
             .Select(i => new {
                 Value1 = TweakValue(item.Value1),
                 Value2 = TweakValue(item.Value2)
              });

Edit: Depending 7 on what TweakValue actually does, you can push the 6 whole thing to the server. Riffing on your 5 current example:

public Expression<Func<Item, ItemProjection>> TweakValue()
{
    return item => new ItemProjection 
                   {
                       Value1 = item.Value1,
                       Value2 = item.Value2 + 0 // or something else L2E can understand...
                   }; 
}

Now use it like:

var exp = TweakValue();
var items =  myContext.Select(exp);

Note I'm 4 storing exp in a variable so that L2E doesn't 3 try to directly invoke TweakValue in the query, which 2 would fail.

Naturally, this only works if 1 TweakValue does stuff that L2E can do.

More Related questions