J'ai une requête ci-dessous, mais je souhaite effectuer un Include () pour charger les propriétés. Actions possède une propriété de navigation, Utilisateur (Action.User)
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 Action.User est pas rempli.
3) Essayez de charger ardemment "Utilisateur" dans la propriété de navigation en action en dehors de la requête:
(from a in Actions
join u in Users on a.UserId equals u.UserId
select a).Include("User")
Dans LINQPad essayant d'inclure, j'obtiens une erreur:
'System.Linq.IQueryable' ne contient pas de définition pour 'Include' et aucune méthode d'extension 'Include' acceptant un premier argument de type 'System.Linq.IQueryable' n'a pu être trouvée (appuyez sur F4 pour ajouter une directive ou une référence d'assembly à l'aide )
Je pense que c'est parce que LINQ ne prend pas en charge Include ().
J'ai donc essayé en VS; la requête 2 s'exécute, mais renvoie une propriété utilisateur non peuplée. Requête 3, la méthode d'extension ne semble pas exister, bien qu'elle existe sur Action elle-même sans la requête.
Je l'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 n'a pas affiché Inclure après la requête était parce que j'avais besoin des éléments suivants en utilisant:
using System.Data.Entity;
Tout a bien fonctionné en faisant cela.
Si vous voulez une requête qui retournera toutes les entités Action
dont l'entité User
associée existe réellement via le Action.UserId
propriété de la clé étrangère , cela le fera:
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 effectuer le filtrage , car 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 cet exemple:
var results = context.Actions
.Include("User")
.Where(action => action.User != null);
Si votre modèle indique que le Action.User
la propriété ne peut jamais être nulle (c.-à-d. la Action.UserId
la clé étrangère n'est pas annulable dans la base de données) et ce que vous voulez est en fait toutes les entités Action
avec leurs Users
associées, la requête devient encore plus simple
var results = context.Actions.Include("User");
Meilleur code convivial de refactorisation (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 du 31/03/2017
Vous pouvez également utiliser l'inclusion dans la syntaxe lambda pour l'une ou l'autre méthode:
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 publiée, vous ne pourrez pas voir les propriétés de l'utilisateur à moins que vous ne retourniez 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 ObjectContext, vous pouvez utiliser les éléments suivants:
Assurez-vous que LazyLoading est désactivé à l'aide de la ligne suivante:
entities.ContextOptions.LazyLoadingEnabled = false;
Procédez ensuite en
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 ça. ctx est votre DataContext. Cela fonctionne pour moi :-)