LINQ to Entities 无法识别该方法
Posted
技术标签:
【中文标题】LINQ to Entities 无法识别该方法【英文标题】:LINQ to Entities does not recognize the method 【发布时间】:2011-11-07 17:50:00 【问题描述】:尝试执行 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;
如果您需要更多信息,请告诉我。
非常感谢,
安妮莉
【问题讨论】:
检查this answer 也会检查一下,谢谢! 很高兴看到您如何使用Find()
,而您如何在其中使用IsSatisfied()
。
相关帖子 - LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression & Entity Framework Specification Pattern Implementation
【参考方案1】:
正如您所知道的,Entity Framework 实际上不能将您的 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()));
【讨论】:
如有疑问请搜索:***.com/questions/2352764/… 返回一个构造的Expression<Func<T,type>>
是一个非常好的方法。
如何在 LINQ 表达式中使用它?我想做这样的事情作为可重复使用的 Where 子句,但正在努力实现它。
编辑:没关系,应该是:context.Where(IsSatisfied())
关键部分:“实体框架实际上不能将您的 C# 代码作为其查询的一部分运行。”【参考方案2】:
我在这段代码中遇到了同样的错误:
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(),这将实体和 linq 代码解耦,并避免我的下一个 linq 表达式被翻译
注意:这个解决方案不是最优的,因为避免实体过滤,并且只是将所有表加载到内存中
【讨论】:
大多数时候这是最简单的解决方案,但为了不加载所有对象,我通常在 .ToList() 之前使用我需要的东西进行匿名选择... xx.Select(x=> new x.Id, x.DateTimeUpdate).ToList().Select(x=> new x.Id, DateTimeUpdate = x.DateTimeUpdate.ToString("dd/MM/yyyy") )【参考方案3】:我今天遇到了同样的问题,这是我点击的第一个链接。但是我不是在寻找验证我的查询。因此,如果其他人有同样的问题并正在寻找此解决方案,则将其添加到此处。我的问题在另一个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();
【讨论】:
【参考方案4】:如果有人正在寻找 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
【讨论】:
【参考方案5】:我在这段代码中遇到了同样的错误:
解决方案
可查询
.toList() 是最佳选择
【讨论】:
以上是关于LINQ to Entities 无法识别该方法的主要内容,如果未能解决你的问题,请参考以下文章