2012-02-27 3 views
0

linqのエンティティに対する実際のクエリは、このようにdbに対してうまくいきます。オブジェクトへのlinqを使用してクエリをユニット化しようとすると、null参照例外が発生します。Linqからオブジェクトへの一連の左結合をどのように処理するのですか?

linqPadで再現しました。

void Main() 
{ 
    var _news= new [] {new {ID=0, ExpiryDate=(DateTime?)null }, new {ID=1,ExpiryDate=(DateTime?)DateTime.UtcNow.AddDays(-1)}}; 
    var _newsRegionSource = new RegionSource[]{}; 
    var _entitledRegions=new Region[] {}; 

    var validNews = from n in _news.Where(n=>n.ExpiryDate==null || n.ExpiryDate>DateTime.UtcNow) 
     select n; 
    var q = from n in validNews 

      join r in _newsRegionSource 
      on n.ID equals r.ID into rLeft 
      from rn in rLeft.DefaultIfEmpty() 

      join erL in _entitledRegions 
      // adding .DefaultIfEmpty() here instead moves the exception to erL.ID 
      //NullReferenceException underlining rn at rn.RegionID 
      on rn.RegionID equals erL.ID into erLeft 
      from er in erLeft.DefaultIfEmpty() 

      where rn==null | (rn.ID==n.ID && er!=null) 
      select new {News=n,RegionID=(rn==null? (byte?)null: rn.RegionID)}; 
      var materialized=q.ToArray(); 
     materialized.Dump(); 

} 

public class Region 
{ 
    public byte ID {get;set;} 
} 
public class RegionSource 
{ 
    public int ID{get;set;} 
    public byte RegionID{get;set;} 
} 

はまた、私は製造

  • を試み確認がソース・アレイの全てにおいて、少なくとも1つのアイテムであった(彼らはまだ、この特定のクエリ/場合の0行をもたらす)、
  • .AsQueryable()

で配列をラップするにはどうすれば左Linq to Objectsでおそらく0行の合流扱うのですか?

答えて

0

エンティティの動作は、ここで見つけたように、左外部結合に関するオブジェクトに対してLINQの動作と少し異なります。あなたはまだそれを非常にわずかな微調整で動作させることができます。このトリックは、逆参照を避ける結合式を提供することにあります。null。それは潜在的にあなたに依存RegionIDの有効な値である可能性があるので、それはまた、任意の値の両方で、のように見えるInt32.MinValue以来、満足のいく未満

 on (rn == null : Int32.MinValue : rn.RegionID) equals erL.ID into erLeft 

私の最初の試みは、私が参加し表現していました使用法。もう1つのオプションはnull可能なintを使用することです。これは、Int32.MinValueケースをハイジャックすることなく同じ結果を提供するため、より満足しています。

次のように今、ショート( ||)に次の条件付きでOR( |)を変更
 on (rn == null ? (Int32?) null : rn.RegionID) equals erL.ID into erLeft 

代わり NullReferenceExceptionあなたは、単一のニュース、RegionID結果を受けなければならない今の
 where rn==null || (rn.ID==n.ID && er!=null) 

、予想通り。

関連する問題