У меня есть простой код, который извлекает записанные исключения Elmah из БД:NotSupportedException выброшен после вызова .AsEnumerable()
HealthMonitoringEntities context = new HealthMonitoringEntities();
IQueryable<ELMAH_Error> exceptions = context.ELMAH_Error;
if (filter.ToDate != null)
exceptions = exceptions.Where(e => e.TimeUtc <= filter.ToDate.Value.AddHours(-4));
return exceptions.OrderByDescending(e => e.TimeUtc)
.Take(filter.Size)
.AsEnumerable()
.Select(e => new ElmahException()
{
ErrorId = e.ErrorId,
Application = e.Application,
Host = e.Host,
Type = e.Type,
Source = e.Source,
Error = e.Message,
User = e.User,
Code = e.StatusCode,
TimeStamp = e.TimeUtc.AddHours(-4).ToString()
}).ToList();
}
я получаю исключение на этой линии:
TimeStamp = e.TimeUtc.AddHours(-4).ToString()
Исключением является:
LINQ to Entities does not recognize the method 'System.DateTime AddHours(Double)' method, and this method cannot be translated into a store expression.
Когда я звоню .AsEnumerable()
перед началом проекции с Select()
, моя последовательность перечисляется, и я проецируюсь из последовательности, которая реализует IEnumerable<ELMAH_Error>
. Учитывая это, почему я не работаю с API Linq-To-Objects в моей проекции, который понимает AddHours()
, а не работает с API Linq-To-Entities?
UPDATE
Существует пост на эту тему Джон тарелочкам здесь:
Он имеет этот запрос:
var query = db.Context
.Customers
.Where(c => some filter for SQL)
.OrderBy(c => some ordering for SQL)
.Select(c => some projection for SQL)
.AsEnumerable() // Switch to "in-process" for rest of query
.Where(c => some extra LINQ to Objects filtering)
.Select(c => some extra LINQ to Objects projection);
Обратите внимание, что после его вызова AsEnumerable()
, он указал, что переключается на Linq-To-Objects. Я выполняю что-то подобное в своей функции, но получаю исключение Linq-To-Entities, где я думал, что буду выполнять API Linq-To-Objects.
Дальнейшее обновление
Из блога Джима Вули в: http://linqinaction.net/blogs/jwooley/archive/2009/01/21/linq-supported-data-types-and-functions.aspx
«В качестве примера следующие методы показаны как имеющие переводы для значений DateTime: Добавить, Равно, CompareTo, дата, день, месяц, В отличие от методов, таких как ToShortDateString, IsLeapYear, ToUniversalTime не поддерживаются.
Если вам нужно использовать один из неподдерживаемых методов, вам нужно принудительно выполнить результаты для клиента и просчитать их, используя LINQ to Objects в этой точке.Это можно сделать с помощью метода расширения .AsEnumerable в любой точке понимания запроса. "
Разве это не то, что я делаю?
Расширения AsEnumerable() из Queryable не будет перечислять. Он возвращает только IEnumarable. –
Jehof