LINQ to Entities не распознает System.String - PullRequest
0 голосов
/ 14 июля 2020

Я получаю сообщение об ошибке Linq doesn't recognize ToString. Он работает без добавленного стиля форматирования, например dd/MM/yyyy. Есть ли другой способ сделать это?

ОШИБКА

LINQ to Entities не распознает метод System.String ToString

Код

var MeetingList = (from m in db.Meetings
join md in db.MeetingDates on m.MeetingId equals md.MeetingId
    select new Model.Meeting
    {
        MeetingId = m.MeetingId,
        MeetingDate = md.StartTime.Value.ToString("dd/MM/yyyy")
    }).ToList();

1 Ответ

1 голос
/ 15 июля 2020

+ 1 к комментарию Crowcoder & NetMage: Форматирование должно быть проблемой пользовательского интерфейса, а не предметной области, если это не вызов API. (В этом случае рекомендуется дата в формате ISO «гггг-MM-ddTHH: mm: ssZ»)

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

var meetingList = db.Meetings
    // TODO: Assuming a Where filter on what Meetings to include/exclude...
    .SelectMany(m => m.MeetingDates
        .Where(md => md.StartTime.HasValue) // Avoid null ref if StartTime can be null-able
        .Select(md => new { m.MeetingId, md.StartTime }))
    .ToList()
    .Select( x => new Model.Meeting
    {
        MeetingId = x.MeetingId,
        MeetingDate = x.StartTime.Value.ToString("dd/MM/yyyy")
    }).ToList();

Это предполагает, что у вас есть свойства навигации, настроенные между собраниями и датами собрания. Вы можете написать его с помощью явных объединений, но я настоятельно рекомендую использовать свойства навигации и позволить EF обрабатывать ассоциации.

Первая проекция EF может безопасно преобразоваться в SQL и вернуть желаемые необработанные данные. Это материализуется вызовом ToList. Вторая проекция выполняет форматирование для объектов в памяти.

Двойное проецирование следует использовать осторожно и избегать случаев, когда простое добавление ToList, кажется, решит проблему. Например:

var meetingList = db.Meetings
    // TODO: Assuming a Where filter on what Meetings to include/exclude...
    .SelectMany(m => m.MeetingDates
        .Where(md => md.StartTime.HasValue))
    .ToList() // Materializes the list to memory so the below call will work... BAD.
    .Select( md => new Model.Meeting
    {
        MeetingId = md.MeetingId,
        MeetingDate = md.StartTime.Value.ToString("dd/MM/yyyy")
    }).ToList();

Это будет работать, однако первая проекция вернет на сервер целые объекты MeetingDate, даже если нам нужна только пара столбцов. Если бы более поздний оператор Select имел доступ к дополнительным свойствам навигации, каждая из этих итераций инициировала бы потенциальный обратный вызов для ленивой загрузки в базу данных. При рассмотрении двойной проекции важно, чтобы первая проекция, которая идет к SQL, была как можно более явной с точки зрения того, какие данные возвращаются.

...