2010-06-11 3 views
46

J'ai une instruction LINQ Joining en C# avec plusieurs conditions.LINQ Rejoindre en C# avec plusieurs conditions

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 jointure ne fonctionne pas correctement. Qu'est-ce que je fais mal?

+2

Ai-je tort de penser que cela pourrait arriver au point où il est illisible? Ce pourrait juste être le formatage. C'est totalement hors sujet et je m'excuse pour ça. –

+0

si vous avez une réponse, veuillez la marquer. Pour que votre requête fonctionne, vous devez nommer vos variables du même nom et les assimiler à vos projections (comme dans la réponse de Zar Shardan) et aussi corriger votre clause where comme dans la réponse de p.campbell) – ericosg

Répondre

5

Votre and doit être un && dans la clause where.

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

devrait être

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

AFAIK vous ne pouvez rejoindre cette façon:

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 
    } 

Les principales exigences sont les suivantes: noms de propriété, les types et l'ordre dans les objets anonymes de votre » L'adhésion doit correspondre.

Vous ne pouvez PAS utiliser des ORs, etc. dans les jointures. Juste object1 est égal à object2.

Plus de choses avancées dans cet exemple de 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}; 
} 

Aborder les noms et l'ordre de la propriété est simple, les types d'adressage peut être réalisé par coulée/conversion/analyse/appel de méthodes, etc. Cela ne fonctionne pas toujours avec LINQ à EF ou SQL ou NHibernate, la plupart des appels de méthode ne fonctionneront certainement pas et échoueront à l'exécution, donc YMMV. Cela est dû au fait qu'ils sont copiés dans les propriétés publiques en lecture seule des objets anonymes. Par conséquent, tant que votre expression produit des valeurs correctes, tapez la propriété join. Cela ne pose aucun problème.

+1

+1 pour la meilleure réponse ici – ericosg

+4

assez sûr que les noms de champs doivent correspondre, vous obtenez une erreur d'inférence de type s'ils ne –

+0

Merci Daniel, vous avez raison, mis à jour la réponse pour refléter vos notes et ajouté un autre exemple plus avancé. –

0

Si vous ne devez pas égal état objet utilisation jointure croisée séquences:

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