Почему LINQ to Entities не распознает метод System.String ToString ()?

Получение ошибки внутри веб-приложения MVC3. LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.

когда я пытаюсь получить значения, используя EF из запроса:

<code>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();
        }
    }
</code>

Ответы на вопрос(7)

return dbContext.Reporting_DailyNAV_Pricing.AsEnumerable().Select(x => new SelectListItem
{
    Text = x.PricingSecurityID.ToString(),
    Value = x.PricingSecurityID.ToString()
}).ToList();
Решение Вопроса

теоретически, это могло бы, но не реализовано.

Вам просто нужно выполнить прогноз после получения результатов:

var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing
                                     select m.PricingSecurityID).AsEnumerable()
    .Select(x => new SelectListItem{ Text = x.ToString(), Value = x.ToString() });
 11 апр. 2012 г., 22:38
@JonSkeet Спасибо за совет; обновляется соответственно.
 10 нояб. 2012 г., 09:58
@MandeepJanjua: ОП звонитToList в конце концов, в любом случае, чтобы вернуть список - нет смысла звонитьToList().Select(...).ToList().
 10 нояб. 2012 г., 02:10
@JonSkeet Это зависит. Если вам нужно работать с результатами сразу или вы хотите подождать, пока компилятор не выполнит запрос.
 11 апр. 2012 г., 22:29
Нет необходимости звонитьToList() здесь - зачем строить другой список, когдаAsEnumerable будет выполнять работу с меньшими накладными расходами?

и он не может. Прекратить звонокToStringи сделайте прогноз, прежде чем вернуться к звонящему. Итак, замените вашselect оговорка с

select m.PricingSecurityID

а потом сказать

return pricingSecurityID
           .AsEnumerable()
           .Select(x => x.ToString())
           .Select(x => new SelectListItem { Text = x, Value = x })
           .ToList();

Кроме того, я отмечаю, что вы смешиваете проблемы пользовательского интерфейса и проблемы запросов данных. Это вообще плохая практика. На самом деле, вы должны просто возвращать список идентификаторов и позволить части пользовательского интерфейса вашего кода беспокоиться о том, чтобы привести его в правильную форму.

ся целыми числами. Я ищу совпадения в обоих полях, поэтому у меня есть 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.

 13 дек. 2012 г., 15:54
Не могли бы вы отредактировать свой ответ, чтобы более тесно связать с вопросом? Соединение не сразу очищается.

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)
   }; 

AsEnumerable() это путь Однако я хотел бы выделить общий сценарий, с которым я обычно сталкиваюсь, когдаAsEnumerable() используется неэффективно для устранения этой ошибки.

ОтИнтегрированный в язык .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.

References

Am I misunderstanding LINQ to SQL .AsEnumerable()? Understanding .AsEnumerable() in LINQ to SQL

Inefficient way

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 используется для всей таблицы. Все столбцы выбираются, даже если они не нужны.

Better Way

 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
                                 }
                                 );

ToString на первом месте? Я подозреваю, что перевод не был включен в LINQ to Entities, потому что это бессмысленно. Измените выбранное предложение на:

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

если тыreally нужно сделать что-то, что не поддерживается 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> который представлен в другом месте.

Также обратите внимание, что если выjust собираюсь использовать одинselect пункт или простоwhere В действительности, выражения запросов действительно не добавляют много - вызов методов расширения LINQ может привести к меньшему беспорядку, особенно если вы хотите вызывать методы, которыеaren't поддерживается в выражениях запросов (таких какToList).

 11 апр. 2012 г., 22:47
Вы правы насчет последней части, спасибо.
 11 апр. 2012 г., 18:53
Ты читаешьSystem.String ToString() как смыслPricingSecurityID ужеstring? Я действительно думаю, что это относится к типу возвращаемого значенияToString и этоPricingSecurityID возможно (вероятно?) уже неstring.
 08 мая 2013 г., 09:58
Я только что проверил: в сообщении об ошибке также упоминаетсяSystem.String ToString() если тип данных источникаnot строка.
 11 апр. 2012 г., 18:56
@ Джейсон: Да, это мое предположение. Возможно, я ошибаюсь, и в этом случае мой второй кусок кода (с вызовами ToString) будет правильным решением. Я не думаю, что ваш подход простого разделения проекции помог бы - он все еще будет выполняться в базе данных, если вы не материализуете запрос или не используете AsEnumerable.

Ваш ответ на вопрос