我有一个Linq语句,它有两个可选的Where子句但我无法弄清楚如何实现这个linq(目前我在这个方法中有4个linq语句当然不好!):
//Params passed into my method:
int StoreId = 0;
bool ShowEnabledTills = true;
var query = (from Transactions in db.Transactions
join Tills in db.Tills on new { TillId = Convert.ToInt32(Transactions.TillId) } equals new { TillId = Tills.TillId }
join CompanyAddresses in db.CompanyAddresses on new { CompanyId = Convert.ToInt32(Transactions.StoreID) } equals new { CompanyId = CompanyAddresses.CompanyId }
where
CompanyAddresses.CompanyId == StoreId <===== OPTIONAL
&& Tills.Active == ShowEnabledTills <===== OPTIONAL
select new
{
Tills.TillId,
Tills.ComputerName,
Tills.Description,
CompanyAddresses.CompDescription
}).Distinct();
我看了一下PredicateBuilder,但是我无法理解这一点,但是如果我能创建一些可重复使用的代码,那就太棒了!
答案 0 :(得分:1)
// get these from params to decide optional or not
var validateStoredId = false;
var validateActiveStatus = false;
在你的where
条款中执行以下操作:
where
(!validateStoreId || CompanyAddresses.CompanyId == StoreId)
&& (!validateActiveStatus || Tills.Active == ShowEnabledTills)
答案 1 :(得分:0)
试试这个:
var query = db.Transactions.Join(
db.Tills, //Join to this table
transaction => transaction.TillId //Outer key
, till => till.TillId, //Inner key
(transaction, till) => new {transaction, till}) //Result of join
.Join(db.CompanyAddresses, //Join to this table
r => r.till.StoreId, //Outer key
a => a.CompanyId, //Inner key
(r, address) => new {r.transaction, r.till, address}); //Result of join
if(StoreId != null)
query = query.Where(d => d.address.StoreId == StoreId);
if(ShowEnabledTills)
query = query.Where(d => d.till.Active == true);
var items = query.Select(d => new {
d.Till.TillId,
d.Till.ComputerName,
d.Till.Description,
d.address.CompDescription
}).Distinct();
我是在不了解你的架构的情况下做到的,但这应该会给你一个好主意。
我不喜欢&#34; SQL风格&#34;出于这个原因的语法(有时令人困惑)。我开始使用像这样的方法调用,从那以后就没有问题了。
答案 2 :(得分:0)
我认为我在这里有一些贡献。我遇到了同样的问题,并实施了类似的解决方案。然而!这不会像您希望的那样短路(或者至少不是我的!)
这导致我循环浏览一万个项目,以有效地检查true == false,这虽然不是一项昂贵的检查,但您仍然不想做数千次。
对于任何其他涉及此问题的人,我建议将您的查询分解为用if检查包装的子查询,这在处理大型数据集时会表现得更好:)
编辑:我为此目的构建了这个小帮手,希望其他人发现它有用,我很喜欢不必中断方法链:)
public static IEnumerable<T> OptionalWhere<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool excecuteFilter)
{
if (!excecuteFilter)
{
return source;
}
else
{
return source.Where(predicate);
}
}