.net LINQ to Entities 无法识别该方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7259567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 15:52:10  来源:igfitidea点击:

LINQ to Entities does not recognize the method

.netlinqentity-frameworklinq-to-entitiesspecification-pattern

提问by annelie

I'm getting the following error when trying to do a linq query:

尝试执行 linq 查询时出现以下错误:

LINQ to Entities does not recognize the method 'Boolean IsCharityMatching(System.String, System.String)' method, and this method cannot be translated into a store expression.

LINQ to Entities 无法识别方法 'Boolean IsCharityMatching(System.String, System.String)' 方法,并且此方法无法转换为存储表达式。

I've read lots of previous questions where people get the same error, and if I understand this correctly it's because LINQ to Entities requires the whole linq query expression to be translated to a server query, and therefore you can't call an outside method in it. I haven't been able to convert my scenario into something that works yet, and my brain is starting to melt down, so I was hoping someone could point me in the right direction. We're using Entity Framework and the specification pattern (and I'm new to both).

我已经阅读了很多以前的问题,人们遇到了同样的错误,如果我理解正确,那是因为 LINQ to Entities 需要将整个 linq 查询表达式转换为服务器查询,因此您不能调用外部方法在里面。我还没有能够将我的场景转换成可行的东西,我的大脑开始崩溃,所以我希望有人能指出我正确的方向。我们正在使用实体框架和规范模式(我对两者都是新手)。

Here's the code that uses the specification:

这是使用规范的代码:

ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);

charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();

Here's the linq expression:

这是 linq 表达式:

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    return p => p.IsCharityMatching(this.charityName, this.charityReference);
}

Here's the IsCharityMatching method:

这是 IsCharityMatching 方法:

public bool IsCharityMatching(string name, string referenceNumber)
{
    bool exists = true;

    if (!String.IsNullOrEmpty(name))
    {
        if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
            !this.alias.ToLower().Contains(name.ToLower()) &&
           !this.charityId.ToLower().Contains(name.ToLower()))
        {
            exists = false;
        }
    }

    if (!String.IsNullOrEmpty(referenceNumber))
    {
        if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
        {
            exists = false;
        }
    }

    return exists;
}

Let me know if you need any more information.

如果您需要更多信息,请告诉我。

Many thanks,

非常感谢,

Annelie

安妮莉

回答by StriplingWarrior

As you've figured out, Entity Framework can't actually run your C# code as part of its query. It has to be able to convert the query to an actual SQL statement. In order for that to work, you will have to restructure your query expression into an expression that Entity Framework can handle.

正如您已经发现的那样,实体框架实际上无法将您的 C# 代码作为其查询的一部分运行。它必须能够将查询转换为实际的 SQL 语句。为了使其工作,您必须将查询表达式重组为实体框架可以处理的表达式。

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    string name = this.charityName;
    string referenceNumber = this.referenceNumber;
    return p => 
        (string.IsNullOrEmpty(name) || 
            p.registeredName.ToLower().Contains(name.ToLower()) ||
            p.alias.ToLower().Contains(name.ToLower()) ||
            p.charityId.ToLower().Contains(name.ToLower())) &&
        (string.IsNullOrEmpty(referenceNumber) ||
            p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}

回答by Ing. Gerardo Sánchez

I got the same error in this code:

我在这段代码中遇到了同样的错误:

 var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

this was the exactly error:

这正是错误:

System.NotSupportedException: 'LINQ to Entities does not recognize the method 'Boolean Exists(System.Predicate`1[conector_gp.Models.almacenes_por_sucursal])' method, and this method cannot be translated into a store expression.'

System.NotSupportedException: 'LINQ to Entities 无法识别方法 'Boolean Exists(System.Predicate`1[conector_gp.Models.almacenes_por_sucursal])' 方法,并且此方法无法转换为存储表达式。

I solved this way:

我是这样解决的:

var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

I added a .ToList()before my table, this decouple the Entity and linq code, and avoid my next linq expression be translated

我在我的表之前添加了一个.ToList(),这将实体和 linq 代码解耦,并避免我的下一个 linq 表达式被翻译

NOTE:this solution isn't optimal, because avoid entity filtering, and simply loads all table into memory

注意:这个解决方案不是最优的,因为避免实体过滤,只是将所有表加载到内存中

回答by Mik

If anyone is looking for a VB.Net answer (as I was initially), here it is:

如果有人正在寻找 VB.Net 答案(就像我最初那样),这里是:

Public Function IsSatisfied() As Expression(Of Func(Of Charity, String, String, Boolean))

Return Function(charity, name, referenceNumber) (String.IsNullOrWhiteSpace(name) Or
                                                         charity.registeredName.ToLower().Contains(name.ToLower()) Or
                                                         charity.alias.ToLower().Contains(name.ToLower()) Or
                                                         charity.charityId.ToLower().Contains(name.ToLower())) And
                                                    (String.IsNullOrEmpty(referenceNumber) Or
                                                     charity.charityReference.ToLower().Contains(referenceNumber.ToLower()))
End Function

回答by Michael Fayad

I had a similar problem to yours and this LINQ documentationhelped me find the right string functions to work around the limitations.

我遇到了和你类似的问题,这个 LINQ 文档帮助我找到了正确的字符串函数来解决这些限制。