Linq with Optional Where子句

时间:2018-04-24 17:39:35

标签: c# linq

我有一个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,但是我无法理解这一点,但是如果我能创建一些可重复使用的代码,那就太棒了!

3 个答案:

答案 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);
        }
}