6

建立一堆报告,必须对不同的领域一遍又一遍地做同样的事情

    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();
    }

我的脑海里一片空白,我如何才能将这两者结合在一起。

4

3 回答 3

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

我还没有检查它是否会编译,但你明白了。

于 2013-01-31T18:49:34.120 回答
1

看起来唯一改变的是分组参数的名称。你能写一个包装函数来接受指定分组参数的 lambdas 吗?或者甚至是一个接受两个字符串然后构建原始 T-SQL 的包装函数,而不是使用 LINQ?

或者,我不知道这是否会编译,您能否为 group 语句中的字段设置别名,以便始终可以以相同的方式引用分组构造,例如g.Key.id1and g.Key.id2?然后,您可以将分组构造传递给构造ReportSummary函数,并在一个地方进行左手/右手赋值。(你需要将它作为动态传递,因为它在调用站点是一个匿名对象)

于 2013-01-31T18:42:49.320 回答
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();
}

我不知道您为实体映射了哪些类型,所以我做了一些假设。使用适合您情况的任何内容。

于 2013-01-31T19:42:12.440 回答