Why LINQ to Entities does not recognize the method 'System.String ToString()?
在MVC3 Web应用程序中获取错误。
当我尝试从查询中使用ef获取值时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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。我想,从理论上讲,它是可以实现的,但还没有实现。
您只需在获得结果后执行投影:
1 2 3 | var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing select m.PricingSecurityID).AsEnumerable() .Select(x => new SelectListItem{ Text = x.ToString(), Value = x.ToString() }); |
如果它已经是一个字符串,那么为什么你一开始就打电话给
1 2 3 4 5 | select new SelectListItem { Text = m.PricingSecurityID, Value = m.PricingSecurityID } |
如果您确实需要执行Linq to Entities不支持的操作,请使用
1 2 3 4 5 6 7 8 9 | 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(); } |
我也同意杰森的反对意见,顺便说一句,你最好还是退回其他地方提供的
还要注意,如果只使用一个
这个怎么样?在本例中,db中的vdn字段和skill字段都是整数。我在寻找两个领域的匹配,所以我有两个比较。
包括:
1 | using System.Data.Objects.SqlClient; // needed to convert numbers to strings for linq |
比较数字时,请执行以下操作:
1 2 3 4 5 6 7 | // 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 |
小精灵。
因为它试图将其转换为SQL,但无法转换。在返回到调用方之前,请取消对
1 | select m.PricingSecurityID |
然后说
1 2 3 4 5 | return pricingSecurityID .AsEnumerable() .Select(x => x.ToString()) .Select(x => new SelectListItem { Text = x, Value = x }) .ToList(); |
另外,我注意到您混合了UI关注点和数据查询关注点。这通常是一种不好的做法。实际上,您应该返回ID列表,让代码的UI部分担心是否将其混入正确的表单。
遗憾的是,ef不知道如何转换.toString(),您必须使用嵌入函数sqlFunctions.stringConvert:http://msdn.microsoft.com/en-us/library/dd466292.aspx。int也没有重载,因此您必须将类型转换为double:。-(
1 2 3 4 5 6 | var vendors = from v in Vendors select new { Code = SqlFunctions.StringConvert((double)v.VendorId) }; |
我理解这个问题得到了回答,我同意使用
来自.NET语言的关系数据集成查询
The AsEnumerable() operator, unlike ToList() and ToArray(), does not cause execution of the query. It is still deferred. The AsEnumerable() operator merely changes the static typing of the query, turning a IQueryable into an IEnumerable, tricking the compiler into treating the rest of the query as locally executed.
工具书类
低效方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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(); |
这里,
更好的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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 } ); |
1 2 3 4 5 | return dbContext.Reporting_DailyNAV_Pricing.AsEnumerable().Select(x => new SelectListItem { Text = x.PricingSecurityID.ToString(), Value = x.PricingSecurityID.ToString() }).ToList(); |