Utilisation de la syntaxe d'extension J'essaie de créer une jointure à gauche à l'aide de LINQ sur deux listes que j'ai. Ce qui suit provient de l'aide de Microsoft, mais je l'ai modifié pour montrer que la liste des animaux de compagnie ne contient aucun élément. Je termine avec une liste de 0 éléments. Je suppose que c'est parce qu'il y a une jointure interne. Ce que je veux finir est une liste de 3 éléments (les objets 3 personnes) avec des données nulles renseignées pour les éléments manquants. c'est-à-dire une jointure à gauche. Est-ce possible?
Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" };
Person charlotte = new Person { Name = "Weiss, Charlotte" };
//Pet barley = new Pet { Name = "Barley", Owner = terry };
//Pet boots = new Pet { Name = "Boots", Owner = terry };
//Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
//Pet daisy = new Pet { Name = "Daisy", Owner = magnus };
List<Person> people = new List<Person> { magnus, terry, charlotte };
//List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };
List<Pet> pets = new List<Pet>();
// Create a list of Person-Pet pairs where
// each element is an anonymous type that contains a
// Pet's name and the name of the Person that owns the Pet.
var query =
people.Join(pets,
person => person,
pet => pet.Owner,
(person, pet) =>
new { OwnerName = person.Name, Pet = pet.Name }).ToList();
Je pense que si vous voulez utiliser des méthodes d'extension, vous devez utiliser le GroupJoin
var query =
people.GroupJoin(pets,
person => person,
pet => pet.Owner,
(person, petCollection) =>
new { OwnerName = person.Name,
Pet = PetCollection.Select( p => p.Name )
.DefaultIfEmpty() }
).ToList();
Vous devrez peut-être jouer avec l'expression de sélection. Je ne suis pas sûr que cela vous donnerait ce que vous voulez dans le cas où vous avez une relation un à plusieurs.
Je pense que c'est un peu plus facile avec la syntaxe LINQ Query
var query = (from person in context.People
join pet in context.Pets on person equals pet.Owner
into tempPets
from pets in tempPets.DefaultIfEmpty()
select new { OwnerName = person.Name, Pet = pets.Name })
.ToList();
Vous devez obtenir les objets joints dans un jeu, puis appliquer DefaultIfEmpty comme indiqué par JPunyon:
Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" };
Person charlotte = new Person { Name = "Weiss, Charlotte" };
Pet barley = new Pet { Name = "Barley", Owner = terry };
List<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet>{barley};
var results =
from person in people
join pet in pets on person.Name equals pet.Owner.Name into ownedPets
from ownedPet in ownedPets.DefaultIfEmpty(new Pet())
orderby person.Name
select new { OwnerName = person.Name, ownedPet.Name };
foreach (var item in results)
{
Console.WriteLine(
String.Format("{0,-25} has {1}", item.OwnerName, item.Name ) );
}
Les sorties:
Adams, Terry has Barley
Hedlund, Magnus has
Weiss, Charlotte has
Je le message d'erreur suivant face à ce même problème:
Le type d'une des expressions dans la clause join est incorrect. L'inférence de type a échoué lors de l'appel à 'GroupJoin'.
Résolu lorsque j'ai utilisé le même nom de propriété, cela a fonctionné.
(...)
join enderecoST in db.PessoaEnderecos on
new
{
CD_PESSOA = nf.CD_PESSOA_ST,
CD_ENDERECO_PESSOA = nf.CD_ENDERECO_PESSOA_ST
} equals
new
{
enderecoST.CD_PESSOA,
enderecoST.CD_ENDERECO_PESSOA
} into eST
(...)
Voici un bon article de blog qui vient d'être posté par Fabrice (auteur de LINQ in Action) qui couvre le contenu de la question que j'ai posée. Je le mets ici pour référence, car les lecteurs de la question trouveront cela utile.
Conversion des requêtes LINQ de syntaxe de requête en syntaxe de méthode/opérateur
Les jointures à gauche dans LINQ sont possibles avec la méthode DefaultIfEmpty (). Je n'ai cependant pas la syntaxe exacte pour votre cas ...
En fait, je pense que si vous changez simplement d'animaux de compagnie en animaux de compagnie.
EDIT: Je ne devrais vraiment pas répondre aux questions quand il est tard ...
Si vous avez réellement une base de données, voici le moyen le plus simple:
var lsPetOwners = ( from person in context.People
from pets in context.Pets
.Where(mypet => mypet.Owner == person.ID)
.DefaultIfEmpty()
select new { OwnerName = person.Name, Pet = pets.Name }
).ToList();