haydnD
haydnD

Reputation: 2293

LINQ expression error could not be translated

I'm getting this error with trying to execute my query.

System.InvalidOperationException: .Where(ti => (int)ti.Inner.OptionType == 1 && ti.Inner.QualifierId == null && ti.Inner.CreditingMethod != "xxx" && __ToList_0 .Any(e => e.Vdate== (Nullable)ti.Outer.ADate))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'

The object that I'm populating is

public class OCList
    {
        public DateTime? Vdate{ get; set; }
        public Double? VWeight{ get; set; }
    }

/// example of adding to the list
List<OCList> ocList= new List<OCList>();
            if (request.Date1 != null && request.Weight1 != null)
            {
                ocList.Add(new OCList{ Vdate = request.Date1.Value, VWeight = request.Weight1.Value });
            }

it error's here:

&& ocList.ToList().Any(e => e.Vdate == x.Tb2.ADate))

Linq expression:

var results = _context.Tb1
                .Join(_context.Tb2, oc => oc.OptionId, o => o.OptionId, (oc, o) => new { OptionCost = oc, Option = o })
                .Where(x => x.Tb2.Val1 == 1 
                    && x.Tb2.Val2 == null 
                    && ocList.ToList().Any(e => e.Vdate == x.Tb2.ADate))
                ////.........

Upvotes: 2

Views: 5198

Answers (1)

Athanasios Kataras
Athanasios Kataras

Reputation: 26450

Check client and server side evaluation here: https://learn.microsoft.com/en-us/ef/core/querying/client-eval

EF Core supports partial client evaluation in the top-level projection (essentially, the last call to Select()). If the top-level projection in the query can't be translated to the server, EF Core will fetch any required data from the server and evaluate remaining parts of the query on the client. If EF Core detects an expression, in any place other than the top-level projection, which can't be translated to the server, then it throws a runtime exception.

Your ToList and then Any can't be translated to sql and thus you get the error.

This would work

var results = _context.Tb1
                .Join(_context.Tb2, oc => oc.OptionId, o => o.OptionId, (oc, o) => new { OptionCost = oc, Option = o })
                .AsEnumerable()
                .Where(x => x.Tb2.Val1 == 1 
                    && x.Tb2.Val2 == null 
                    && ocList.ToList().Any(e => e.Vdate == x.Tb2.ADate))

BUT it would first fetch everything from the server and then apply the where clause, resulting to poor performance.

You could make it a bit better like this

var results = _context.Tb1
                .Join(_context.Tb2, oc => oc.OptionId, o => o.OptionId, (oc, o) => new { OptionCost = oc, Option = o })
                .Where(x => x.Tb2.Val1 == 1 
                    && x.Tb2.Val2 == null)
                .AsEnumerable()
                 .Where(ocList.ToList().Any(e => e.Vdate == x.Tb2.ADate))

Upvotes: 2

Related Questions