LINQ to实体无法识别该方法

本文关键字:识别 方法 to 实体 LINQ | 更新日期: 2023-09-27 18:00:40

我理解为什么我会出现以下错误,但我不确定如何提供解决方案。

{System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean IsStatus(CDAX.DataModel.ProcessStatusEnum)' method, and this method cannot be translated into a store expression.

我不想只返回IEnumerable,因为我想将过滤器转换为底层SQL语句,这样我就不会查询太多行等

    public override IQueryable<Session> GetQuery()
    {
        Func<Session, bool> activeSessions = (session) => !session.IsStatus(ProcessStatusEnum.Deleted);
        // these functions are causing issues.  I'm not sure how to change them to
        // work with IQueryable??   
        return base.GetQuery().Where(p => activeSessions(p) && _queryFilter.FilterOn(p.Customer));
    }

queryFilter类是一个接口,例如:

public interface IDataQueryFilter
{
    bool FilterOn(Customer obj);
}

客户只是我数据库中的一个实体对象,具有Id、CustomerNumber等属性。

Session是我数据库中的另一个Entity对象,IsStatus方法如下:

    public bool IsStatus(ProcessStatusEnum status)
    {
        return SessionStatus == (byte)status;
    }

我使用的条件通常非常简单,所以我相信它们应该能够转换为SQL。我想这只是因为它们在函数中,所以它们不能。我可以用其他东西作为返回类型吗?

LINQ to实体无法识别该方法

LINQ to Entities正在尝试将LINQ查询转换为SQL语句。现在它不知道如何直接在数据库上执行自定义Func,所以它抛出了这个错误。

您可以简单地将IsStatus方法更改为session.Status == ProcessStatusEnum.Deleted,但很可能会在第二个函数中出现错误。

"修复"此问题的最简单方法是在数据库上要执行的部分和内存中要执行的部件之间放置.ToList()。显然,数据库中的内容越多越好。

对于过滤器,您可以考虑将FilterOn更改为返回表达式树的方法:

public interface IDataQueryFilter
{
    Expression<Func<Customer, bool>> FilterOn();
}

例如,如果你想让伦敦的所有客户都通过LondonCustomFilter:的一个实例

public class LondonCustomFilter : IDataQueryFilter {
    Expression<Func<Customer, Bool>> FilterOn() {
        return (customer) => customer.City == "London";
    }
}

您的IsStatus方法调用无法转换为SQL。我建议您在没有方法调用的情况下手动进行状态验证。

(session) => session.Status != ProcessStatusEnum.Deleted

另一种选择是将所有实体放入内存(通过执行ToList()),但这会很慢。