2009-02-06 21 views
34

Soy muy nuevo en Linq y estoy desnudo conmigo. ¿Puedo devolver más de un artículo en una selección? Por ejemplo, tengo una lista de accesorios (piense en los partidos de fútbol (o fútbol para los yanquis)). Cada accesorio contiene un equipo local y visitante y un puntaje de local y visitante. Quiero obtener todos los equipos que dibujaron. Quiero usar algo como¿Puedo seleccionar varios objetos en una consulta de Linq?

IEnumerable<Team> drew = from fixture in fixtures 
         where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
         select fixture.HomeTeam && fixture.AwayTeam; 

Sé que esta sintaxis es incorrecta, lo que no sé es si es posible hacer esto. ¿Necesitaría dos consultas y luego las concatenaría?

Editar: esto es realmente una cosa de aprendizaje por lo que no es crítico lograr esto de una manera particular. Básicamente, en esta etapa todo lo que quiero es una lista de los equipos que han dibujado. Un ejemplo de uso podría ser que para una lista dada de aparatos puedo encontrar todos los equipos dibujados para poder actualizar sus posiciones en una tabla por 1 punto (3 para una victoria, 0 para una pérdida).

Saludos James

Respuesta

21

Creo que está buscando el método de la Unión de la siguiente manera:

IEnumerable<Team> drew = (from fixture in fixtures 
        where fixture.Played 
         && (fixture.HomeScore == fixture.AwayScore) 
        select fixture.HomeTeam) 
        .Union(from fixture in fixtures 
        where fixture.Played 
         && (fixture.HomeScore == fixture.AwayScore) 
        select fixture.AwayTeam); 
+1

¿Hay alguna palabra clave LINQ equivalente al método '.Union()'? –

30

101 LINQ Samples, a saber Select - Anonymous tipos 1

... select new { HomeTeam = fixture.HomeTeam, AwayTeam = fixture.AwayTeam }; 
+0

No es la respuesta que está buscando. Él quiere una lista de equipos, no una lista de tipos anónimos con propiedades de equipo de casa y de equipo visitante. –

+0

Esto es cierto ... podría sortearlo utilizando tipos anónimos ... solo me preguntaba si había una manera de obtener solo una lista de equipos. Si es la única forma en que es la única forma en que –

+0

estoy de acuerdo en que esto no devuelve una lista de equipos, pero creo que es mejor que él adapte su código para soportar el manejo de este tipo de anon. Si James Hay pudiera actualizar su pregunta para describir su uso, eso podría ayudar. – bendewey

5

Editar: Lo sentimos, entendido mal su pregunta original, por lo reescribió respuesta.

Se puede usar el operador "SelectMany" para hacer lo que quiera:

IEnumerable<Team> drew = 
      (from fixture in fixtures 
      where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
        select new List<Team>() 
          { HomeTeam = fixture.HomeTeam, 
           AwayTeam = fixture.AwayTeam 
          }).SelectMany(team => team); 

Esto devolverá una lista de los equipos de aplanado que sacaban.

6

O puede definir un tipo para contener todos los datos:

IEnumerable<TeamCluster> drew = from fixture in fixtures 
         where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
         select new TeamCluster { 
          Team1 = fixture.HomeTeam, 
          Team2 = fixture.AwayTeam, 
          Score1 = fixture.HomeScore, 
          Score2 = fixture.AwayScore 
         }; 

class TeamCluster { 
    public Team Team1 { get; set; } 
    public Team Team2 { get; set; } 
    public int Score1 { get; set; } 
    public int Score2 { get; set; } 
} 
21

Una variación (independiente) sobre John la solución de precio ...

IEnumerable<Team> drew = 
    from fixture in fixtures 
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
    from team in new[]{fixture.AwayTeam, fixture.HomeTeam} 
    select team; 

Se podría considerar la adición de "ParticipatingTeams" a la clase de accesorio para obtener:

IEnumerable<Team> drew = 
    from fixture in fixtures 
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
    from team in fixture.ParticipatingTeams 
    select team; 
+3

+1 para su primera consulta - no requiere un cambio de contrato y es más eficiente que la respuesta principal. –

14

Tomando una puñalada de esto yo mismo se me ocurrió la misma versión que "depende".

Utilizando la sintaxis comprensión de consulta:

IEnumerable<Team> drew = 
    from fixture in fixtures 
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
    from team in new[]{fixture.AwayTeam, fixture.HomeTeam} 
    select team; 

El uso de lambda con los métodos de extensión:

IEnumerable<Team> drew = 
    fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore) 
    .SelectMany(f => new[]{f.HomeTeam, f.AwayTeam}); 

Editar: no sé si un equipo pudo haber jugado y elaborado más de una vez en su base de datos, pero si eso es posible, entonces puede hacer uso del operador de consulta Distinct:

IEnumerable<Team> drew = 
    (from fixture in fixtures 
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore) 
    from team in new[]{fixture.AwayTeam, fixture.HomeTeam} 
    select team).Distinct(); 

o:

IEnumerable<Team> drew = 
    fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore) 
    .SelectMany(f => new[]{f.HomeTeam, f.AwayTeam}) 
    .Distinct(); 
+1

La última muestra funcionó para mí. También me enseñó que puedes usar la inferencia de tipo para declarar matrices. Todos los días es un día escolar. – Gusdor

1

Vine contra este mismo asunto, y no podía encontrar lo que quería, así que escribí un pequeño método de extensión, que hice lo que quería.

public static IEnumerable<R> MapCombine<M, R>(this IEnumerable<M> origList, params Func<M, R>[] maps) 
{ 
    foreach (var item in origList) 
    foreach (var map in maps) 
    { 
     yield return map(item); 
    } 
} 

Siguiendo el problema en la pregunta, usted entonces hacer algo como esto

var drew = fixtures.Where(fixture => fixture.Played && 
         (fixture.HomeScore == fixture.AwayScore)) 
        .MapCombine(f => f.HomeTeam, f => f.AwayTeam); 

Curiosamente IntelliSense no es exactamente contento con esto, no obtiene la expresión Lamdba en la parte superior de el menú desplegable, sin embargo después de '=>' es bastante feliz. Pero lo principal es que el compilador está contento.

Cuestiones relacionadas