Подтвердить что ты не робот

Как синтаксис выражения LINQ работает с Include() для активной загрузки

У меня есть запрос ниже, но я хочу выполнить свойство Include() для активных свойств загрузки. Действия имеют свойство навигации, User (Action.User)

1) Мой основной запрос:

from a in Actions
join u in Users on a.UserId equals u.UserId
select a

2) Первая попытка:

from a in Actions.Include("User")
join u in Users on a.UserId equals u.UserId
select a

Но Action.User - это не.

3) Попробуйте загрузить "Пользователь" в свойство навигации в действии вне запроса:

(from a in Actions
join u in Users on a.UserId equals u.UserId    
select a).Include("User")

В попытке LINQPad включить я получаю сообщение об ошибке:

'System.Linq.IQueryable' не содержит определения для "Include", и не может быть найден метод расширения "Include", принимающий первый аргумент типа "System.Linq.IQueryable" (нажмите F4, чтобы добавить директиву using или ссылку на сборку)

Я думаю, это связано с тем, что LINQ не поддерживает Include().

Итак, я пробовал в VS; запрос 2 работает, но возвращает непопущенное свойство пользователя. В запросе 3 метод расширения, похоже, не существует, хотя он существует и сам по себе без запроса.

4b9b3361

Ответ 1

Я понял это, спасибо за предложения в любом случае. Решение должно сделать это (вторая попытка в моем вопросе):

var qry = (from a in Actions
join u in Users on a.UserId equals u.UserId    
select a).Include("User")

Причина, по которой intellisense не показывала Include после запроса, потому что мне понадобилось следующее:

using System.Data.Entity;

Все отлично работало.

Ответ 2

Если вам нужен запрос, который будет возвращать все Action сущности, чей связанный объект User фактически существует через Action.UserId свойство внешнего ключа, это сделают это:

var results = context.Actions
    .Include("User")
    .Where(action =>
        context.Users.Any(user =>
            user.UserId == action.UserId));

Однако вам не нужно использовать свойства внешнего ключа для фильтрации, так как у вас также есть свойства навигации. Таким образом, ваш запрос может быть упрощен путем фильтрации в качестве свойства навигации Action.User, как в этом примере:

var results = context.Actions
    .Include("User")
    .Where(action => action.User != null);

Если ваша модель заявляет, что свойство Action.User никогда не может быть нулевым (т.е. внешний ключ Action.UserId не имеет значения NULL в базе данных), и на самом деле вы хотите, чтобы все Action сущности с их ассоциированными Users то запрос становится еще проще

var results = context.Actions.Include("User");

Ответ 3

Лучший, удобный для рефакторинга код (EF6)

using System.Data.Entity;
[...]
var x = (from cart in context.ShoppingCarts
         where table.id == 123
         select cart).Include(t => t.CartItems);

или же

var x = from cart in context.ShoppingCarts.Include(nameof(ShoppingCart.CartItems))
        where table.id == 123
        select cart;

Обновление 31.03.2017

Вы также можете использовать include в лямбда-синтаксисе для любого метода:

var x = from cart in context.ShoppingCarts.Include(p => p.ShoppingCart.CartItems))
        where table.id == 123
        select cart;

Ответ 4

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

from a in Actions
join u in Users on a.UserId equals u.UserId
select new
{
   actionUserId = a.UserId
   .
   .
   .
   userProperty1 = u.UserId
};

Однако для использования метода Include в ObjectContext вы можете использовать следующее:

Убедитесь, что LazyLoading выключен, используя следующую строку:

entities.ContextOptions.LazyLoadingEnabled = false;

Затем перейдите к

var bar = entities.Actions.Include("User");
var foo = (from a in bar
           select a);

Ответ 5

Я использую для этого параметр LoadWith

var dataOptions = new System.Data.Linq.DataLoadOptions();
dataOptions.LoadWith<Action>(ac => as.User);
ctx.LoadOptions = dataOptions;

Вот оно. ctx - ваш DataContext. Это работает для меня: -)