LINQ Joining in C# with multiple conditions
I have a LINQ Joining statement in C# with multiple 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 };
The joining does not work correctly. What am I doing wrong?
As far as I know you can only join this way:
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
}
The main requirements are: Property names, types and order in the anonymous objects you're joining on must match.
You CAN'T use ANDs, ORs, etc. in joins. Just object1 equals object2.
More advanced stuff in this LinqPad example:
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};
}
Addressing names and property order is straightforward, addressing types can be achieved via casting/converting/parsing/calling methods etc. This might not always work with LINQ to EF or SQL or NHibernate, most method calls definitely won't work and will fail at run-time, so YMMV (Your Mileage May Vary). This is because they are copied to public read-only properties in the anonymous objects, so as long as your expression produces values of correct type the join property - you should be fine.
Your and
should be a &&
in the where
clause.
where epl.DepartAirportAfter > sd.UTCDepartureTime
and epl.ArriveAirportBy > sd.UTCArrivalTime
should be
where epl.DepartAirportAfter > sd.UTCDepartureTime
&& epl.ArriveAirportBy > sd.UTCArrivalTime
If you need not equal object condition use cross join sequences:
var query = from obj1 in set1
from obj2 in set2
where obj1.key1 == obj2.key2 && obj1.key3.contains(obj2.key5) [...conditions...]