Частичная загрузка сущностей Entity Framework и передача их на уровень представления - PullRequest
1 голос
/ 21 декабря 2011

Если я хочу выбрать только несколько столбцов при извлечении данных для сущности EF и привести их к типу сущности, я не смогу этого сделать, потому что он выдает ошибку, как указано в этом посте Субъект не может бытьпостроен в запросе LINQ to Entities .Я не хочу выбирать все столбцы, потому что мне нужно только несколько из них.Я могу использовать анонимные типы, но если я использую шаблон репозитория и хочу инкапсулировать весь код доступа к данным в объект репозитория и передать строго типизированную коллекцию объектов в контроллер (не анонимную коллекцию объектов), как я могу этого достичь?Является ли единственной возможностью определить объект DTO для каждого подмножества свойств объекта EF?Я знаю, что существует риск потери данных с частично загруженными объектами, но если я готов пойти на риск и хочу получить полный контроль над обновлениями данных, разве это невозможно?

например, мне бы хотелось "ProductRepository"подпись метода должна быть такой

public IEnumerable<Product> GetProducts(int categoryID) //selection of subset of data

, и я хочу передать эту коллекцию продуктов из контроллера в представление (в проекте ASP.NET MVC), а в представлении я хочу иметь строго типизированную модель (с интеллигентным) объектом.Это возможно?в противном случае мне, возможно, придется пересмотреть вопрос об использовании EF для моего проекта из-за этого ограничения.Я использую версию EF 4.1.

Ответы [ 2 ]

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

Да, опция в этом случае является специальным объектом для каждого подмножества свойств, которые вы хотите выбрать. Вы можете назвать объект DTO, потому что это просто результат проекции. Это правильный подход, потому что если ваш пользовательский интерфейс не нуждается в других свойствах типа сущности, правильно передать его только специализированной ViewModel.

Еще один более сложный (и худший) вариант - это выбор анонимного типа в вашем запросе Linq-to-entity, вызов ToList и после этой конструкции реального типа сущности. Частичный выбор объекта не допускается, и проецирование на сопоставленные типы объектов также не допускается. Вот почему вы должны использовать такой громоздкий подход. Пример:

// Select anonymous projection
var query = from x in context.Entities
            where ...
            select new { ... };

// Repopulate entity type
var reultSet = query.ToList().Select(x => new Entity { ... });
1 голос
/ 21 декабря 2011

Да, то, что вы хотите, вполне возможно при использовании моделей представления вместо сущностей. Вот пример кода контроллера:

var productEntities = productRepos.GetProducts(6);
var productViewModels = Automapper.Mapper
    .Map<IEnumerable<ProductViewModel>>(productEntities);
return View(productViewModels);

Ваша модель представления будет иметь только те свойства, которые необходимы для представления. Проверьте автомаппер.

...