EF Lambda включает навигационные свойства - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть следующий объект, который называется Filter со следующими свойствами:

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Type> Types{ get; set; }
    public virtual ICollection<Step> Steps { get; set; }
    public virtual ICollection<Flow> Flows { get; set; }
    public virtual ICollection<Room> Rooms { get; set; }

Когда я выбираю список фильтров из базы данных, я понятия не имею, как включить коллекции (типы, шаги, Потоки, комнаты). Мой код выглядит следующим образом:

var filters = (
            from filter in dbContext.DbSet<Filter>()
            let rooms = (
                from r in dbContext.DbSet<Room>()
                select r
                )
            let eventTypes = (
                from t in dbContext.DbSet<Type>()
                select t
                )
            let processFlows = (
                from f in dbContext.DbSet<Flow>()
                select f
                )
            let processFlowSteps = (
                from s in dbContext.DbSet<Step>()
                select s
                )
            select filter
            ).ToList();

Моя коллекция Filter возвращается, но коллекции внутри пустые. Не могли бы вы сказать мне, как я могу добиться этого?

Ps: я не хочу использовать Включить из-за проблем с производительностью, мне не нравится, как Entity Framework генерирует запрос, и я хотел бы сделать это так способ.

Ответы [ 3 ]

1 голос
/ 07 февраля 2020

Ваш метод работает, вы просто делаете это немного неправильно.

Чтобы включить свойство навигации, все, что вам нужно сделать, это выбрать часть (используя linq), например:

var filters = (from filter in dbContext.DbSet<Filter>()
                select new Filter
                {
                    filter.Id,
                    filter.Name,
                    Rooms = (from r in dbContext.DbSet<Room>()
                            where r.FilterId == filter.Id
                            select r).ToList()
                }).ToList();

Имейте в виду, что EF не выполнит запрос, пока вы не вызовете метод возврата (ToList, Any, FirstOrDefault и т. Д. c). Таким образом, вместо выполнения уродливых запросов, которых вы хотите избежать, не используя Include (), он просто запустит два запроса и правильно назначит значения нужному объекту.

1 голос
/ 07 февраля 2020

Вам необходимо использовать Include метод расширения:

var filters=dbContext.DbSet<Filter>()
                     .Include(f=>f.Types)
                     .Include(f=>f.Steps)
                     .Include(f=>f.Flows)
                     .Include(f=>f.Rooms)
                     .ToList()

Обновление

@ MrSilent, Include метод расширения был сделан именно с целью загрузка связанных сущностей, я думаю, что другой вариант, который у вас есть, - это выполнение raw sql, но способ, которым вы делаете, - не способ go, у вас есть четыре обращения к базе данных, и вам нужно используйте вместо этого соединение, чтобы получить связанные сущности, Include генерирует эти объединения для вас, и это всего лишь одна поездка туда и обратно.

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

var query= from f in context.DbSet<Filter>()
           from s in f.Steps
           from r in f.Rooms
           from t in f.Types
           from fl in f.Flows
           select new {f, s, r, t, fl};
0 голосов
/ 08 февраля 2020

Вы можете использовать отложенную загрузку, как:

Сначала вам нужно получить свойства, которые включают в себя склонность быть виртуальными, а затем пустой конструктор с защищенным типом доступа, чтобы хорошо выполнять свою работу.

public virtual ICollection<Type> Types{ get; set; }
public virtual ICollection<Step> Steps { get; set; }
public virtual ICollection<Flow> Flows { get; set; }
public virtual ICollection<Room> Rooms { get; set; }

И

 //FOR EF !
 protected Filter() { }

Я думаю, что это решение решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...