带有多个条件的WHERE子句的LINQ查询

时间:2012-04-26 12:47:15

标签: linq entity-framework

我将EntityFramework与POCO一起使用 假设我的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条记录,这些记录属于Class1Class2Class3中的任何一条,其中ClassX.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.Class1x.Class2x.Class3始终具有null值。我感到惭愧,因为我没有明确说明延迟加载被禁用 - 问题本来就很明显了。

但是感谢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应该执行自动空合并。

2 个答案:

答案 0 :(得分:4)

恕我直言,你应该对此感到满意:

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之前测试空值,但如果您通过Linq-to评估SQL中的SomeNumber则不需要-entities。 Linq-to-entities应该执行自动空合并。

答案 1 :(得分: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();