我认为我已经完成了一个非常重复的查询,我想知道你是否可以帮助我理解如何做得更好。我正在执行Join
和GroupBy
,具体取决于EnumDateFilter
。你能帮帮我吗请尽快缩短代码吗?
非常感谢!
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;
}
}
答案 0 :(得分:0)
使用匿名类型,这很难实现。您可以尝试使用具体类型进行连接和分组。例如,您必须创建
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}
然后可以在LINQ中使用,例如
books.Join(dates, bookSelector, dateSelector, ...)
然后可以将您的开关缩减为获得适当的选择器,并且可以在交换机外部编写主查询。例如:
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, ...)
我希望这可以帮助你获得一些想法。