为什么LINQ to Entities无法识别方法’System.String ToString()?

在MVC3 Web应用程序中获取错误。 LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.

当我尝试从查询中使用EF获取值时:

 public class DataRepository { public mydataEntities1 dbContext = new mydataEntities1(); public List GetPricingSecurityID() { var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing select new SelectListItem { Text = m.PricingSecurityID.ToString(), Value = m.PricingSecurityID.ToString() }); return pricingSecurityID.ToList(); } } 

那不能转换为SQL。 我想,从理论上讲,它可以,但没有实施。

您只需在获得结果后执行投影:

 var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing select m.PricingSecurityID).AsEnumerable() .Select(x => new SelectListItem{ Text = x.ToString(), Value = x.ToString() }); 

如果它已经是一个字符串,为什么你首先打扰调用ToString ? 我怀疑LINQ to Entities中没有包含翻译,因为它没有意义。 将您的select子句更改为:

 select new SelectListItem { Text = m.PricingSecurityID, Value = m.PricingSecurityID } 

如果您确实需要执行LINQ to Entities不支持的操作,请使用AsEnumerable从数据库查询转换为进程内:

 public List GetPricingSecurityID() { return dbContext.Reporting_DailyNAV_Pricing .Select(m => m.PricingSecurityID) .AsEnumerable() // Rest of query is local // Add calls to ToString() if you really need them... .Select(id => new SelectListItem { Text = id, Value = id }) .ToList(); } 

顺便说一句,我同意Jason的反对意见。 你最好还是返回一个在别处呈现的List

另请注意,如果您只是要使用单个select子句或只使用where子句,查询表达式实际上不会增加​​太多 – 调用LINQ扩展方法最终可能会减少混乱,特别是如果您想调用哪些方法查询表达式(例如ToList支持。

因为它试图将其转换为SQL,而它却不能。 取消对ToString的调用,并在返回调用者之前进行投影。 所以,用你的select子句替换

 select m.PricingSecurityID 

然后说

 return pricingSecurityID .AsEnumerable() .Select(x => x.ToString()) .Select(x => new SelectListItem { Text = x, Value = x }) .ToList(); 

此外,我注意到您正在混合UI问题和数据查询问题。 这通常是一种不好的做法。 实际上,您应该返回ID列表,让代码的UI部分担心将其分成正确的forms。

这个怎么样。 在此示例中,db中的VDN字段和Skill字段都是整数。 我正在寻找两个领域的比赛,所以我有两个比较。

包括这个:

 using System.Data.Objects.SqlClient; // needed to convert numbers to strings for linq 

比较数字时这样做:

  // Search Code if (!String.IsNullOrEmpty(searchString)) { depts = depts.Where(d => SqlFunctions.StringConvert((double)d.VDN).Contains(searchString.ToUpper()) || SqlFunctions.StringConvert((double)d.Skill).Contains(searchString.ToUpper())); } // End Search Code 

Workie。

遗憾的是EF不知道如何转换.ToString()你必须使用嵌入式函数SqlFunctions.StringConvert: http : //msdn.microsoft.com/en-us/library/dd466292.aspx此外,int也没有重载所以你必须typecast加倍:-(

 var vendors = from v in Vendors select new { Code = SqlFunctions.StringConvert((double)v.VendorId) }; 

我知道这个问题已得到解答,我同意使用AsEnumerable()AsEnumerable()的方法。 但是,我想强调一个常见的情况,我经常遇到AsEnumerable()无效率地解决此错误。

来自.NET语言 – 关系数据的集成查询

与ToList()和ToArray()不同,AsEnumerable()运算符不会导致执行查询。 它仍然推迟。 AsEnumerable()运算符只是更改查询的静态类型,将IQueryable转换为IEnumerable,欺骗编译器将查询的其余部分视为本地执行。

参考

  1. 我误解了LINQ to SQL .AsEnumerable()?
  2. 在LINQ to SQL中理解.AsEnumerable()

效率低下的方式

 IEnumerable inefficientEnumerable = (from a in db.Invoices where a.Practice_Key == practiceKey.FirstOrDefault() select a ).AsEnumerable(). Select(x => new InvoiceDTO { InvoiceID = x.InvoiceID, PracticeShortName = x.Dim_Practice.Short_Name, InvoiceDate = x.InvoiceDate, InvoiceTotal = x.InvoiceAmount, IsApproved = x.IsApproved, InvoiceStatus = ( x.IsApproved == null ? "Pending" : x.IsApproved == true ? "Approved" : x.IsApproved == false ? "Rejected" : "Unknown" ), InvoicePeriodStartDateText = x.InvoicePeriodStart.ToShortDateString(), InvoicePeriodEndDateText = x.InvoicePeriodEnd.ToShortDateString(), InvoicePeriodStartDate = x.InvoicePeriodStart, InvoicePeriodEndDate = x.InvoicePeriodEnd } ); invoices = inefficientEnumerable.ToList(); 

这里AsEnumerable用于整个表。 尽管不需要,但所有列都会被选中。

更好的方法

  IQueryable invoicesQuery = (from a in db.Invoices where a.Practice_Key == practiceKey.FirstOrDefault() select new InvoiceDTO { InvoiceID = a.InvoiceID, PracticeShortName = a.Dim_Practice.Short_Name, InvoiceDate = a.InvoiceDate, InvoiceTotal = a.InvoiceAmount, IsApproved = a.IsApproved, InvoiceStatus = ( a.IsApproved == null ? "Pending" : a.IsApproved == true ? "Approved" : a.IsApproved == false ? "Rejected" :"Unknown" ), InvoicePeriodStartDate = a.InvoicePeriodStart, InvoicePeriodEndDate = a.InvoicePeriodEnd }); IEnumerable betterEnumerable = invoicesQuery.AsEnumerable(). Select(x => new InvoiceDTO { InvoiceID = x.InvoiceID, PracticeShortName = x.PracticeShortName, InvoiceDate = x.InvoiceDate, InvoiceTotal = x.InvoiceTotal, IsApproved = x.IsApproved, InvoiceStatus = x.InvoiceStatus, InvoicePeriodStartDateText = x.InvoicePeriodStartDate.ToShortDateString(), InvoicePeriodEndDateText = x.InvoicePeriodEndDate.ToShortDateString(), InvoicePeriodStartDate = x.InvoicePeriodStartDate, InvoicePeriodEndDate = x.InvoicePeriodEndDate } ); 
 return dbContext.Reporting_DailyNAV_Pricing.AsEnumerable().Select(x => new SelectListItem { Text = x.PricingSecurityID.ToString(), Value = x.PricingSecurityID.ToString() }).ToList();