2012-01-27 2 views
3

У меня есть сценарий с несколькими методами linq include с ассоциациями табличных объектов. Пусть сценарий:Как использовать INCLUDE в Linq только для выбранных столбцов?

User has Groups 
User has Permissions 
User has Vehicles 

var _users= 
(from u in dbconetxt.Users 
join g in dbconetxt.Gropus on u.userId equals g.userId 
join p in dbconetxt.Permissions on u.userId equals p.userId 
join v in dbconetxt.Vehicles on u.userId equals v.userId 
Where u.Status=true 
select u).Include(u.Groups) 
     .Include(u.Permissions) 
     .Include(u.Vehicles) 
     .ToList() 

После присоединения всех этих таблиц в одном запросе, я выбираю объект пользователя. Конечно, я бы получил List, но я хочу, чтобы каждый пользовательский объект должен включать свои соответствующие группы, разрешения, транспортные средства, но из транспортных средств и разрешений я хочу загрузить только несколько столбцов/свойств, а не все. Итак, как я могу указать, какие столбцы загружать в этом сценарии?

Я использую Entity Framework 4.1 + C# + SQL Server.

+0

Я не совсем понимаю ваш вопрос, но NHibernate допускает ленивые свойства загрузки, а EF - нет. NHibernate чаще поддерживает то, о чем вы просите, но EF может поддерживать то, что вы хотите, если вам не нужны ленивые загруженные свойства. –

+0

Начиная с v4 Entity Framework поддерживает ленивую загрузку. См.: http://thedatafarm.com/blog/data-access/a-look-at-lazy-loading-in-ef4/ – Pawel

+0

@Pawel - Я не говорю о ленивой загрузке всего класса, EF всегда поддержал это. Я говорю о ленивой загрузке одного или нескольких свойств в классе, в то же время стремясь загрузить другие свойства, которые, похоже, просят Red Swan. –

ответ

6

Include - это метод расширения, прикрепленный к IQueryable. Это означает, что вы должны использовать его для пользователей DbSet.

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

var users = from u in dbContext.Users.Include(u => u.Groups) 
      where u.Status == true 
      select new 
      { 
       u.Name, 
       u.Id, 
       u.WhatSoEver 
      }; 

или

var users = from u in dbContext.Users.Include(u => u.Groups) 
      where u.Status == true 
      select new UserView 
      { 
       Name = u.Name, 
       Id = u.Id, 
       Property1 = u.WhatSoEver 
      }; 
+0

Я согласен использовать класс annonymos. Но, к сожалению, объектная структура разработана и ограничена добавлением пользовательских классов/анонимных классов. это другой путь для того же. –

+0

, пожалуйста, объясните, что вы имеете в виду. – Kralizek

+0

Какова цель включения в эти запросы? Btw. include не работает, как только вы начинаете использовать проекцию. –

3

Если вы хотите подмножества столбцов вы должны использовать проекцию анонимный или пользовательский тип или создать конкретный вид базы данных для запроса и сопоставить его новый объект только для чтения. Include всегда будет загружать все столбцы включенного объекта (так что другой подход делит объект на разбиение таблицы, но это выглядит как излишний). Также Include имеет очень ограниченное использование - форма корневого запроса не должна изменяться, поэтому, когда вы используете какую-либо пользовательскую проекцию или присоединяетесь, Include не будет работать.

EF ORM - как только вы начертите объект, вы всегда будете работать со всей сущностью не только со своей частью. Если вам нужно работать с частью объекта, вы должны использовать проецирование для не-сущностного класса (не отображаемого).

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