Dynamic Linq where clause throws OutOfMemoryException

c# dynamic-linq entity-framework expression-trees linq

Question

I am a total newbie when it comes to expression trees and Linq.

I discovered a generic expression procedure that constructs a basic Linq where clause at:
https://www.simple-talk.com/dotnet/net-framework/dynamic-linq-queries-with-expression-trees/

public Func<TSource,bool> SimpleFilter<TSource> (string property, object value)
{
    var type = typeof(TSource);
    var pe = Expression.Parameter(type, "p");
    var propertyReference = Expression.Property(pe,property);
    var constantReference = Expression.Constant(value);
    var ret = Expression.Lambda<Func<TSource, bool>>
        (Expression.Equal(propertyReference, constantReference), new[] { pe });
    return ret.Compile();
}

Invoking the function asSimpleFilter("JobCustomerID", 449152) it yields (p => p.JobCustomerId == 449152) , which is accurate.

I get the right response if I manually add that criterion to my Linq statement.

var jj = db.VW_Job_List.Where((p => p.JobCustomerId == 449152));

However, the Linq throws an exception when used with the filter function.OutOfMemoryException . In my application, I refer to it as:

var jj = db.VW_Job_List.Where(SimpleFilter<VW_Job_List>("JobCustomerID", 449152));

The method returns correctly if I call it with a text criterion:

var jj = db.VW_Job_List.Where(SimpleFilter<VW_Job_List>("CompanyCode", "LCS"));

Are there any special requirements that must be satisfied while utilizing integer variables? Do I have anything wrongly coded? Any ideas or information would be much appreciated.

1
3
12/7/2016 8:30:00 PM

Accepted Answer

The two calls

var jj = db.VW_Job_List.Where((p => p.JobCustomerId == 449152));

and

var jj = db.VW_Job_List.Where(SimpleFilter<VW_Job_List>("JobCustomerID", 449152));

are not the same. The first determinesQueryable.Where the filter is thus applied within the database, and the second - toEnumerable.Where causing the whole table to be loaded into memory and the filter to be applied there.

The issue is that the last two return kindSimpleFilter is Func<TSource, bool> They should be equal to make them comparable.Expression<Func<TSource, bool>> . Due to the varied overload resolution when applied to lambda expression and lambda delegate, there is a significant difference between them even though they seem to be aesthetically similar.IQueryable<T> .

Change the approach in the following way, then try again:

public Expression<Func<TSource,bool>> SimpleFilter<TSource> (string property, object value)
{
    var type = typeof(TSource);
    var pe = Expression.Parameter(type, "p");
    var propertyReference = Expression.Property(pe,property);
    var constantReference = Expression.Constant(value);
    var ret = Expression.Lambda<Func<TSource, bool>>
        (Expression.Equal(propertyReference, constantReference), new[] { pe });
    return ret; // No .Compile()
}
3
12/9/2016 9:49:59 AM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow