2012-04-26 20 views
6

私はPOCOでEntityFrameworkを使用します。
は、私はPOCOSこの(簡体字)のように定義されていると仮定します。複数の条件を持つWHERE句を使用したLINQクエリ

class Class1 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class Class2 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class Class3 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class SomeClass 
{ 
    public int ID; 
    public int? Class1ID; 
    public Class1 Class1; 
    public int? Class2ID; 
    public Class2 Class2; 
    public int? Class3ID; 
    public Class3 Class3; 
} 

は、私はどちらかClassX.SomeNumberは、いくつかの数に等しいClass1Class2またはClass3のいずれかに属し、データベースからすべてのSomeClassレコードを取得したいです。しかしretValueは、任意のレコードが含まれていません...

Database DB = new Database(); // object context 
var result = DB.SomeClass.ToList(); 

int SomeNumber = 1; // some number 
List<SomeClass> retValue = result 
    .Where(x => 
     { 
      int Number = 0; 
      if (x.Class1 != null) 
       Number = x.Class1.SomeNumber; 
      else if (x.Class2 != null) 
       Number = x.Class2.SomeNumber; 
      else if (x.Class3 != null) 
       Number = x.Class3.SomeNumber; 
      return Number == SomeNumber; 
     }) 
    .ToList(); 

私はこのようになりますLINQクエリを書きました。遅延ロードが無効になっていたと x.Class1x.Class2x.Class3は常に null値を持っていたので

ソリューションは、どうやら私は.Include文を指定する必要がありました。私は、怠惰なローディングが無効になっていることを明示していないので、恥じらいます。問題は明らかでした。

しかしラディスラフのポストのおかげで、私はそうのように私のコードを改善:

Database DB = new Database(); // object context 

int SomeNumber = 1; // some number 
List<SomeClass> retValue = DB.SomeClass 
    .Include("Class1") 
    .Include("Class2") 
    .Include("Class3") 
    .Where(x => 
     SomeNumber == x.Class1.SomeNumber || 
     SomeNumber == x.Class2.SomeNumber || 
     SomeNumber == x.Class3.SomeNumber) 
    .ToList(); 

自動ヌル合体を実行する必要があり、私はLINQツーエンティティを知りませんでした。

答えて

3

私見あなただけのこれでOKする必要があります:

Database DB = new Database(); 
var result = DB.SomeClass.Where(x => 
          Number == x.Class1.SomeNumber || 
          Number == x.Class2.SomeNumber || 
          Number == x.Class3.SomeNumber) 
         .ToList(); 

あなたのクエリは、すべてのデータをロードして、.NETでの状態を評価することの後に=あなたが前SomeNumberにアクセスするにはnull値をテストする必要がありますが、場合には必要ありませんLinq-to-entitiesを通じてSomeNumberをSQLで評価します。 Linqからエンティティへの自動ヌル統合を実行する必要があります。

+0

実は解決策は(私は通常私が尋ねる直後に自分自身をそれを見つける)されたことが原因遅延ロードを無効に( 'Class2 ')。' Where'句を実行する前にInclude( "Class3") 'を実行する必要がありました。しかし、私はコードを改善する方法を教えてくれたので、これを受け入れられたとマークしています(LINQ-To-Entitiesで直接 'Where'を使用してください) –

2

あなたのロジックによると、x.Class1がnullではないが、x.Class1.SomeNumberが3の場合、他のすべての句はチェックされません。あなたがチェックしたい場合は

、単にいくつかのClassN.SomeNumber == SomeNumber場合、あなたはこのようにそれを実行する必要があります。

int SomeNumber = 1; // some number 
List<SomeClass> retValue = result 
    .Where(x => 
     { 
      if (x.Class1 != null && x.Class1.SomeNumber == SomeNumber) 
       return true; 
      else if (x.Class2 != null && x.Class2.SomeNumber == SomeNumber) 
       return true; 
      else if (x.Class3 != null && x.Class3.SomeNumber == SomeNumber) 
       return true; 
      return false; 
     }) 
    .ToList(); 
+0

このコードは私のコードと同じですが、ライン? –

+0

いいえ。数値が等しい場合はすぐに戻ります。あなたのコードでは、正しい番号がありますが、別のif節で上書きされる可能性があります。 – LueTm

+0

'else'節があるのでオーバーライドすることはできません。条件に一致しない場合は0を返します。 –

関連する問題