LINQ to SQL Особенности - PullRequest
       24

LINQ to SQL Особенности

5 голосов
/ 02 октября 2008

Я сталкиваюсь с некоторыми особенностями LINQ to SQL.

При относительно простом запросе я хочу выбрать некоторые поля, но поля даты должны быть отформатированы как строки, чего я впервые достиг:

        var list = dataContext.MyLists.Single(x => x.ID == myId);

        var items = from i in list.MyItems
                    select
                        new
                            {
                                i.ID,
                                i.Sector,
                                i.Description,
                                CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "",
                                DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : ""
                            };                               

Позже я попробовал следующий запрос, который точно такой же, за исключением того, что я запрашиваю прямо из моего dataContext, а не элемента в моем первом запросе:

        var items = from i in dataContext.MyLists
                    select
                        new
                            {
                                i.ID,
                                i.Sector,
                                i.Description,
                                CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "",
                                DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : ""
                            };

Первый работает нормально, а второй запрос выдает:

Не удалось перевести выражение '...' в SQL и не удалось обработать его как локальное выражение.

Если я удаляю строки, которые форматируют дату, она работает нормально. Если я уберу проверку .HasValue, она также будет работать нормально, пока не появятся нулевые значения.

Есть идеи?

Anthony

Ответы [ 5 ]

14 голосов
/ 02 октября 2008

Я бы выполнил часть SQL без форматирования, а затем выполнил бы форматирование на стороне клиента:

var items = list.MyItems.Select(item => new { item.ID, item.Sector, item.Description, 
                                              item.CompleteDate, item.DueDate })
                        .AsEnumerable() // Don't do the next bit in the DB
                        .Select(item => new { item.ID, item.Sector, item.Description,
                                              CompleteDate = FormatDate(CompleteDate),
                                              DueDate = FormatDate(DueDate) });


static string FormatDate(DateTime? date)
{
    return date.HasValue ? date.Value.ToShortDateString() : ""
}
8 голосов
/ 02 октября 2008

В первом запросе вы уже получили данные из базы данных к моменту запуска второй строки (var items = ...). Это означает, что 2-я строка запускается на клиенте, где ToShortDateString может работать довольно счастливо.

Во втором запросе, поскольку выборка выполняется непосредственно в коллекции IQueryable (dataContext.MyLists), он пытается преобразовать выборку в SQL для обработки на сервере, где ToShortDateString не понимается - отсюда и «Не удалось перевести». . "исключение.

Чтобы понять это немного лучше, вам действительно нужно понять разницу между IQueryable и IEnumerable, и в этот момент запрос Linq To Sql перестает быть IQueryable и становится IEnumerable. В Интернете есть много информации об этом.

Надеюсь, это поможет,

Пол

6 голосов
/ 02 октября 2008

Так же, как и в сообщении об ошибке, различие связано с тем, что можно делать локально в стихах при подключении к SQL.

Код Linq должен быть преобразован Linq в SQL в команду SQL для удаленного извлечения данных - все, что должно быть сделано локально, не может быть включено.

Как только вы перетянули его в локальный объект (в первом примере), он больше не использует Linq to SQL, просто Linq. В этот момент вы можете выполнять локальные манипуляции с ним.

2 голосов
/ 02 октября 2008

Возможно, в вашем образце произошла ошибка копирования или вставки или просто опечатка. Но если нет, то это может быть проблемой ...

Во втором запросе вы запрашиваете коллекцию списков, тогда как в первом запросе вы запрашивали элементы в списке. Но вы не изменили запрос, чтобы учесть эту разницу.

То, что вам нужно, может быть этим. Обратите внимание на закомментированные строки, которых не было в вашем втором примере.

    var items = from aList in dataContext.MyLists
                from i in aList.MyItems  // Access the items in a list
                where aList.ID == myId  // Use only the single desired list
                select
                    new
                        {
                            i.ID,
                            i.Sector,
                            i.Description,
                            CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "",
                            DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : ""
                        };
1 голос
/ 05 февраля 2010

ToShortDateString() не поддерживается Linq to SQL http://msdn.microsoft.com/en-us/library/bb882657.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...