LINQ Присоединение к C # с несколькими условиями - PullRequest
53 голосов
/ 11 июня 2010

У меня есть оператор LINQ Joining в C # с несколькими условиями.

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

Соединение не работает правильно. Что я делаю не так?

Ответы [ 3 ]

95 голосов
/ 18 октября 2011

AFAIK Вы можете присоединиться только так:

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
    }

Основные требования: имена, типы и порядок свойств в анонимных объектах, к которым вы присоединяетесь, должны совпадать.

Вы не можете использовать AND или OR и т.д. в соединениях.Просто object1 равен object2.

Более сложные вещи в этом примере 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};
}

Адресация имен и порядка свойств проста, адресация типов может быть достигнута с помощью методов приведения / преобразования / анализа / вызоваи т. д. Это может не всегда работать с LINQ to EF, SQL или NHibernate, большинство вызовов методов определенно не будут работать и не будут работать во время выполнения, поэтому YMMV.Это связано с тем, что они копируются в общедоступные свойства только для чтения в анонимных объектах, поэтому, пока ваше выражение выдает значения правильного типа для свойства join - с вами все будет в порядке.

5 голосов
/ 11 июня 2010

Ваш and должен быть && в предложении where.

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

должен быть

where epl.DepartAirportAfter >  sd.UTCDepartureTime 
&& epl.ArriveAirportBy > sd.UTCArrivalTime
0 голосов
/ 18 апреля 2017

Если вам не нужно равное условие объекта, используйте последовательности перекрестного соединения:

var query = from obj1 in set1
from obj2 in set2
where obj1.key1 == obj2.key2 && obj1.key3.contains(obj2.key5) [...conditions...]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...