2010-06-11 9 views
46

Mam instrukcję dołączania LINQ w języku C# z wieloma warunkami.Łączenie LINQ w języku C# z wieloma warunkami

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 }; 

Łączenie nie działa poprawnie. Co ja robię źle?

+2

mylę się sądząc, że to może dostać się do punktu, gdzie jest nieczytelny? Może to być po prostu formatowanie. To całkowicie nie na temat i przepraszam za to. –

+0

jeśli masz odpowiedź, zaznacz ją. Aby zapytanie zadziałało, musisz nazwać zmienne o tej samej nazwie i przyrównać je do swoich prognoz (jak w odpowiedzi Zar Shardana), a także poprawić klauzulę "gdzie", jak w odpowiedzi p.campbell). – ericosg

Odpowiedz

5

Twoja and powinna być && w klauzuli where.

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

powinny być

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

AFAIK można dołączyć tylko w ten sposób:

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 
    } 

Główne wymagania to: Nazwy właściwości, rodzaje i kolejność w anonimowym obiektów swoimi” Dołączanie musi pasować.

NIE MOŻNA używać elementów AND i innych w połączeniach. Tylko object1 jest równy object2.

Bardziej zaawansowane rzeczy w tym przykładzie 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}; 
} 

Adresowanie nazwy i kolejność nieruchomość jest prosta, zwracając typy mogą być osiągnięte poprzez odlewniczych/konwersji/parsowania/metod wywołujących itd. Może to nie zawsze działa z LINQ do EF lub SQL lub NHibernate, większość wywołań metod zdecydowanie nie zadziała i zawiedzie w czasie wykonywania, więc YMMV. Dzieje się tak dlatego, że są one kopiowane do publicznych właściwości tylko do odczytu w anonimowych obiektach, tak długo jak wyrażenie generuje wartości poprawnego typu właściwości łączenia - powinno być dobrze.

+1

+1 za najlepszą odpowiedź tutaj – ericosg

+4

Jestem pewien, że nazwy pól muszą się zgadzać, pojawia się błąd wnioskowania, jeśli nie są one zgodne z –

+0

. Dziękuję, Danielu, masz rację, zaktualizowałeś odpowiedź, aby odzwierciedlić notatki i dodano inny, bardziej zaawansowany przykład. –

0

Jeśli potrzebujesz nie równa obiekt użycie warunek krzyż dołączyć sekwencje:

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