【问题标题】:Multiple condition checks in the query?查询中的多个条件检查?
【发布时间】:2015-10-19 19:10:54
【问题描述】:

我有以下查询,我从 UI 传递了 4 个参数。 BU 和 Region 在 UI 中有单选按钮选项(All、Option1、Option2、Option3 等)。选项 1 - 3 是数据中的值,而“全部”不是。

有没有办法更有效地编写以下内容?例如,如果 BU 或 Region 值是“来自 UI”的“全部”(不是数据集中的值),如果选择了 all 是否有一个字符可以分配给 bu 或 region,以便查询知道选择所有的价值观?

我不知道是否有这样的事情,但我想避免做类似下面的事情。

     public string GetAvgSeatPrice(string bu, string region, DateTime? startDate, DateTime? endDate)
    {

        if (bu.Equals("All"))
        {
            var averageSeatPrice = (from r in db.Registrations
                                    where
                                         //r.BusinessUnit.Equals(bu) &&
                                         r.Region.Equals(region) &&
                                         r.StartDate >= startDate &&
                                         r.EndDate <= endDate &&
                                         r.ActualPrice > 0
                                    select r.ActualPrice).Average();

            var AvgSeatPrice = "$" + string.Format("{0:0.00}", averageSeatPrice);

            return AvgSeatPrice;
        }
        else if (region.Equals("All"))
        {
            var averageSeatPrice = (from r in db.Registrations
                                    where
                                         r.BusinessUnit.Equals(bu) &&
                                        // r.Region.Equals(region) &&
                                         r.StartDate >= startDate &&
                                         r.EndDate <= endDate &&
                                         r.ActualPrice > 0
                                    select r.ActualPrice).Average();

            var AvgSeatPrice = "$" + string.Format("{0:0.00}", averageSeatPrice);

            return AvgSeatPrice;
        }
        else if (bu.Equals("All") && region.Equals("All"))
        {
            var averageSeatPrice = (from r in db.Registrations
                                    where
                                         //r.BusinessUnit.Equals(bu) &&
                                         // r.Region.Equals(region) &&
                                         r.StartDate >= startDate &&
                                         r.EndDate <= endDate &&
                                         r.ActualPrice > 0
                                    select r.ActualPrice).Average();

            var AvgSeatPrice = "$" + string.Format("{0:0.00}", averageSeatPrice);

            return AvgSeatPrice;
        }
        else
        {
            var averageSeatPrice = (from r in db.Registrations
                                    where
                                         r.BusinessUnit.Equals(bu) &&
                                         r.Region.Equals(region) &&
                                         r.StartDate >= startDate &&
                                         r.EndDate <= endDate &&
                                         r.ActualPrice > 0
                                    select r.ActualPrice).Average();

            var AvgSeatPrice = "$" + string.Format("{0:0.00}", averageSeatPrice);

            return AvgSeatPrice;
        }

    }

}

}

【问题讨论】:

  • 您当前的代码有什么问题?你有错误吗?
  • 如果我传入选项 1、2 或 3,它会起作用,因为这些是我可以分配给这些选项的数据中的值。如果我选择“全部”,则没有什么可以比较的,因为没有任何值可以分配给 All 以在 Where 中进行比较。我想知道是否有一个字符可以分配给 All 选项,这样它就不会被过滤。

标签: c# entity-framework linq


【解决方案1】:

只需这样做:

public string GetAvgSeatPrice(string bu, string region, DateTime? startDate, DateTime? endDate)
    {
        var averageSeatPrice = (
            from r in db.Registrations
            where (bu == "ALL" || r.BusinessUnit.Equals(bu))
            && (region == "ALL" || r.Region.Equals(region))
            && r.StartDate >= startDate
            && r.EndDate <= endDate
            && r.ActualPrice > 0
            select r.ActualPrice).Average();

        var AvgSeatPrice = "$" + string.Format("{0:0.00}", averageSeatPrice);

        return AvgSeatPrice;
    }

由于 OR (||),如果选择是“ALL”,则永远不会检查第二个条件,并且不会通过给定属性缩小选择范围。 It is checked only if the selection is NOT "ALL" and in such case the selection is narrowed down.

【讨论】:

  • 谢谢,但是,'ALL' 不是数据集中的值,我正在寻找一个字符来替换 'ALL' 以便我可以在查询之前将其分配给 bu 以便查询不过滤。我什至不知道是否有这样的事情,但我正在尝试为上述代码找到更好的解决方案,我更新了这些代码以澄清我的愿望。
  • 我查看了您更新的问题,但我仍然认为我的回答正是您想要的。请注意,我不会将“ALL”与第一部分(|| 之前)的数据集进行比较。我只是检查来自 UI 的内容,如果它是“ALL”,那么整个条件已经为真,并且永远不会检查第二部分,这意味着您将获得所有记录。
  • 假设 BU 字段中的唯一值是“Cats”、“Dogs”和“Birds”。如果从 UI 传入“ALL”,根据您的解决方案,它会将记录限制为 0,因为“ALL”不是 BU 中的值。正确的?我错过了什么?
  • @JReam。这里的假设是“bu”来自 UI,“r.BusinessUnit”来自数据库。因此,与“bu”进行比较意味着与 UI 进行比较。 OR 条件“短路”另一个比较,因为它等于 true。
  • 如果我写了这个 (r.BusinessUnit.Equals("ALL") || r.BusinessUnit.Equals(bu)) 那么你是对的。但这不是我的解决方案。括号内只是一个返回真或假的条件(由两个较小的条件组成)。它会根据数据库中的所有记录进行检查,并返回它返回 true 的记录。请注意,如果您传递“ALL”,则 bu=="ALL" 的第一部分已经为真。每条记录都是如此,因此将返回每条记录。试试看吧。
【解决方案2】:

我希望这不是您要求提供的内容(我可以从您的问题中以两种不同的方式解释多个 if/else case/etc)。但你可以这样做:

var averageSeatPrice = 
    from r in db.Registrations
    where r.StartDate >= startDate &&
          r.EndDate <= endDate &&
          r.ActualPrice > 0

// note I'm assuming your "bu" "all" option is represented as the string "All"
if (bu.ToUpper() != "ALL") 
    averageSeatPrice = averageSeatPrice
        .Where(w => w.BusinessUnit == bu);

if (region.ToUpper() !+ "ALL")
    averageSeatPrice = averageSeatPrice
        .Where(w => w.Region == region);

averageSeatPrice = averageSeatPrice select r.ActualPrice).Average();

抱歉,我对您使用的 linq 语法不太清楚(或者我会用它来回答),但希望这会有所帮助。

基本上 if 语句说明如果选项是 not all,则附加 where 子句的该部分,否则它不会附加,并且永远不会成为查询。

Kritner - 你能详细说明你在这里做什么吗?似乎也是一种有趣的方法

给定BusinessUnit 可以有以下值:

option1
option2
option3

如果 bu 提供为 option1,那么我们需要 where 子句包含 where BusinessUnit = 'option1'

所以:

if (bu.ToUpper() != "ALL")  // bu is option1, evaluates true
    averageSeatPrice = averageSeatPrice // add the where clause to the IQueryable
        .Where(w => w.BusinessUnit == bu); // deferred execution, so have not yet executed query, and can continue to modify and only do a single trip to db

另一方面,如果bu 是“ALL”或 string.empty,或者您希望它是无效值的任何值,那么我们不希望 BusinessUnit 成为where 子句……发布的代码也完成了这个场景:

if (bu.ToUpper() != "ALL") // this evaluates to false (bu is "ALL"), don't add the where clause information at all.
    averageSeatPrice = averageSeatPrice
        .Where(w => w.BusinessUnit == bu);

每个averageSeatPrice = averageSeatPrice.Where(...) 都只是简单地附加到查询中,直到您枚举结果为止。

【讨论】:

  • Kritner - 你能详细说明你在这里做什么吗?似乎也是一种有趣的方法。
猜你喜欢
  • 2017-10-20
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-01
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多