为什么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<SelectListItem> 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() }); 

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

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

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

 public List<SelectListItem> 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(); } 

顺便说一句,我同意杰森的反对意见。 你最好还是返回一个List<string> ,它在其他地方渲染。

还要注意的是,如果你只是使用一个select子句或只是一个where子句,查询expression式确实不会增加太多 – 调用LINQ扩展方法最终可能会减less混乱,特别是如果你想调用方法在查询expression式(如ToList )中不受支持。

因为它试图将其转换为SQL,而不能。 放弃对ToString的调用,并在返回给调用者之前做一个投影。 所以,用你的select子句replace

 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字段都是整数。 我正在寻找来自两个领域的比赛,所以我有2比较。

包括:

 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()您必须使用embedded式函数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()被低效地用来解决这个错误的一个常见的场景。

从关系数据的.NET语言集成查询

与ToList()和ToArray()不同,AsEnumerable()运算符不会导致执行查询。 它仍然推迟。 AsEnumerable()运算符只是改变查询的静态types,把IQueryable变成IEnumerable,诱使编译器将查询的其余部分视为本地执行。

参考

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

没有效率的方法

 IEnumerable<InvoiceDTO> 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用于整个表格。 尽pipe不需要,所有的列都被选中了。

更好的方法

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