Linq表达式中的条件

时间:2012-07-10 04:09:45

标签: c# sql linq linq-to-sql linq-to-entities

我有一个连接两个表的LINQ表达式。我想有条件地检查另一个布尔值:(注意下面*********之间的文字)

bool status = testfunc();

var List = 
    from t in Houses
    join k in Tbl_HouseOwner on t.HouseCode equals k.HouseCode
    where k.ReqCode== t.ReqCode 
    *********** if (status) { where k.Name.Contains(Name) } **********
    select new
    {
        ...
        name = k.Name,
        ...
    };

3 个答案:

答案 0 :(得分:7)

您可以使用status屏蔽条件,如下所示:

where k.ReqCode == t.ReqCode && (!status || k.Name.Contains(Name))

如果statusfalse,则OR ||将立即成功,并且AND &&将为真(假设我们必须评估OR ||,AND &&的左侧必须为真。另一方面,如果statustrue,则需要对k.Name.Contains(Name)进行评估,以便完成对条件的评估。

答案 1 :(得分:3)

dasblinkenlight的答案(应该可以正常工作)的另一种选择是以编程方式构建查询。在这种情况下,您正在有效地更改连接的右侧,因此您可以使用:

IQueryable<Owner> owners = Tbl_HouseOwner;
if (status)
{
    owners = owners.Where(k => k.Name.Contains(Name));
}

然后:

var query = from t in Houses
            join k in owners on t.HouseCode equals k.HouseCode
            where k.ReqCode == t.ReqCode
            select new { ... };

哪种方法最合适取决于您的方案。如果要添加各种不同的查询过滤器,以编程方式构建它可以更清晰 - 并使任何给定查询的最终SQL更容易理解。对于一次性,dasblinkenlight的方法更简单。

另请注意,至少在LINQ to Objects中,加入两个列会更有效:

var query = from t in Houses
            join k in owners 
            on new { t.HouseCode, t.ReqCode } equals new { k.HouseCode, k.ReqCode }
            select new { ... };

在任何转换为​​SQL的LINQ中,我都希望通过数据库或查询转换来优化它。

答案 2 :(得分:1)

我是这样做的:

        IQueryable<X> r = from x in Xs
                                  where (x.Status == "Active")
                                  select x;
        if(withFlagA) {
            r = r.Where(o => o.FlagA == true);
        }

为了使这适合你的例子,首先你可以这样做:

 IQueryable<YourOwnerType> filteredOwners = Tbl_HouseOwner;
 if( status ) {
     filteredOwners = filteredOwners.Where( o => o.Name.Contains(Name) );
 }

然后将 Tbl_HouseOwner 替换为 filteredOwners

var List = 
from t in Houses
join k in filteredOwners on t.HouseCode equals k.HouseCode
where k.ReqCode== t.ReqCode 
//Nothing here 
select new
{
    ...
    name = k.Name,
    ...
};

现在,你可能知道这一点,但这里的重点是最初的 .Where '伸出'到数据库。在您开始枚举它(例如foreach)或调用 ToList() First() FirstOrDefault()等方法之前,您的查询不会被执行。这意味着如果您愿意,可以在选择后调用 .Wheres ,最终查询仍然有效。