在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();
}
}
答案 0 :(得分:54)
无法转换为SQL。我想,从理论上讲,它可以,但尚未实施。
您只需在获得结果后执行投射:
var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing
select m.PricingSecurityID).AsEnumerable()
.Select(x => new SelectListItem{ Text = x.ToString(), Value = x.ToString() });
答案 1 :(得分:17)
如果它已经是一个字符串,你为什么要首先打电话给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
子句,则查询表达式实际上不会增加太多 - 调用LINQ扩展方法最终可以减少混乱,特别是如果要调用查询表达式中不支持的方法(例如ToList
)。
答案 2 :(得分:4)
因为它试图将其转换为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部分担心将其分成正确的形式。
答案 3 :(得分:4)
这个怎么样?在此示例中,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。
答案 4 :(得分:3)
可悲的是,EF不知道如何转换.ToString()你必须使用嵌入式函数SqlFunctions.StringConvert:http://msdn.microsoft.com/en-us/library/dd466292.aspx同样没有int的重载所以你必须强制转换为double: - (
var vendors =
from v in Vendors
select new
{
Code = SqlFunctions.StringConvert((double)v.VendorId)
};
答案 5 :(得分:1)
我知道这个问题已得到解答,我同意使用AsEnumerable()
是可行的方法。但是,我想强调一个常见的情况,即我经常遇到使用AsEnumerable()
效率低下来解决此错误的问题。
来自.NET Language-Integrated Query for Relational Data
与ToList()和ToArray()不同,AsEnumerable()运算符不会导致执行查询。它仍然是推迟的。 AsEnumerable()运算符只是更改查询的静态类型,将IQueryable转换为IEnumerable,欺骗编译器将查询的其余部分视为本地执行。
<强>参考强>
效率低下
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
用于整个表格。尽管不需要,但所有列都会被选中。
更好的方式
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
}
);
答案 6 :(得分:0)
尝试使用VB.NET进行此操作,重要点是您需要获得答案中所述的AsEnumerable结果。
Dim _EventsDaysResult = From ED In TAdbContext.EventPolicies.AsEnumerable
Where ED.EventID = EID
Select New With {ED.EventID,
.DayInfo =
ED.EventDay.GetValueOrDefault.ToShortDateString & " ( " & ED.EventDayTitle & " ) "}
答案 7 :(得分:-3)
return dbContext.Reporting_DailyNAV_Pricing.AsEnumerable().Select(x => new SelectListItem
{
Text = x.PricingSecurityID.ToString(),
Value = x.PricingSecurityID.ToString()
}).ToList();