Pregunta

El uso de la sintaxis de extensión que estoy tratando de crear una izquierda se unen utilizando LINQ en dos listas que tengo. El siguiente es de la ayuda de Microsoft, pero he modificado para mostrar que la lista de mascotas no tiene elementos. Lo que estoy terminando con una lista de elementos 0. Asumo que esto se debe a una Unión interna está teniendo lugar. Lo que quiero es terminar con una lista de 3 elementos (los objetos Persona 3) con datos nulos rellenaron de los elementos que faltan. es decir, una izquierda-Unir. ¿Es esto posible?

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();
¿Fue útil?

Solución

Creo que si desea utilizar los métodos de extensión es necesario utilizar la 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();

Es posible que tenga que jugar con la expresión de la selección. No estoy seguro de que daría desea que desear en el caso de que usted tiene una relación de 1 a varios.

Creo que es un poco más fácil con la sintaxis de consultas LINQ

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();

Otros consejos

Es necesario para conseguir los objetos unidas en un conjunto y luego aplicar DefaultIfEmpty como dijo 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 ) );
}

Salidas:

Adams, Terry              has Barley
Hedlund, Magnus           has
Weiss, Charlotte          has

el siguiente mensaje de error cuando se enfrentan el mismo problema:

El tipo de una de las expresiones de la cláusula de combinación es incorrecta. La inferencia de tipos falló en la llamada a 'GroupJoin'.

resuelve cuando he usado el mismo nombre de propiedad, funcionó.

(...)

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

(...)

He aquí una buena entrada de blog que acaba de ser publicado por Fabrice (autor de LINQ en Acción), que cubre el material en la pregunta que le hice. Me estoy poniendo aquí por referencia como lectores de la cuestión se encuentra este útil.

conversión de consultas LINQ de sintaxis de consulta con el método / operador sintaxis

Izquierda se une en LINQ son posibles con el método DefaultIfEmpty (). No tengo la sintaxis exacta para su caso, sin embargo ...

En realidad creo que si se acaba de cambiar a los animales domésticos pets.DefaultIfEmpty () en la consulta que podría funcionar ...

EDIT: Realmente no debería responder a las cosas cuando es tarde ...

Si usted tiene realmente una base de datos, esta es la manera más 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();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top