Linq中基于过滤器的动态分组

时间:2016-09-26 15:04:17

标签: c# entity-framework linq

我有两个过滤器。一个是按月,年,日分组,另一个过滤器是选择是否有人想按产品或公司分组。也可以有更多的过滤器。现在我在开始的时候为其他特定情况编写了if else。

List<IGrouping<String, TopItemReportData>> GroupedData = new List<IGrouping<String, TopItemReportData>>();

if (filters.DateBy.ToLower().Replace(" ", "") == "yearlyreport")
    GroupedData = topsalesQueryable.GroupBy(x => x.SalesDate.Year.ToString()).OrderByDescending(x => x.Sum(y => y.SellingQuantity)).Skip((filters.CurrentPage - 1) * filters.RecordsPerPage).Take(filters.RecordsPerPage).ToList();
else if (filters.DateBy.ToLower().Replace(" ", "") == "monthlyreport")
    GroupedData = topsalesQueryable.GroupBy(x => x.SalesDate.Month.ToString()).OrderByDescending(x => x.Sum(y => y.SellingQuantity)).Skip((filters.CurrentPage - 1) * filters.RecordsPerPage).Take(filters.RecordsPerPage).ToList();
else
    GroupedData = topsalesQueryable.GroupBy(x => x.SalesDate.Date.ToString()).OrderByDescending(x => x.Sum(y => y.SellingQuantity)).Skip((filters.CurrentPage - 1) * filters.RecordsPerPage).Take(filters.RecordsPerPage).ToList();

if (filters.GroupBy.ToLower().Replace(" ", "") == "variantoption")
    GroupedData = topsalesQueryable.GroupBy(x => (x.VariantId).ToString()).OrderByDescending(x => x.Sum(y => y.SellingQuantity)).Skip((filters.CurrentPage - 1) * filters.RecordsPerPage).Take(filters.RecordsPerPage).ToList();
else if (filters.GroupBy.ToLower() == "product")
    GroupedData = topsalesQueryable.GroupBy(x => (x.ProductId).ToString()).OrderByDescending(x => x.Sum(y => y.SellingQuantity)).Skip((filters.CurrentPage - 1) * filters.RecordsPerPage).Take(filters.RecordsPerPage).ToList();

但这不会起作用,因为现在我必须根据选定的过滤器值同时按年份和产品进行分组。所以当我尝试这样做时,我不知道替换字符串是什么,因为编译器会出错:

GroupedData = topsalesQueryable.GroupBy(x => new {x.SalesDate.Year.ToString(),x.ProductId.ToString()}).OrderByDescending(x => x.Sum(y => y.SellingQuantity)).Skip((filters.CurrentPage - 1) * filters.RecordsPerPage).Take(filters.RecordsPerPage).ToList();

必须使用成员分配声明匿名类型成员。我的问题是如何摆脱if else以及如何解决这个错误

1 个答案:

答案 0 :(得分:0)

您想要的只是包含年份和产品ID的单个字符串。

我们有一个非常简单的方法来创建它:

string.Format("{0:0000}|{1:000000}", x.SalesDate.Year, x.ProductId)

冒号获得字段大小后的零,以防ProductId的长度变化。

整件事(清理了一下)将是:

void Main()
{
    var filters = new Filters();
    var topsalesQueryable = new List<TopItemReportData>();
    var TopItemReportData = new List<TopItemReportData>();
    IEnumerable<IGrouping<String, TopItemReportData>> tempGroupedData;

    var dateBy = filters.DateBy.ToLower().Replace(" ", "");
    var groupBy = filters.GroupBy.ToLower().Replace(" ", "");


    if ( dateBy  == "yearlyreport")
    {
        if (groupBy ==  "product")
            tempGroupedData = TopItemReportData
                               .GroupBy(x =>string.Format("{0:0000}|{1:000000}",
                                         x.SalesDate.Year, x.ProductId));
        else
           tempGroupedData = TopItemReportData.GroupBy(x => x.SalesDate.Year.ToString());
    }
    else if (dateBy == "monthlyreport")
        tempGroupedData = topsalesQueryable.GroupBy(x => x.SalesDate.Month.ToString());
    else
        tempGroupedData = topsalesQueryable.GroupBy(x => x.SalesDate.Date.ToString());

    if (groupBy == "variantoption")
        tempGroupedData = topsalesQueryable.GroupBy(x => x.VariantId.ToString());
    else if (groupBy == "product")
        tempGroupedData = topsalesQueryable.GroupBy(x => x.ProductId.ToString());

    var GroupedData = tempGroupedData
                            .OrderByDescending(x => x.Sum(y => y.SellingQuantity))
                            .Skip((filters.CurrentPage - 1) * filters.RecordsPerPage)
                            .Take(filters.RecordsPerPage)
                            .ToList();
}

class Filters
{
    public string DateBy;
    public string GroupBy;
    public int CurrentPage;
    public int RecordsPerPage;

    public Filters()
    {
        DateBy = "Yearly Report";
        GroupBy = "variantoption";
    }

}

class TopItemReportData
{
    public DateTime SalesDate;
    public int SellingQuantity;
    public int VariantId;
    public int ProductId;
}

你仍然需要理顺if / elses,尽管我认为是消除DateBy属性并使用GroupBy的最佳方法。