LINQ left-join Entity Frame work - Невозможно создать постоянное значение типа - PullRequest
1 голос
/ 15 декабря 2011

Есть симулированные вопросы с ответами, которые не работают в моей ситуации.

Я получаю

Невозможно создать постоянное значение типа '.Model.featureoptions».В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid).

Использование Entity First, EntityFramework 4.1, MVC3, C # 4.

vehicles таблица данных транспортных средств, owners таблица владельцев транспортных средств.vehicles и owners являются внутренними соединениями, и это работает.

features таблица представляет собой список дополнительных функций, например, люк на крыше, окраска и т. Д. featureOptions представляет собой список доступных параметров для функции,например, краска может быть «перламутровой», «матовый», а люк на крыше - «всплывающее стекло», «заголовок + слайд».

vehicleFeatures - это список выбранных опций для автомобиля, в частностиАвтомобиль может иметь ноль или одну запись.

В этом запросе feature1 должно быть null или выбранное значение для функции (т. е. выбранная опция люка в крыше) и feature2 должно быть nullили выбранное значение для другой функции (например, выбранный параметр рисования)

var query = (from v in _entities.vehicles

                 join o
                    in _entities.owners
                    on v.OwnerID equals o.OwnerID

                 // Some more inner joins

                 select new
                 {
                     // <code snipped >
                     // o. fields and v. fields
                     // </ code snipped>

                     feature1 = (from feature1
                                     in _entities.vehiclefeatures
                                     .Where ( f_1 => f_1.VehicleID == v.VehicleID)
                                 join feature1_fo
                                     in _entities.featureoptions
                                 on feature1.FeatureOptionID equals feature1_fo.FeatureOptionID
                                 join feature1_f
                                     in _entities.features
                                     .Where (bt_f => bt_f.CodeEnum==1)
                                 on feature1_fo.FeatureID equals feature1_f.FeatureID
                                 select new featureoptionsDTO () { Option = feature1_fo.Option }
                               ),
                      feature2 = (from feature2
                                         in _entities.vehiclefeatures
                                         .Where(f_2 => f_2.VehicleID == v.VehicleID)
                                      join feature2_fo
                                         in _entities.featureoptions
                                      on feature2.FeatureOptionID equals feature2_fo.FeatureOptionID
                                      join feature2_f
                                          in _entities.features
                                         .Where(feature2_f => feature2_f.CodeEnum == 2)
                                      on feature2_fo.FeatureID equals feature2_f.FeatureID
                                      select new featureoptionsDTO() { Option = feature2_fo.Option }
                                 )
                 }
);

foreach (var vehicle in query)  // Exception here
{
}

feature1 = (from ..

и

feature2 = (from .. 

вызывают

Невозможно создать постоянное значение типа '.Model.featureoptions'.В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid).

Я понимаю, что LINQ пытается создать объект, как я могу получить его для создания анонимного(или собственный класс) вместо этого?

Ответы [ 2 ]

1 голос
/ 15 декабря 2011

К сожалению, Entity Framework не может обрабатывать предложения select, которые создают произвольные типы в запросах LINQ to Entities. Я сам споткнулся об этом несколько раз, и это довольно раздражает. Это, однако, совершенно необходимо, поскольку запросы LINQ to Entities переводятся в SQL для запуска в базе данных, а база данных не может обрабатывать создание объектов .NET. Было бы неплохо иметь возможность сделать это в конце запроса, но это никогда не может быть разрешено в середине.

Что я обычно делаю, так это пишу запрос, который выдает именно те данные, которые требуются для конструкторов в LINQ to Entities, чтобы он выполнялся в базе данных. Затем вызовите ToEnumerable () для IQueryable, который вы получаете из этого, который превращает его в IEnumerable, и после этого вы находитесь в LINQ to Objects, чтобы вы могли делать все что угодно в своей Select ().

0 голосов
/ 19 декабря 2011

Я решил это, используя представление в базе данных для выполнения внешних объединений, и linq запрашивает объект, связанный с представлением.

Выполнение левого внешнего в базе данных означает, что внешние объединения выполняются раньшеВозможно, сделав это немного быстрее.Линк аккуратнее и просто должен делать то, что ему нужно, что в данном случае фильтрует.

...