nev.angelova
nev.angelova

Reputation: 94

Error in a predicate with expression function

I'm using an expression function for predicate in LINQ Where method (that returns IQueryable result) which takes a class parameter:

    public ActionResult FilterProfiles(FilterViewModel filter)
    {
        var profiles = database.Profiles
            .Where(Predicate(filter))
            ...
    }

The predicate is:

    private static Expression<Func<UserProfile, bool>> Predicate(FilterViewModel f)
    {
       return p => (CompareFilter(p, f));
    }

The problem is with the CompareFilter function:

    private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
    {
        if (filter.FirstName != null)
        {
            if (profile.FirstName != null)
            {
                if (profile.FirstName.CompareTo(filter.FirstName) != 0)
                {
                    return false;
                }
            }
       ...
      }

The exception is:

LINQ to Entities does not recognize the method 'Boolean CompareFilter(Project.Models.UserProfile, Project.Web.ViewModels.FilterViewModel)' method, and this method cannot be translated into a store expression.

Exception Details: System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean CompareFilter(Project.Models.UserProfile, Project.Web.ViewModels.FilterViewModel)' method, and this method cannot be translated into a store expression.

Thanks in advance!

Upvotes: 0

Views: 604

Answers (1)

David
David

Reputation: 10708

The issue is that you're attempting to use a method in the lambda being translated by Entity Framework.

Entity Framework is actually using IQueryables to translate your method calls into SQL as you call them, to make querying a database seamless. This means, however, that any method you define is inherently outside the purview of Entity Framework, and it therefore cannot translate it into SQL, and thus fails. Even though you know the source, the Expression functions cannot access a compiled method as an expression tree.

A workarounf for this (and many other similar situations) is to use .AsEnumerable() which will cause further Linq calls to be the IEnumerable versions, which enumerate via foreach and thus pull our objects into memory.

Upvotes: 1

Related Questions