2012-07-10 128 views
1

我有一个连接两个表的LINQ表达式。我想有条件地检查其他布尔值:(通知文本之间的低于*********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, 
     ... 
    }; 

回答

7

您可以使用status掩盖病情,像这样:

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

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

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到对象至少,这将是更有效的加入对列:

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

在LINQ的任何味道它转换为SQL,我期望这尽管如此,仍然可以通过数据库或查询翻译进行优化。

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_HouseOwnerfilteredOwners

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

现在,你可能知道这一点,但这里的关键是,初始。凡“伸手”到数据库中。您的查询在您开始枚举之前(例如foreach)或者调用方法如ToList(),First(),FirstOrDefault()。这意味着您可以拨.Where在您的选择之后,如果您愿意并且最终查询仍然有效。