LINQ Joining in C# with multiple conditions

最后都变了- 提交于 2019-12-17 15:23:04

问题


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?


回答1:


AFAIK 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 your'e 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. 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.




回答2:


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



回答3:


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...]


来源:https://stackoverflow.com/questions/3020442/linq-joining-in-c-sharp-with-multiple-conditions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!