30

在 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();
        }
    }
4

8 回答 8

55

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

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

var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing
                                     select m.PricingSecurityID).AsEnumerable()
    .Select(x => new SelectListItem{ Text = x.ToString(), Value = x.ToString() });
于 2012-04-11T16:47:26.693 回答
18

如果它已经是一个字符串,你为什么还要费心打电话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 扩展方法最终会减少混乱,特别是如果您想调用“ t在查询表达式中支持(例如ToList)。

于 2012-04-11T16:45:51.813 回答
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 部分担心将其调整为正确的形式。

于 2012-04-11T16:42:49.270 回答
4

这个怎么样。在此示例中,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

工作人员。

于 2012-12-13T14:28:23.437 回答
3

遗憾的是,EF 不知道如何转换 .ToString() 您必须使用嵌入式函数 SqlFunctions.StringConvert:http: //msdn.microsoft.com/en-us/library/dd466292.aspx另外 int 没有重载,因此您必须类型转换为双倍:-(

var vendors = 
   from v in Vendors  
   select new
   {             
       Code = SqlFunctions.StringConvert((double)v.VendorId)
   }; 
于 2013-08-24T15:54:19.297 回答
2

我知道这个问题得到了回答,我同意使用AsEnumerable()是要走的路。但是,我想强调一个常见的场景,我通常会遇到AsEnumerable()使用效率低下来解决此错误的地方。

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

AsEnumerable() 运算符与 ToList() 和 ToArray() 不同,不会导致执行查询。它仍然被推迟。AsEnumerable() 运算符仅更改查询的静态类型,将 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用于整个表。所有列都被选中,即使它们不是必需的。

更好的方法

 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
                                 }
                                 );
于 2017-04-06T17:51:48.077 回答
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 & " ) "}
于 2019-08-20T18:12:50.233 回答
-3
return dbContext.Reporting_DailyNAV_Pricing.AsEnumerable().Select(x => new SelectListItem
{
    Text = x.PricingSecurityID.ToString(),
    Value = x.PricingSecurityID.ToString()
}).ToList();
于 2015-05-07T12:36:21.910 回答