Соединение Linq с инструкцией Include

#c# #linq #entity-framework

#c# #linq #entity-framework

Вопрос:

 IQueryable<Employee> emps = CreateObjectSet<Employee>()
                                  .Include(u => u.Departments)
                                  .AsQueryable();
IQueryable<Products> prods = CreateObjectSet<Products>().AsQueryable();
  

CreateObjectSet — это метод Createobjectset для ObjectContext от ObjectContext

         return (from emp in emps
                join prod in prods
                on emp.ProductID equals prod.ProductID
                where emp.EmployeeID == 10
                select employee).ToList();
  

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

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

Спасибо

Комментарии:

1. Что CreateObjectSet делает? Я с подозрением отношусь к необходимости AsQueryable … это не должно требоваться.

2. @JonSkeet Я думаю, причина в том, что он возвращает DbSet, а OP изначально использовал var

3. @johnny5: Я не понимаю, как это что-то меняет в коде, который нам показали.

4. @JonSkeet если CreateObjectSet<Employee>() возвращает a DbSet , а emps был переменной var, последующая работа с этой переменной всегда будет DbSet, поэтому, если OP не показывает полный код, и он попытается присвоить ему значение из другого IQueryable, это приведет к сбою. Итак, если вы добавляете AsQueryable с самого начала, вы знаете, что ваш var является IQueryable

5. @johnny5: Это звучит как ужасно много догадок, когда мы не знаем, что они когда-либо использовали var , и мы не знаем, что они когда-либо пытались присвоить ему другое значение.

Ответ №1:

Это известная проблема с include. Вы могли бы взглянуть на следующую статью, включенную в EF

 var results =
         ((from post in ctx.Posts
         from blog in post.Blogs
         where blog.Owner.EmailAddress == "alexj@microsoft.com"
         select post) as ObjectQuery<Post>).Include("Comments");
  

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

Механизм исправления отношения сущности EF затем «исправит» включение для вас.

Комментарии:

1. Указанная вами ссылка имеет очень чистые решения. Большое спасибо

2. @Wouter включает в себя сохранение в groupBy и выбирает в anonymous, но объединения не делают почему?

Ответ №2:

Это можно решить с помощью следующего кода:

 var query = from emp in emps
            join prod in prods
            on emp.ProductID equals prod.ProductID
            where emp.EmployeeID == 10
            select employee;
var result = query.Include(u => u.Departments)