构建一堆报告,必须一遍又一遍地使用不同的字段做同样的事情
public List<ReportSummary> ListProducer()
{
return (from p in Context.stdReports
group p by new { p.txt_company, p.int_agencyId }
into g
select new ReportSummary
{
PKi = g.Key.int_agencyId,
Name = g.Key.txt_company,
Sum = g.Sum(foo => foo.lng_premium),
Count = g.Count()
}).OrderBy(q => q.Name).ToList();
}
public List<ReportSummary> ListCarrier()
{
return (from p in Context.stdReports
group p by new { p.txt_carrier, p.int_carrierId }
into g
select new ReportSummary
{
PKi = g.Key.int_carrierId,
Name = g.Key.txt_carrier,
Sum = g.Sum(foo => foo.lng_premium),
Count = g.Count()
}).OrderBy(q => q.Name).ToList();
}
我的思绪在如何将这两者结合在一起的空白。
答案 0 :(得分:1)
看起来唯一改变的是分组参数的名称。你能编写一个包含指定分组参数的lambdas的包装函数吗?或者甚至是一个包装器函数,它接受两个字符串然后构建原始T-SQL,而不是使用LINQ?
或者,我不知道这是否会编译,您是否可以对group语句中的字段进行别名,以便始终可以以相同的方式引用分组结构,例如g.Key.id1
和{{1} }?然后,您可以将分组构造传递给g.Key.id2
构造函数,并在一个位置执行左手/右手分配。 (您需要将其作为动态传递,因为它是呼叫站点的匿名对象)
答案 1 :(得分:1)
你可以这样做:
public List<ReportSummary> GetList(Func<Record, Tuple<string, int>> fieldSelector)
{
return (from p in Context.stdReports
group p by fieldSelector(p)
into g
select new ReportSummary
{
PKi = g.Key.Item2
Name = g.Key.Item1,
Sum = g.Sum(foo => foo.lng_premium),
Count = g.Count()
}).OrderBy(q => q.Name).ToList();
}
然后你可以这样称呼它:
var summary = GetList(rec => Tuple.Create(rec.txt_company, rec.int_agencyId));
或:
var summary = GetList(rec => Tuple.Create(rec.txt_carrier, rec.int_carrierId));
当然,您需要将Record
替换为实际返回的Context.stdReports
类型。
我没有检查过是否会编译,但你明白了。
答案 2 :(得分:0)
由于两个查询之间的所有更改都是组键,因此请对其进行参数化。由于它是一个复合键(在其中有多个值),因此您需要创建一个可以保存这些值的简单类(使用通用名称)。
在这种情况下,要对其进行参数化,请将键选择器作为函数的参数。它必须是表达式和方法语法才能使其工作。然后,您可以将其概括为函数:
public class GroupKey
{
public int Id { get; set; }
public string Name { get; set; }
}
private IQueryable<ReportSummary> GetReport(
Expression<Func<stdReport, GroupKey>> groupKeySelector)
{
return Context.stdReports
.GroupBy(groupKeySelector)
.Select(g => new ReportSummary
{
PKi = g.Key.Id,
Name = g.Key.Name,
Sum = g.Sum(report => report.lng_premium),
Count = g.Count(),
})
.OrderBy(summary => summary.Name);
}
然后使用适当的密钥选择器在您的查询中使用此函数。
public List<ReportSummary> ListProducer()
{
return GetReport(r =>
new GroupKey
{
Id = r.int_agencyId,
Name = r.txt_company,
})
.ToList();
}
public List<ReportSummary> ListCarrier()
{
return GetReport(r =>
new GroupKey
{
Id = r.int_carrierId,
Name = r.txt_carrier,
})
.ToList();
}
我不知道您为实体映射的类型,所以我做了一些假设。在你的情况下使用任何适当的东西。