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

私の心は、これら2つをどのように組み合わせることができるかについて空白を描いています。

4

3 に答える 3

1

変更されるのは、グループ化パラメーターの名前だけのようです。グループ化パラメーターを指定するラムダを受け入れるラッパー関数を記述できますか?または、LINQを使用する代わりに、2つの文字列を受け入れて生のT-SQLを構築するラッパー関数でさえありますか?

または、これがコンパイルされるかどうかはわかりませんが、groupステートメントのフィールドにエイリアスを付けて、グループ化構造を常に同じ方法で参照できるようにすることはできますg.Key.id1g.Key.id2?次に、グループ化構文をコンストラクターに渡し、ReportSummary左側/右側の割り当てを1か所で行うことができます。(ただし、呼び出しサイトでは匿名オブジェクトであるため、動的として渡す必要があります)

于 2013-01-31T18:42:49.320 に答える
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 に答える
0

2つのクエリ間で変更されるのはグループキーだけなので、パラメータ化してください。これは複合キー(内部に複数の値がある)であるため、これらの値を(一般的な名前で)保持できる単純なクラスを作成する必要があります。

この場合、パラメーター化するには、キーセレクターを関数のパラメーターにします。これを機能させるには、式とメソッドの構文である必要があります。次に、それを関数に一般化できます。

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 に答える