C# LINQ中的条件Groupby

C# LINQ中的条件Groupby,c#,linq,C#,Linq,我试图做非常相似的linq语句,但条件是它们略有不同。现在,我只是重复整个声明,稍作修改,但这应该可以更加简洁。我要做的是在语句中执行条件groupby和条件select。我的长版本是: class data { public string year; public string quarter; public string month; public string week; public string tariff; public double

我试图做非常相似的linq语句,但条件是它们略有不同。现在,我只是重复整个声明,稍作修改,但这应该可以更加简洁。我要做的是在语句中执行条件groupby和条件select。我的长版本是:

class data
{
    public string year;
    public string quarter;
    public string month;
    public string week;
    public string tariff;
    public double volume;
    public double price;
}

class results
{
    public string product_code;
    public string tariff;
    public double volume;
    public double price;
}

class Program
{
    public static List<results> aggregationfunction(List<data> inputdata, string tarifftype, string timecategory)
    {
        List<results> returndata = new List<results>();

        if (tarifftype.Equals("daynight") & timecategory.Equals("yearly"))
        {
            returndata = inputdata.GroupBy(a => new { a.tariff, a.year })
                                  .Select(g => new results { product_code = g.Select(a => a.year).First(), tariff = g.Select(a => a.tariff).First(), volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                      .ToList();
        }
        else if (tarifftype.Equals("allday") & timecategory.Equals("yearly"))
        {
            returndata = inputdata.GroupBy(a => new { a.year })
                                  .Select(g => new results { product_code = g.Select(a => a.year).First(), tariff = "allday", volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                  .ToList();
        }
        else if (tarifftype.Equals("daynight") & timecategory.Equals("quarterly"))
        {
            returndata = = inputdata.GroupBy(a => new { a.tariff, a.year, a.quarter })
                                    .Select(g => new results { product_code = g.Select(a => a.year).First() + "_" + g.Select(a => a.quarter).First(), tariff = g.Select(a => a.tariff).First(), volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                    .ToList();
        }
        else if (tarifftype.Equals("allday") & timecategory.Equals("quarterly"))
        {
            returndata = inputdata.GroupBy(a => new { a.year, a.quarter })
                                  .Select(g => new results { product_code = g.Select(a => a.year).First() + "_" + g.Select(a => a.quarter).First(), tariff = "allday", volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                  .ToList();
        } 

        return returndata;
    }
}
类数据
{
公共字符串年;
公共字符串季度;
公众弦月;
公共字符串周;
公共关税;
公共双卷;
公开双价;
}
课堂成绩
{
公共字符串产品代码;
公共关税;
公共双卷;
公开双价;
}
班级计划
{
公共静态列表聚合函数(列表输入数据、字符串tarifftype、字符串时间类别)
{
List returndata=新列表();
if(tarifftype.Equals(“daynight”)&timecategory.Equals(“年度”))
{
returndata=inputdata.GroupBy(a=>new{a.tarriff,a.year})
.Select(g=>newresults{product_code=g.Select(a=>a.year.First(),关税=g.Select(a=>a.price.First(),volume=g.Sum(a=>a.volume),price=g.Average(a=>a.price)})
.ToList();
}
else if(tarifftype.Equals(“全天”)和timecategory.Equals(“每年”))
{
returndata=inputdata.GroupBy(a=>new{a.year})
.Select(g=>newresults{product_code=g.Select(a=>a.year).First(),tarriff=“allday”,volume=g.Sum(a=>a.volume),price=g.Average(a=>a.price)})
.ToList();
}
else if(tarifftype.Equals(“daynight”)&timecategory.Equals(“季刊”))
{
returndata==inputdata.GroupBy(a=>new{a.tariff,a.year,a.quarter})
.Select(g=>newresults{product\u code=g.Select(a=>a.year.First()+“\u”+g.Select(a=>a.quarter.First(),关税=g.Select(a=>a.price.First(),数量=g.Sum(a=>a.volume),价格=g.Average(a=>a.price)})
.ToList();
}
else if(tarifftype.Equals(“全天”)和timecategory.Equals(“季度”))
{
returndata=inputdata.GroupBy(a=>new{a.year,a.quarter})
.Select(g=>newresults{product\u code=g.Select(a=>a.year.First()+“\u”+g.Select(a=>a.quarter.First(),tarriff=“allday”,volume=g.Sum(a=>a.volume),price=g.Average(a=>a.price)})
.ToList();
} 
返回数据;
}
}
任何指点都将不胜感激。正如您所看到的,group by以及关税和产品代码的分配有所不同,但这并不意味着我需要重复所有内容,是吗?

通过
inputdata.GroupBy返回的项目。
(其中
data
inputdata
的元素类型)将始终实现
IEnumerable
,而不考虑匿名密钥类型(可能是{year}或{private,year}等)。因此,可以将所有GroupBy值概括为
IEnumerable
,然后可以将其分解为两个步骤:

IEnumerable<IEnumerable<data>> groups;
if (condition) {
    groups = inputdata.GroupBy(a => new { a.year });
} else if (condition) {
    groups = inputdata.GroupBy(a => new { a.tariff, a.year });
} else {
    groups = inputdata.GroupBy(a => new { a.year, a.quarter });
}
returndata = groups.Select(...)
较短的代码:

return inputdata
    .GroupBy(a => new
    {
        a.year,
        quarter = timecategory == "quarterly" ? a.quarter : string.Empty,
        tariff = tarifftype == "daynight" ? a.tariff : "allday"
    })
    .Select(g => new results
    {
        product_code = g.Key.year + (string.IsNullOrEmpty(g.Key.quarter) ? "" : "_" + g.Key.quarter),
        tariff = g.Key.tariff,
        volume = g.Sum(a => a.volume),
        price = g.Average(a => a.price)
    })
    .ToList();

在分组中的任何地方,您都有
g.Select(a=>a.something)。首先()
您应该有
g.Key.something
。这是获取键的一个值的适当方法。此外,可能值得将tarifftype和timecategory更改为enum而不是string,然后在尝试确定条件时获得intellisense。愚蠢的问题(很有可能)在我的真实问题中,我有很多变量,通常我会先选择,我可以一直使用g.key吗?@nik只要你按感兴趣的变量分组,你就应该使用g.key
return inputdata
    .GroupBy(a => new
    {
        a.year,
        quarter = timecategory == "quarterly" ? a.quarter : string.Empty,
        tariff = tarifftype == "daynight" ? a.tariff : "allday"
    })
    .Select(g => new results
    {
        product_code = g.Key.year + (string.IsNullOrEmpty(g.Key.quarter) ? "" : "_" + g.Key.quarter),
        tariff = g.Key.tariff,
        volume = g.Sum(a => a.volume),
        price = g.Average(a => a.price)
    })
    .ToList();