我有一个连接两个表的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,
...
};
答案 0 :(得分:7)
您可以使用status
屏蔽条件,如下所示:
where k.ReqCode == t.ReqCode && (!status || k.Name.Contains(Name))
如果status
为false
,则OR ||
将立即成功,并且AND &&
将为真(假设我们必须评估OR ||
,AND &&
的左侧必须为真。另一方面,如果status
为true
,则需要对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 ,最终查询仍然有效。