Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq Join和GroupBy重构_C#_Entity Framework_Linq - Fatal编程技术网

C# Linq Join和GroupBy重构

C# Linq Join和GroupBy重构,c#,entity-framework,linq,C#,Entity Framework,Linq,我想我已经做了一个非常重复的查询,我想知道你是否可以帮助我了解如何做得更好。根据EnumDateFilter,我正在执行一个Join和GroupBy。你能帮我把代码尽量缩短吗 非常感谢 foreach (Client client in listClient){ var books = _servBook.GetBooks(BeginDate, EndDate, ClientId).ToList(); switch (enumDateFilter) {

我想我已经做了一个非常重复的查询,我想知道你是否可以帮助我了解如何做得更好。根据
EnumDateFilter
,我正在执行一个
Join
GroupBy
。你能帮我把代码尽量缩短吗

非常感谢

foreach (Client client in listClient){
    var books = _servBook.GetBooks(BeginDate, EndDate, ClientId).ToList();

    switch (enumDateFilter)
    {
        case EnumDateFilter.Today:
        case EnumDateFilter.OneDay:
            {
                books.Join(
                    dates,
                    bk => new { bk.Date.Hour, bk.Date.Day, bk.Date.Month, bk.Date.Year },
                    cd => new { cd.Date.Hour, cd.Date.Day, cd.Date.Month, cd.Date.Year },
                    (bk, chart) => new { bk, chart.Data }
                )
                .GroupBy(a => new
                {
                    a.bk.Date.Hour,
                    a.bk.Date.Day,
                    a.bk.Date.Month,
                    a.bk.Date.Year,
                    a.Data
                })
                .Select(
                    a =>
                    {
                        a.Key.Data[client.Name] = a.Count().ToString();
                        return a;
                    }
                ).ToList();
            }
            break;

        case EnumDateFilter.OneWeek:
        case EnumDateFilter.OneMonth:
        case EnumDateFilter.LastWeek:
        case EnumDateFilter.LastMonth:
            {
                books.Join(
                    dates,
                    bk => new { bk.Date.Day, bk.Date.Month, bk.Date.Year },
                    cd => new { cd.Date.Day, cd.Date.Month, cd.Date.Year },
                    (bk, chart) => new { bk, chart.Data }
                )
                .GroupBy(a => new
                {
                    a.bk.Date.Day,
                    a.bk.Date.Month,
                    a.bk.Date.Year,
                    a.Data
                })
                .Select(
                    a =>
                    {
                        a.Key.Data[client.Name] = a.Count().ToString();
                        return a;
                    }
                ).ToList();

                break;
            }

        case EnumDateFilter.ThreeMonths:
        case EnumDateFilter.SixMonths:
        case EnumDateFilter.OneYear:
        case EnumDateFilter.LastThreeMonths:
        case EnumDateFilter.LastSixMonths:
        case EnumDateFilter.LastYear:
            {
                books.Join(
                    dates,
                    bk => new { bk.Date.Month, bk.Date.Year },
                    cd => new { cd.Date.Month, cd.Date.Year },
                    (bk, chart) => new { bk, chart.Data }
                )
                .GroupBy(a => new
                {
                    a.bk.Date.Month,
                    a.bk.Date.Year,
                    a.Data
                })
                .Select(
                    a =>
                    {
                        a.Key.Data[client.Name] = a.Count().ToString();
                        return a;
                    }
                ).ToList();
                break;
            }

        case EnumDateFilter.SinceBeginning:
            {
                books.Join(
                    dates,
                    bk => new { bk.Date.Year },
                    cd => new { cd.Date.Year },
                    (bk, chart) => new { bk, chart.Data }
                )
                .GroupBy(a => new
                {
                    a.bk.Date.Year,
                    a.Data
                })
                .Select(
                    a =>
                    {
                        a.Key.Data[client.Name] = a.Count().ToString();
                        return a;
                    }
                ).ToList();
                break;
            }
    }

对于匿名类型,这将很难实现。您可以尝试使用具体类型进行连接和分组。例如,您必须创建

struct TimeDescriptor{
   public int Year;
   //TODO: Put other fields
}
这将允许您计算出一些lambda表达式,例如

Expression<Func<Book, TimeDescriptor>> bookSelector = b => new TimeDescriptor{Year = b.Date.Year, ...}
Expression<Func<DateType, TimeDescriptor>> dateSelector = d => new TimeDescriptor{Year = d.Date.Year}
然后,您的开关可以简化为获得适当的选择器,并且您可以在开关外部写入主查询。例如:

Expression<Func<Book, TimeDescriptor>> bookSelector;
Expression<Func<DateType, TimeDescriptor>> dateSelector;

switch((enumDateFilter)
{
    case EnumDateFilter.Today:
    case EnumDateFilter.OneDay:
         bookSelector = ...;
         dateSelector = ...;
         break;
    ...
}

return books.Join(dates, bookSelector, dateSelector, ...)
表达式选择器;
表达式日期选择器;
开关((enumDateFilter)
{
案例枚举日期筛选器。今天:
案例EnumDateFilter.OneDay:
bookSelector=。。。;
日期选择器=。。。;
打破
...
}
返回图书。加入(日期、图书选择器、日期选择器等)

我希望这能帮助您获得一些想法。

对于匿名类型,这将很难实现。您可以尝试使用具体类型进行连接和分组。例如,您必须创建

struct TimeDescriptor{
   public int Year;
   //TODO: Put other fields
}
这将允许您计算出一些lambda表达式,例如

Expression<Func<Book, TimeDescriptor>> bookSelector = b => new TimeDescriptor{Year = b.Date.Year, ...}
Expression<Func<DateType, TimeDescriptor>> dateSelector = d => new TimeDescriptor{Year = d.Date.Year}
然后,您的交换机可以简化为获取适当的选择器,并且您可以在交换机外部写入主查询。例如:

Expression<Func<Book, TimeDescriptor>> bookSelector;
Expression<Func<DateType, TimeDescriptor>> dateSelector;

switch((enumDateFilter)
{
    case EnumDateFilter.Today:
    case EnumDateFilter.OneDay:
         bookSelector = ...;
         dateSelector = ...;
         break;
    ...
}

return books.Join(dates, bookSelector, dateSelector, ...)
表达式选择器;
表达式日期选择器;
开关((enumDateFilter)
{
案例枚举日期筛选器。今天:
案例EnumDateFilter.OneDay:
bookSelector=。。。;
日期选择器=。。。;
打破
...
}
返回图书。加入(日期、图书选择器、日期选择器等)

我希望这能帮助您获得一些想法。

用表达式替换是什么意思?Lambda表达式,但我不确定它是否可能用于什么目的?您认为Lambda表达式允许您在这里做什么?请发布有意义的代码。您可以调用
ToList()
在每种情况下都不使用结果。这是没有意义的。问题是,在切换的每种情况下,我都会重新引用查询,结果基本相同。我认为可以简化查询。也许您有一些建议“替换为表达式”是什么意思?Lambda表达式,但我不确定它是否可能用于什么目的?您认为Lambda表达式允许您在此处执行什么操作?请发布有意义的代码。您可以调用
ToList()
在每种情况下都不使用结果。这是没有意义的。问题是,在每种切换情况下,我都会重新引用查询,结果基本相同。我认为可以简化查询。也许您有一些建议感谢Ronald的回答!非常有帮助!感谢Ronald的回答!非常有帮助!