question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

EFCore Linq Query Could not be translated and will be evaluated locally

See original GitHub issue

This is more of an enhancement. I have seen other posts, and I understand there are numerous possibilities as to why a Linq Query could not be translated. However, I believe this should not only be a fairly simple enhancement, but it should serve a great many developers. Below is the warning message provided by EF Core, then the steps to reproduce the error, then the suggested enhancement.

Warning:

Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'where Invoke(__isActiveItem_0, [x])' could not be translated and will be evaluated locally.
### Steps to reproduce

Create a Func and predicate scenario. It can be extremely simple:

public static class DisplayFilters
    {
        /// the business need here is to still use the deleted item for internal reports and looking good if the client accidentally deletes the item.
        public static Func<DisplayItem, bool> isActiveItem = (x) => x.IsDeleted == false;
        .... 
       (n) number of composable filter functions. More complex functions could rely on multiple nested  functions
       ///additional pure/transparent functions could be created not just based on filtering, but grouping/joining etc
    }

Create a simple controller with get logic to use the function

using  f = namespace.DisplayFilters;
...
       [HttpGet]
        public IActionResult Get()
        {
            IEnumerable<DisplayItem> xItem = _context.DisplayItem.Where(x => f.isActiveItem(x));
            return Ok(xItem);
        }
### Further technical details
EF Core version: (2.0.2)
Database Provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Operating system: Windows 10
IDE: (Visual Studio 2017)

This ultimately is a simple example. But this is the start of a larger need. An application can quickly grow where all our statements are becoming more complex, and the logic for this business rule can be strewn everywhere.

Imagine dealing with dozens of linq queries, and statically referencing x.isDeleted == false hundreds of times, when now, the business says active items also rely on the created date property to be greater than 30 days.

Since a composable function like above will always require the object itself DisplayItem to be passed in, a linq to sql query should always know what Where clause to be modifying, what sub Select query or otherwise to modify.

Thank you

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
smitpatelcommented, Mar 20, 2018

Is there any specific reason you are using Func<DisplayItem, bool> instead of Expression<Func<DisplayItem, bool>> ?

The reason I ask this because, unless the expression is passed into the linq query, the function call itself would become opaque to EF Core. The Expression tree generated by compiler when you use func does not allow us to inspect what is inside of the Func, hence EF Core cannot translate the body of the func and has to do client evaluation. If you use Expression<Func<>> inside linq query then EF Core would translate that to Server.

4reactions
CodeSwimBikeRunnercommented, Mar 22, 2018

Thank you for taking the time to explain the issue, and provide me with enough information to research ExpressionTrees. For anyone who stumbles across this in the future, this is what I did.

The Expression:

public static class DisplayFilters
    {

        public static Expression<Func<DisplayItem, bool>> byProperty(int val)
        {
            ConstantExpression constant = Expression.Constant(val, typeof(int));
            ParameterExpression iParam = Expression.Parameter(typeof(DisplayItem), "x");
            MemberExpression prop = Expression.Property(iParam, "Property"); /// be sure it's the property on the generated model.
            BinaryExpression equalTo = Expression.Equal(constant, prop);
            return Expression.Lambda<Func<DisplayItem, bool>>(equalTo, iParam);
        }
    }

And its usage:

using df = namespace.DisplayFilters;
...
        [HttpGet("GetByPropValue/{prop}")]
        public IActionResult GetAllActive(int prop)
        {

            return Ok(_context.DisplayItem.Where(
                        df.byProperty(prop)
                 ));
        }

This will generate the correct sql on the server side.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - The LINQ expression could not be translated and will ...
Since Equals can't be used, the warning says that the data is fetched locally before the Where is executed. So it might be...
Read more >
Why a simplest ef core query throws 'cannot be translated ...
This seems very strange. The expression you are using for Select is placed into Where section of the genrated LINQ expression. Is it...
Read more >
LINQ Expression Could not Be Translated - Microsoft Q&A
Hello everyone and thanks for the help in advance. I am creating a MVC application uisng .Net 6 and EF 6 to query...
Read more >
The Query (LINQ) expression could not be Translated ...
The Query (LINQ) expression could not be Translated Entity Framework Core · Entity Framework Core evaluates a LINQ query on the server side...
Read more >
C# – The LINQ expression could not be translated and will ...
Linq – EF core Linq groupby and having sum count – could not be translated and will be evaluated locally. If possible, upgrade...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found