Comment la syntaxe D'expression de LINQ fonctionne-t-elle avec Include() pour le chargement rapide?
j'ai une requête ci-dessous, mais je veux effectuer un Include() pour charger des propriétés. Actions possède une propriété de navigation, User (Action.De l'utilisateur)
1) Ma requête de base:
from a in Actions
join u in Users on a.UserId equals u.UserId
select a
2) Première tentative:
from a in Actions.Include("User")
join u in Users on a.UserId equals u.UserId
select a
Mais L'Action.L'utilisateur est peuplée.
3) Essayez de charger 'User' dans la propriété de navigation en action en dehors de query:
(from a in Actions
join u in Users on a.UserId equals u.UserId
select a).Include("User")
in LINQPad trying Includ's I get an erreur:
'Système.Linq.IQueryable" ne contient pas de définition pour "Include" et aucune méthode d'extension "Include" accepter un premier argument de type " Système.Linq.IQueryable ' peut être trouvé (appuyez sur F4 pour ajouter une directive d'utilisation ou une référence d'assemblage)
je pense que C'est parce que LINQ ne supporte pas Include().
alors j'ai essayé en VS; la requête 2 s'exécute, mais renvoie la propriété utilisateur non peuplée. Requête 3 la méthode d'extension ne semble pas exister, bien qu'elle existe sur l'Action elle-même sans la requête.
5 réponses
j'ai compris, merci pour les suggestions de toute façon. La solution est de le faire (2ème tentative dans ma question):
var qry = (from a in Actions
join u in Users on a.UserId equals u.UserId
select a).Include("User")
la raison pour laquelle intellisense ne s'est pas montré Include après la requête était parce que j'avais besoin de l'utilisation suivante:
using System.Data.Entity;
tout fonctionnait bien en faisant cela.
si ce que vous voulez est une requête qui retournera tout Action
entités dont les associés User
entity existe réellement via le Action.UserId
propriété de clé étrangère, cela va faire ça:
var results = context.Actions
.Include("User")
.Where(action =>
context.Users.Any(user =>
user.UserId == action.UserId));
cependant vous n'avez pas besoin d'utiliser des propriétés de clé étrangère pour faire du filtrage, puisque vous avez également propriétés de navigation. Ainsi, votre requête peut être simplifiée en filtrant sur le Action.User
propriété de navigation à la place, comme dans cette exemple:
var results = context.Actions
.Include("User")
.Where(action => action.User != null);
si votre modèle indique que le Action.User
propriété ne peut jamais être nulle (c'est à dire l' Action.UserId
clé étrangère n'est pas les valeurs null dans la base de données) et ce que vous voulez est en fait tout Action
entités qui leur sont associés Users
, alors la requête devient encore plus simple
var results = context.Actions.Include("User");
Mieux, refactoriser le code est adapté (EF6)
using System.Data.Entity;
[...]
var x = (from cart in context.ShoppingCarts
where table.id == 123
select cart).Include(t => t.CartItems);
ou
var x = from cart in context.ShoppingCarts.Include(nameof(ShoppingCart.CartItems))
where table.id == 123
select cart;
mise à Jour 3/31/2017
vous pouvez également utiliser la syntaxe include dans lambda pour l'une ou l'autre des méthodes:
var x = from cart in context.ShoppingCarts.Include(p => p.ShoppingCart.CartItems))
where table.id == 123
select cart;
en faisant la requête de base mentionnée dans votre question postée, vous ne pourrez pas voir les propriétés de L'utilisateur à moins de retourner un type anonyme comme suit:
from a in Actions
join u in Users on a.UserId equals u.UserId
select new
{
actionUserId = a.UserId
.
.
.
userProperty1 = u.UserId
};
Cependant pour utiliser la méthode Include sur L'ObjectContext vous pouvez utiliser ce qui suit:
assurez-vous d'avoir désactivé le téléchargement en utilisant la ligne suivante:
entities.ContextOptions.LazyLoadingEnabled = false;
puis procéder par
var bar = entities.Actions.Include("User");
var foo = (from a in bar
select a);
j'utilise pour cela L'option LoadWith
var dataOptions = new System.Data.Linq.DataLoadOptions();
dataOptions.LoadWith<Action>(ac => as.User);
ctx.LoadOptions = dataOptions;
c'est tout. ctx est votre DataContext. Cela fonctionne pour moi :-)