56

複数の条件を持つ C# の LINQ Joining ステートメントがあります。

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

結合が正しく機能しません。私は何を間違っていますか?

4

3 に答える 3

105

私の知る限り、この方法でのみ参加できます。

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 (Your Mileage May Vary) です。これは、それらが匿名オブジェクトの読み取り専用パブリック プロパティにコピーされるためです。そのため、式が正しい型の結合プロパティの値を生成する限り、問題はありません。

于 2011-10-18T19:56:39.070 に答える
4

あなたは句の中にあるandべきです。&&where

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

する必要があります

where epl.DepartAirportAfter >  sd.UTCDepartureTime 
&& epl.ArriveAirportBy > sd.UTCArrivalTime
于 2010-06-11T05:49:01.170 に答える