为什么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,诱使编译器将查询的其余部分视为本地执行。
参考
- 我误解LINQ to SQL .AsEnumerable()?
- 了解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();