LINQ to Entities does not recognize the method

147,505

Solution 1

As you've figured out, Entity Framework can't actually run your C# code as part of its query. It has to be able to convert the query to an actual SQL statement. In order for that to work, you will have to restructure your query expression into an expression that Entity Framework can handle.

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    string name = this.charityName;
    string referenceNumber = this.referenceNumber;
    return p => 
        (string.IsNullOrEmpty(name) || 
            p.registeredName.ToLower().Contains(name.ToLower()) ||
            p.alias.ToLower().Contains(name.ToLower()) ||
            p.charityId.ToLower().Contains(name.ToLower())) &&
        (string.IsNullOrEmpty(referenceNumber) ||
            p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}

Solution 2

I ran into the same problem today, this was the first link I hit. However I was not looking for verifying my query. So if somebody else has the same issue and are looking for this solution it is added here. My issue was in another link.

It is the most common exception occurs when working with entity framework and converting data inside IQueryable result for filtering.

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems
        .Where(i => i.Code == code.ToString())
        .FirstOrDefault();
}

Several solutions exist. Move ToString() call to a separate line.

using (var context = new CustomerContext())
{
    string codeStr = code.ToString();
    var item = context.InvoiceItems
        .Where(i => i.Code == codeStr)
        .FirstOrDefault();
}

Use EF Extension Method,

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems
        .Where(i => i.Code == SqlFunctions.StringConvert(code))
        .FirstOrDefault();
}

Convert IQueryable result to IEnumerable before Filtering

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems.AsEnumerable()
        .Where(i => i.Code == code.ToString())
        .FirstOrDefault();
}

Solution 3

I got the same error in this code:

 var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

this was the exactly error:

System.NotSupportedException: 'LINQ to Entities does not recognize the method 'Boolean Exists(System.Predicate`1[conector_gp.Models.almacenes_por_sucursal])' method, and this method cannot be translated into a store expression.'

I solved this way:

var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

I added a .ToList() before my table, this decouple the Entity and linq code, and avoid my next linq expression be translated

NOTE: this solution isn't optimal, because avoid entity filtering, and simply loads all table into memory

Share:
147,505
annelie
Author by

annelie

Updated on June 01, 2021

Comments

  • annelie
    annelie about 3 years

    I'm getting the following error when trying to do a linq query:

    LINQ to Entities does not recognize the method 'Boolean IsCharityMatching(System.String, System.String)' method, and this method cannot be translated into a store expression.

    I've read lots of previous questions where people get the same error, and if I understand this correctly it's because LINQ to Entities requires the whole linq query expression to be translated to a server query, and therefore you can't call an outside method in it. I haven't been able to convert my scenario into something that works yet, and my brain is starting to melt down, so I was hoping someone could point me in the right direction. We're using Entity Framework and the specification pattern (and I'm new to both).

    Here's the code that uses the specification:

    ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);
    
    charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();
    

    Here's the linq expression:

    public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
    {
        return p => p.IsCharityMatching(this.charityName, this.charityReference);
    }
    

    Here's the IsCharityMatching method:

    public bool IsCharityMatching(string name, string referenceNumber)
    {
        bool exists = true;
    
        if (!String.IsNullOrEmpty(name))
        {
            if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
                !this.alias.ToLower().Contains(name.ToLower()) &&
               !this.charityId.ToLower().Contains(name.ToLower()))
            {
                exists = false;
            }
        }
    
        if (!String.IsNullOrEmpty(referenceNumber))
        {
            if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
            {
                exists = false;
            }
        }
    
        return exists;
    }
    

    Let me know if you need any more information.

    Many thanks,

    Annelie

  • Chris Hayes
    Chris Hayes over 9 years
    when in doubt search it out: stackoverflow.com/questions/2352764/…
  • Travis J
    Travis J almost 7 years
    Returning a constructed Expression<Func<T,type>> is a very nice approach to this.
  • Zorgarath
    Zorgarath over 6 years
    How would you use this in a LINQ expression? I would like to do something like this as a re-usable Where clause but am struggling with implementing it.
  • Zorgarath
    Zorgarath over 6 years
    EDIT: nevermind, it would be : context.Where(IsSatisfied())
  • Alper
    Alper over 5 years
    Key part: "Entity Framework can't actually run your C# code as part of its query. "
  • Diógenes
    Diógenes over 5 years
    Most of time this the easiest solution but to not load all the object i usually make a anonymous select before the .ToList() with just what i need... xx.Select(x=> new { x.Id, x.DateTimeUpdate}).ToList().Select(x=> new { x.Id, DateTimeUpdate = x.DateTimeUpdate.ToString("dd/MM/yyyy") })