首页 > 解决方案 > LINQKit + EF Core:Where 子句作为方法错误

问题描述

我正在使用 LINQKit.Core 1.1.17,我想在 Expression Func 中使用我的方法。我的问题是我收到错误:

无法翻译 LINQ 表达式 'DbSet .Where(v => TestService.Distance( x1: __current_X_0, y1: __current_Y_1, x2: vX, y2: vY) < __8__locals1_maxDistance_2)'。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2101038

这是我的代码。

表达:

Expression<Func<Test, bool>> exp = v => Distance(current.X, current.Y, v.X, v.Y) < maxDistance;

距离法:

    private double Distance(int x1, int y1, int x2, int y2)
    {
        var x = Math.Abs(x1 - x2);
        var y = Math.Abs(y1 - y2);

        return Math.Sqrt(x ^ 2 + y ^ 2);
    }

是否可以使用 LINQKit 来实现?有没有更好的方法来以这种方式查询数据库?

标签: c#entity-frameworklinqkit

解决方案


您可以将此方法定义为标记为ExpandableAttribute

public static class HelperFunctions
{
    [Expandable(nameof(DistanceImpl))]
    public static double Distance(int x1, int y1, int x2, int y2)
    {
        var x = Math.Abs(x1 - x2);
        var y = Math.Abs(y1 - y2);

        return Math.Sqrt(x ^ 2 + y ^ 2);
    }

    private static Expression<Func<int, int, int, int, double>> DistanceImpl()
    {
        rerutn (x1, y1, x2, y2) =>
            Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }
}

然后您可以在过滤器中使用此功能:

var query = query
   .AsExpandable()
   .Where(q => HelperFunctions.Distance(q.x1, q.y1, q.x2, q.y2) < maxDistance);

LINQKit 将注入定义的 lambda 主体DistanceImpl并使 EF LINQ 翻译器满意。


推荐阅读