Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PredicateBuilder is not working on EF Core

public string[] FindAssets2()
{
    string[] result;

    using (var ctx = new StockContext())
    {
        var predicate = PredicateBuilder.New<Asset>().Or(asset => asset.Symbol.Contains("TSLA"));

        result = ctx.Assets.AsExpandable()
        .Where(predicate)
        .Select(z => z.Symbol)
        .ToArray();
    }

    return result;
}

Just a piece of simple codes. It throws me

Exception: Unhandled expression type: 'Extension'
LinqKit.ExpressionVisitor.Visit(Expression exp)
LinqKit.ExpressionVisitor.VisitExpressionList(ReadOnlyCollection<Expression> original)
LinqKit.ExpressionVisitor.VisitMethodCall(MethodCallExpression m)
LinqKit.ExpressionVisitor.Visit(Expression exp)
LinqKit.Extensions.Expand(Expression expr)
LinqKit.ExpandableQueryProvider<T>.System.Linq.IQueryProvider.CreateQuery<TElement>(Expression expression)
System.Linq.Queryable.Where<TSource>(IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)

Below is my installed package

    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0-preview.4.20220.10" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.4.20220.10" />
    <PackageReference Include="LINQKit.Core" Version="1.1.17" />

Any help would be appreciate. Many thanks!

like image 886
mannok Avatar asked Jun 25 '20 15:06

mannok


1 Answers

It seems that EF-core 5 doesn't play nice with AsExpandable. Or rather the other way around. It worked with EF3, but apparently Linqkit isn't resilient to library-specific idiosyncrasies of expression trees.

There is a work-around for this case. As expained here, predicate is not an Expression, but an ExpressionStarter, which implicitly converts to Expression<Func<T, bool>> and Func<T, bool>. Therefore, queries with predicates on top-level entities (say: EF's IQueryables) work without AsExpandable:

result = ctx.Assets   // No '.AsExpandable()'
    .Where(predicate) // Implicit conversion of 'predicate' to Expression<Func<Asset,boo>l>
    .Select(z => z.Symbol)
    .ToArray();

The bad news is that without any fixes in this area, you won't be able to use AsExpandable when it's really necessary, for example for predicates on collection navigation properties.

like image 158
Gert Arnold Avatar answered Nov 11 '22 04:11

Gert Arnold