【问题标题】:Dynamically/Conditionally adding multiple LINQ GroupBy动态/有条件地添加多个 LINQ GroupBy
【发布时间】:2012-02-28 06:48:11
【问题描述】:

我有一个提供用户选择的用户界面

  1. 表格类型(在几乎相同列集的两个表格之间进行选择)
  2. 运算(总和、平均值、中位数等)
  3. GroupBy 选项(一堆复选框)

我计划创建一个基于用户选择返回结果集的方法,虽然我认为我已经完成了其他所有事情(除了表格选择),但我仍然坚持如何使用 GroupBy(或任何其他方式)一个接一个地建立group by子句。

这是现在唯一让我想到使用简单的 SQL 字符串生成来执行此操作的事情。

这是我目前的代码:

public IQueryable<ACSImpactAnalysisModel> GetDataForReport(TableType table, uint year,     OpType operation, uint groupOptions, uint measures)
    {
        var dataContext = new ACSImpactEntities();

        var discharges = from p in dataContext.ACSNationals
                         select new 
                         {
                             p.YEAR,
                             p.AGE,
                             p.FEMALE,
                             p.RACE,
                             p.ASOURCE,
                             p.PAY1,
                             LOS = p.LOS > 0 ? p.LOS : 0,
                             CHG = p.TOTCHG > 0 ? p.TOTCHG : 0,
                             NPR = p.NPR > 0 ? p.NPR : 0,
                             DIS_STS = p.DISPUB04 > 0 ? p.DISPUB04 : 0
                         };

        //if (table == TableType.states)
        //    discharges = from p in dataContext.ACSStates
        //                 select p;


        List<int> years = new List<int>();
        if ((year & Constants.YEAR2008) == Constants.YEAR2008) years.Add(2008);
        if ((year & Constants.YEAR2009) == Constants.YEAR2009) years.Add(2009);

        discharges = discharges.Where(a => years.Any(b => a.YEAR == b));

        if ((groupOptions & Constants.SEX) == Constants.SEX)
            discharges = discharges.Where(a => a.FEMALE > 0);

        if ((groupOptions & Constants.RACE) == Constants.RACE)
            discharges = discharges.Where(a => a.RACE > 0);

        if ((groupOptions & Constants.ER_ADMISSION) == Constants.ER_ADMISSION)
            discharges = discharges.Where(a => a.ASOURCE > 0);

        if ((groupOptions & Constants.PAYER_TYPE) == Constants.PAYER_TYPE)
            discharges = discharges.Where(a => a.PAY1 > 0);

        var analysis = from a in discharges
                       select new
                       {
                           AGE_GROUP = 
                           (
                                a.AGE >= 18 && a.AGE <= 44 ? "18-44" :
                                a.AGE >= 45 && a.AGE <= 54 ? "45-54" :
                                a.AGE >= 55 && a.AGE <= 64 ? "55-64" : ">= 65"
                           ),
                           SEX = (a.FEMALE == 1 ? "FEMALE" : "MALE"),
                           RACE = 
                           (
                                a.RACE == 1 ? "WHITE" :
                                a.RACE == 2 ? "BLACK" :
                                a.RACE == 3 ? "HISPANIC" :
                                a.RACE == 4 ? "ASIAN OR PACIFIC ISLANDER" :
                                a.RACE == 5 ? "NATIVE AMERICAN" :
                                a.RACE == 6 ? "OTHER" : ""
                           ),
                           ASOURCE = (a.ASOURCE == 1 ? "ER" : "NON ER"),
                           PAY1 =
                           (
                                a.PAY1 == 1 ? "MEDICARE" :
                                a.PAY1 == 2 ? "MEDICAID" :
                                a.PAY1 == 3 ? "PRIVATE INCLUDE HMO" :
                                a.PAY1 == 4 ? "SELF PAY" :
                                a.PAY1 == 5 ? "NO CHARGE" :
                                a.PAY1 == 6 ? "OTHER" : ""
                           ),
                            a.YEAR,
                            a.FEMALE,
                            a.LOS,
                            a.CHG,
                            a.NPR,
                            a.DIS_STS
                       };

        var grouped_analysis = analysis.GroupBy(groups => groups.YEAR);

        //These lines generate error, but this is something what I want to be able to  do
        if ((groupOptions & Constants.AGE_GROUP) == Constants.AGE_GROUP)
            grouped_analysis = analysis.GroupBy(age_group => age_group.AGE_GROUP);

        if ((groupOptions & Constants.ASOURCE) == Constants.ASOURCE)
            grouped_analysis = analysis.GroupBy(asource => asource.ASOURCE);


        return analysis;
    }

【问题讨论】:

    标签: linq dynamic group-by conditional


    【解决方案1】:

    您可以使用Dynamic Linq,您可能还需要Predicate Builder

    【讨论】:

    • 关于动态 Linq,它不会违背编写类型安全查询的全部目的吗?至于谓词生成器,我无法理解它如何有助于将多个条件分组添加到结果集中。似乎更适合构建动态 where/filter 子句
    • 在处理此类查询时很高兴了解 Predicate Builder(是的,用于 Where)
    • DynamicLinq 有一个分组依据的扩展方法。我在 SO 上看到了示例。
    • 嗯...我猜 Dynamic Linq 是下一个最好的东西。理想情况下,我希望一个接一个地进行多个 GroupBy 调用(有条件的),就像我对条件 where 子句所做的那样。在使用 Dynamic Linq 和您的解决方案之前,我会继续努力并尝试找到更多选择。谢谢。
    • 在花费大量时间寻找合适的 Linq 动态查询库文档后,我发现使用它很困难,而且与使用基于字符串的查询生成相比,它甚至没有提供任何显着的好处,我可能必须回到使用后者。但是,感谢您向我指出任何可用的替代方案。
    猜你喜欢
    • 2011-04-25
    • 2012-11-20
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    相关资源
    最近更新 更多