1

我有一个连接两个表的 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,
        ...
    };
4

3 回答 3

7

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

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

如果statusfalse,则 OR||将立即成功,并且 AND&&将为真(假设我们必须评估 OR ||,AND 的左侧&&必须为真)。另一方面,如果statusis ,则需要评估 the 才能完成条件评估。truek.Name.Contains(Name)

于 2012-07-10T04:12:39.627 回答
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 风格中,我希望这将通过数据库或查询转换进行优化。

于 2012-07-10T04:18:27.407 回答
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替换为filtersOwners

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如果愿意,最终查询仍然有效。

于 2012-07-10T07:17:03.590 回答