8

POCO で EntityFramework を使用します。
POCO が次のように定義されているとします (簡略化)。

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

データベースからすべてのレコードを取得したいと思いSomeClassます。これは、 のいずれかに属しているClass1Class2またはClass3ClassX.SomeNumber何らかの数値に等しい場合です。

次のようなLINQクエリを作成しました。

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();

...しかしretValue、レコードは含まれていません。

ソリューション

.Include遅延読み込みが無効になっていて、常に値があったため、ステートメントをx.Class1指定する必要があったようです。遅延読み込みが無効になっていることを明示的に述べていなかったので、私は恥ずかしく思います-その時、問題は明らかだったでしょう.x.Class2x.Class3null

ただし、Ladislav の投稿のおかげで、コードを次のように改善しました。

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-to-Entities が自動 null 合体を実行する必要があることを知りませんでした。

4

2 に答える 2

5

私見あなたはこれだけで大丈夫なはずです:

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

クエリはすべてのデータをロードし、その後 .NET で条件を評価します = アクセスする前に null 値をテストする必要がありますが、Linq-to-entities を介して SQL でSomeNumber評価する場合は必要ありません。SomeNumberLinq-to-entities は、自動 null 合体を実行する必要があります。

于 2012-04-26T13:05:06.510 に答える
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();
于 2012-04-26T13:05:30.553 に答える