2010-06-11 22 views
46

Tengo una declaración LINQ Joining en C# con múltiples condiciones.LINQ Unirse en C# con múltiples condiciones

var possibleSegments = 
    from epl in eventPotentialLegs 
    join sd in segmentDurations on 
     new { 
      epl.ITARequestID, 
      epl.ITASliceNumber, 
      epl.DepartAirportAfter, 
      epl.AirportId_Origin, 
      epl.AirportId_Destination 
     } 
     equals 
     new { 
      sd.ITARequestId, 
      sd.SliceIndex, 
      sd.OriginAirport, 
      sd.DestinationAirport 
     } 
    where 
     epl.DepartAirportAfter > sd.UTCDepartureTime 
     and 
     epl.ArriveAirportBy > sd.UTCArrivalTime 
    select new PossibleSegments{ ArrivalTime = sd.arrivalTime }; 

La unión no funciona correctamente. ¿Qué estoy haciendo mal?

+2

Me equivoco al pensar que esto podría llegar al punto en que es ilegible? Puede ser solo el formato. Esto está totalmente fuera de tema y me disculpo por eso. –

+0

si recibió una respuesta, por favor márquela. Para que su consulta funcione, debe nombrar sus variables con el mismo nombre e igualarlas en sus proyecciones (como en la respuesta de Zar Shardan) y también corregir su cláusula where como en la respuesta de p.campbell) – ericosg

Respuesta

5

Su and debe ser && en la cláusula where.

where epl.DepartAirportAfter > sd.UTCDepartureTime 
and epl.ArriveAirportBy > sd.UTCArrivalTime 

debe ser

where epl.DepartAirportAfter > sd.UTCDepartureTime 
&& epl.ArriveAirportBy > sd.UTCArrivalTime 
82

yo sepa sólo se puede unir de esta manera:

var query = from obj_i in set1 
join obj_j in set2 on 
    new { 
     JoinProperty1 = obj_i.SomeField1, 
     JoinProperty2 = obj_i.SomeField2, 
     JoinProperty3 = obj_i.SomeField3, 
     JoinProperty4 = obj_i.SomeField4 
    } 
    equals 
    new { 
     JoinProperty1 = obj_j.SomeOtherField1, 
     JoinProperty2 = obj_j.SomeOtherField2, 
     JoinProperty3 = obj_j.SomeOtherField3, 
     JoinProperty4 = obj_j.SomeOtherField4 
    } 

Los principales requisitos son: Los nombres de propiedades, tipos y orden en el anonimato objetos de su' e unirse en debe coincidir.

NO PUEDE utilizar ANDs ORs etc. en combinaciones. Solo object1 es igual a object2.

Más cosas avanzadas en este ejemplo LINQPad:

class c1 
    { 
    public int someIntField; 
    public string someStringField; 
    } 

class c2 
    { 
    public Int64 someInt64Property {get;set;} 
    private object someField; 
    public string someStringFunction(){return someField.ToString();} 
    } 

void Main() 
{ 
    var set1 = new List<c1>(); 
    var set2 = new List<c2>(); 

    var query = from obj_i in set1 
    join obj_j in set2 on 
     new { 
       JoinProperty1 = (Int64) obj_i.someIntField, 
       JoinProperty2 = obj_i.someStringField 
      } 
     equals 
     new { 
       JoinProperty1 = obj_j.someInt64Property, 
       JoinProperty2 = obj_j.someStringFunction() 
      } 
    select new {obj1 = obj_i, obj2 = obj_j}; 
} 

Dirigiéndose nombres y el orden propiedad es sencillo, tipos de direccionamiento se puede lograr a través de fundición/conversión/análisis/métodos de llamada, etc. Esto no siempre puede trabajar con LINQ para EF o SQL o NHibernate, la mayoría de las llamadas al método definitivamente no funcionarán y fallarán en el tiempo de ejecución, entonces YMMV. Esto se debe a que se copian en propiedades públicas de solo lectura en los objetos anónimos, por lo que siempre que su expresión produzca valores del tipo correcto, la propiedad de unión: debería estar bien.

+1

+1 para obtener la mejor respuesta aquí – ericosg

+4

bastante seguro de que los nombres de campo deben coincidir, obtienes un error de inferencia de tipo si no lo hacen –

+0

Gracias Daniel, estás en lo correcto, actualizaste la respuesta para reflejar tus notas y añadiste otro ejemplo más avanzado. –

0

Si necesita no es igual objeto de uso condición de combinación cruzada secuencias:

var query = from obj1 in set1 
from obj2 in set2 
where obj1.key1 == obj2.key2 && obj1.key3.contains(obj2.key5) [...conditions...] 
Cuestiones relacionadas