Почему я не могу проецировать `TimeSpan` через RIA, используя` TimeSpan.FromMinutes`? - PullRequest
3 голосов
/ 12 января 2012

Я объединил RIA Services с Entity Framework, используя POCO. Все это работает чудесно (намного лучше, чем LINQ to SQL). У меня проблема со следующим сегментом кода:

[Query]
public IQueryable<MyEntity> GetMyEntities()
{
    return from myEntity in ObjectContext.MyEntities
           where myEntity.Status != "deleted"
           select new MyEntity
           {
               // Other property assignments...

               SuchAndSuchTime = TimeSpan.FromMinutes(project.SuchAndSuchTime ?? 0.0),

               // Other property assignments...
           };
}

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

Операция загрузки не выполнена для запроса 'GetMyEntities'. LINQ to Entities делает не распознает метод «System.TimeSpan FromMinutes (Double)», и этот метод не может быть переведен в выражение магазина.

Почему я не могу этого сделать, и есть ли обход?

Ответы [ 2 ]

4 голосов
/ 13 января 2012

Проблема в том, что класс CLR TimeSpan не имеет полного канонического сопоставления в LINQ to Entities. Это то, на что ссылается ваше исключение в предложении «... не может быть переведено в выражение хранилища ...» *

Для сценариев LINQ запросы к Entity Framework включают отображение определенных методов CLR на методы в базовом источнике данных с помощью канонических функций. Любые вызовы методов в запросе LINQ to Entities, которые явно не сопоставлены с канонической функцией, приводят к возникновению исключения NotSupportedException во время выполнения. Источник: MSDN

TimeSpan является одним из таких случаев.

Есть как минимум два решения, и это ...

  1. Используйте действительный оператор LINQ to SQL (т. Е. Только для канонических методов), чтобы получить полный набор результатов из базы данных; а затем используйте LINQ to Objects, чтобы отфильтровать полученные результаты. Фильтр LINQ to Objects должен содержать все неканонические методы, чтобы ваша фильтрация доставляла нужное подмножество данных.

  2. Эвакуировать неканонические методы в хранимую процедуру (т. Е. Перевести на прямой SQL) и вызвать хранимую процедуру.

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

Четвертый и более неясный подход дан здесь

1 голос
/ 13 января 2012

Я думаю, что это может быть исправлено в EF 4.2, но я не думаю, что это публично выпущено.

Но суть в том, что Гарри прав.

...