查询中有多个条件检查?

时间:2015-10-19 19:10:55

标签: c# entity-framework linq

我有以下查询,我从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;
        }

    }

}

}

2 个答案:

答案 0 :(得分:4)

只需这样做:

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(||),如果选择是&#34; ALL&#34;永远不会检查第二个条件,也不会通过给定属性缩小选择范围。仅在选择不是&#34; ALL&#34;在这种情况下,选择范围缩小了。

答案 1 :(得分: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语句表明该选项是 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是&#34; ALL&#34;或者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(...)都会简单地添加到查询中,直到您枚举结果为止。