LINQ to Entities不识别该方法

i1icjdpr  于 2023-09-28  发布在  其他
关注(0)|答案(5)|浏览(125)

我在尝试执行linq查询时遇到以下错误:
LINQ to Entities无法识别方法“Boolean IsCharityMatching(System.String,System.String)”方法,并且此方法无法转换为存储表达式。
我读过很多以前的问题,人们得到了同样的错误,如果我理解正确的话,这是因为LINQ to Entities需要将整个linq查询表达式转换为服务器查询,因此您不能在其中调用外部方法。我还没能把我的剧本转换成可行的东西,我的大脑开始融化了,所以我希望有人能给我指出正确的方向。我们正在使用实体框架和规范模式(我对这两个都是新手)。
下面是使用该规范的代码:

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

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

下面是linq表达式:

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

下面是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;
}

如果你需要更多的信息就告诉我。
非常感谢
安娜莉

zpqajqem

zpqajqem1#

正如你所发现的,实体框架实际上不能将你的C#代码作为查询的一部分来运行。它必须能够将查询转换为实际的SQL语句。为了使其工作,您必须将查询表达式重新构造为Entity Framework可以处理的表达式。

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()));
}
mspsb9vt

mspsb9vt2#

我今天遇到了同样的问题,这是我点击的第一个链接。然而,我并不是在寻找验证我的查询。因此,如果其他人有同样的问题,并正在寻找这个解决方案,它被添加在这里。我的问题是在另一个link
这是在使用实体框架并转换IQueryable结果中的数据以进行筛选时最常见的异常。

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems
        .Where(i => i.Code == code.ToString())
        .FirstOrDefault();
}

存在若干解决方案。将ToString()调用移动到单独的行。

using (var context = new CustomerContext())
{
    string codeStr = code.ToString();
    var item = context.InvoiceItems
        .Where(i => i.Code == codeStr)
        .FirstOrDefault();
}

使用EF扩展方法,

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems
        .Where(i => i.Code == SqlFunctions.StringConvert(code))
        .FirstOrDefault();
}

在筛选之前将IQueryable结果转换为IEnumerable

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems.AsEnumerable()
        .Where(i => i.Code == code.ToString())
        .FirstOrDefault();
}
xsuvu9jc

xsuvu9jc3#

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

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

这是我收到的错误:
System.NotSupportedException:'LINQ to Entities无法识别方法'Boolean Exists(System.Predicate`1[conector_gp.Models.almacenes_por_sucursal])'方法,此方法无法转换为存储表达式。'
我是这样解决的:

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();

我在我的表后面添加了一个**.ToList()**。这将Entity和linq代码解耦,并防止我的下一个linq表达式被转换为sql。

**注意:**此解决方案不是最佳的,因为它在筛选之前将整个表加载到内存中。

qybjjes1

qybjjes14#

如果有人正在寻找一个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
jdgnovmf

jdgnovmf5#

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

解决方案

IQueryable.toList()是最佳选择

相关问题