3

Я использую LinqPad для проверки моего запроса. Этот запрос работает, когда соединение LInqPad относится к моей базе данных (LInq to SQL), но оно не работает, когда я изменяю соединение для использования моей Entity Framework 5 Model.dll. (Linq to Entity). Это в C#.Linq To Entities 'Поддерживаются только примитивные типы или типы перечислений' Ошибка

У меня есть две таблицы, называемые Plan и PlanDetails. Отношения - это один план для многих плагинов.

var q = from pd in PlanDetails 
     select new { 
      pd.PlanDetailID, 
      ThePlanName = (from p in this.Plans 
        where p.PlanID == pd.PlanID 
        select p.PlanName) 
     }; 
var results = q.ToList(); 
q.Dump(); //This is a linqpad method to output the result. 

Я получаю эту ошибку «NotSupportedException:. Невозможно создать постоянное значение типа„“Domain.Data.Plan Только примитивные типы или типы перечисления поддерживаются в этом контексте.» Любые идеи, почему это работает только с Linq to SQL?

ответ

14

В основном это означает, что вы используете сложный тип данных внутри запроса для сравнения. в вашем случае я подозреваю, что виновником является from p in this.Plans where p.PlanID == pd.PlanID.

И это зависит от DataProvider. Он может работать для поставщика данных Sql, но не для поставщика данных SqlCE и так далее.

, что вы должны сделать, это преобразовать this.Plans коллекции в коллекцию примитивного типа, содержащей только Идентификаторы т.е.

var integers = PlanDetails.Plans.Select(s=>s.Id).ToList(); 

, а затем использовать этот список внутри.

var q = from pd in PlanDetails 
     select new { 
      pd.PlanDetailID, 
      ThePlanName = (from p in integers 
        where p == pd.PlanID 
        select pd.PlanName) 
     }; 
+3

Я беспокоюсь о том, почему он должен делать вложенный запрос, когда он говорит «Один план для многих планов». Это означает, что PlanDetails не могут стоять в одиночестве. Они должны быть связаны с планом ... Итак, если у вас есть PlanDetail он должен иметь навигационное свойство, называемое Plan (если не переименовано) – scartag

+0

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

+0

Спасибо! Я играл с EF, и это тоже имеет смысл. Я попробую это на двух несвязанных сущностях. – duyn9uyen

2

Если отношения уже существуют.

Почему бы просто не сказать.

var q = from pd in PlanDetails 
     select new { 
      pd.PlanDetailID, 
      ThePlanName = pd.Plan.PlanName 
     }; 

Конечно, я предполагаю, что каждый PlanDetail будет принадлежать плану.

Update

Чтобы получить лучшие результаты от LINQPad вы могли бы сказать ему, чтобы использовать свой собственный узел (который содержит ваш DbContext) вместо того, чтобы по умолчанию он использует DataContext.

+0

Вы так правы. Я полностью забыл о навигационной собственности. Можете ли вы сказать, что я только начал использовать EF? Благодаря! – duyn9uyen

3

Это ошибка Linqpad, если вам нравится (или особенность). Я сам нашел подобное поведение. Как и я, вы можете обнаружить, что ваш запрос работает с ObjectContext, но не с DbContext. (И он работает в Visual Studio).

Я думаю, что это связано с внутренней структурой Linqpad. Он добавляет MergeAs (AppendOnly) в коллекции, а контекст - UserQuery, который, вероятно, содержит код, который вызывает эту ошибку.

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

+0

Ваш ответ очень помог мне! У меня была аналогичная проблема даже с более простым предложением «select new», где я просто создаю экземпляр собственного класса со свойствами, являющимися ссылками на сущности (без другого вложенного предложения from from). Используя мой собственный экземпляр контекста, он также работал в LINQPad (как это уже делалось в VS). – juniper

0

Я получил эту ошибку, когда я пытался обнулить проверить навигационные собственности в рамочной сущности выражения

я решил его не использовать не нулевой чек в выражении и просто используя только какую-либо функции().

protected Expression<Func<Entities.Employee, bool>> BriefShouldAppearInSearchResults(
     IQueryable<Entities.Employee> briefs, string username) 
    { 
     var trimmedUsername = NameHelper.GetFormattedName(username); 

     Expression<Func<Entities.Employee, bool>> filterExpression = cse =>     
      cse.Employee.Cars.All(c => 
       c.Employee.Cars!=null && <--Removing this line resolved my issue 
       c.Employee.Cars.Any(cur => cur.CarMake =="Benz"))); 

     return filterExpression; 
    } 

Надеюсь, это поможет кому-то!

Смежные вопросы

 Смежные вопросы