Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using a lambda expression passed into a method slow down an Entity Framework query?

I have a method:

public static void GetObjects()
{
    using(MyContext context = new MyContext())
    {
         var objects = context.Bars.Where(b => b.Prop1 != null)
                       .Select(b => new MyObject{Prop = b.Prop1, Name = b.Name})
                       .ToList();
         foreach(var object in objects)
         {
             // do something with the object
         }
    }
}

I refactored the method to make it more general so that I can pass in a Func so that I can specify the where statement and what property from the Bars table gets assigned to MyObject.Prop like this:

public static void GetObjectsV2(Func<Bar, bool> whereFunc, Func<Bar, string> selectPropFunc)
{
    using(MyContext context = new MyContext())
    {
         var objects = context.Bars.Where(whereFunc)
                       .Select(b => new MyObject{Prop = selectPropFunc(b), Name = b.Name})
                       .ToList();
         foreach(var object in objects)
         {
             // do something with the object
         }
    }
}

GetObjectsV2 seems to run much slower than GetObjects. Are there any reasons this would affect performance, and if so, are there any ways around this while still keeping the function flexible?

like image 775
aubreyrhodes Avatar asked Jan 31 '11 19:01

aubreyrhodes


People also ask

Can I use lambda expressions with Skip and take in LINQ+EF?

If you're using Entity Framework 6, then you can switch to using lambda expressions with Skip and Take. The benefit here is that LINQ+EF will now recognize your Skip and Take values as parameters that can be passed to a compiled query. The change looks like this in Visual Basic: Dim sos = db.SalesOrders.Skip(Function() pos).Take(Function() size)

How to use LambdaExpression to test a method?

The easiest approach is to use an extension method for LambdaExpression composition. It depends on some Expression extension methods for replacing one Expression with another in an Expression: Now you can create your method that takes a lambda representing the field you want to test.

What is a lambda expression in C++?

In C++11 and later, a lambda expression—often called a lambda —is a convenient way of defining an anonymous function object (a closure) right at the location where it is invoked or passed as an argument to a function. Typically lambdas are used to encapsulate a few lines of code that are passed to algorithms or asynchronous methods.

How to replace one expression with another in a lambda expression?

The easiest approach is to use an extension method for LambdaExpression composition. It depends on some Expression extension methods for replacing one Expression with another in an Expression:


1 Answers

The reason it is running slower is because you are passing in a Func<Bar, bool> which forces the context to retrive ALL Bars and then run the Func on the returned result set. A way to make this run better is to pass in Expression<Func<Bar, bool>>

Putting that all together will result in the following:

public static void GetObjectsV2(Expression<Func<Bar, bool>> whereFunc, Expression<Func<Bar, string>> selectPropFunc)
{
    using(MyContext context = new MyContext())
    {
         var objects = context.Bars.Where(whereFunc)
                       .Select(selectPropFunc)
                       .ToList();
         foreach(var object in objects)
         {
             // do something with the object
         }
    }
}
like image 175
Mark Coleman Avatar answered Sep 21 '22 11:09

Mark Coleman