2017-03-14 15 views
0

私は生成しなければならないレポートのいくつかに見られる定期的なパターンを持っています。これらのレポートは、日付範囲に基づくレポートであり、異なるレベルで集計する必要があります。階層データ - 複合パターンC#

このレポートでは、リーフノードレベル(最下位レベル)にタイトルとクォータが生成されたとします。広告申込情報レベル(さまざまなリーフノードのコレクション)で、私はクォータを集約し、別のタイトルを提供したいと思います。これらの広告申込情報は、さらにクォータを集計して固有のタイトルを持つ別のレベルにロールアップされます。

だから、報告書は、このようなものになるだろう:

ROOT LEVEL | Title = "Main Report" | Quota = 100 
    Month Level | Title = "Jan" | Quota = 100 
    Week Level | Title = "Week 1" | Quota = 25 
    Week Level | Title = "Week 2" | Quota = 75 

は私が合成パターンを使用して、これを構築するための方法はありますか?私は数多くのアプローチを試みました。クォータを効果的に集計して上位レベルに集計することができないため、ほとんどが不足しています。その後、私はそうのようなライン・アイテムを構築することができ

public interface IInventoryReportItem 
{ 
    string Title { get; set; } 
    int Quota { get; set; } 
} 

::私はそうのようなインターフェースを構築することができます

public class LineItem : IInventoryReportItem 

私もそうのようなコレクションを構築することができます

public class LineItems : IList<IInventoryReportItem>, IInventoryReportItem 
{ 
    private readonly List<IInventoryReportItem> _subLineItems; 

    public LineItems() 
    { 
     _subLineItems = new List<IInventoryReportItem>(); 
    } 

私の報告書は次のようになります:

public class InventoryReport 
{ 
    public DateRange DateRange { get; set; } 
    public LineItems LineItems { get; set; } 

} 

私は今、階層的に簡単にレポートを作成することができますが、私はまだそれとは対照的に、自動計算する私のためにこれを外部から集約関数を呼び出す必要があります。

var report = new InventoryReport(); 

     var week1Days = new LineItems 
     { 
      new LineItem {Quota = 20, Title = "Day 1"}, 
      new LineItem {Quota = 10, Title = "Day 2"} 
     }; 

     var week2Days = new LineItems 
     { 
      new LineItem {Quota = 10, Title = "Day 1"}, 
      new LineItem {Quota = 10, Title = "Day 2"} 
     }; 

     var week1 = new LineItems {week1Days}; 
     week1.Quota = week1.Sum(x => x.Quota); 
     week1.Title = "Week1"; 


     var week2 = new LineItems {week2Days}; 
     week2.Quota = week2.Sum(x => x.Quota); 
     week2.Title = "Week2"; 

     var month1 = new LineItems(new List<IInventoryReportItem> {week1, week2}); 
     month1.Title = "January"; 
     month1.Quota = month1.Sum(x => x.Quota); 

     report.LineItems = new LineItems(new List<IInventoryReportItem> {month1}); 

あります私はまだ、単一のラインアイテムまたはアイテムの範囲のいずれかを追加する柔軟性を持つことができますし、また、複合材料を使って私のためにデータを自動計算/集計しますか?

助けがあれば助かります。

は、あなたがRX(リアクティブエクステンション)を探しているようですので、あなたが各レベルで毎回手動を合計する必要はありませんが、私にとっては、 Anup

+1

独自の長さをチェックする 'LineItems' 'Quota'プロパティのゲッターを実装し、0より大きい場合は子の' Quota'を合計します。私はそれが "複合パターン"に適合しているかどうかはわかりませんが、動作するコードのパターンにパターンが入り込まないようにしています。 –

答えて

0

をありがとうございました。代わりに、必要なサブスクリプションをセットアップし、自動的に再計算を取得してください。例: Good example of Reactive Extensions Use

+0

こんにちは、接続シナリオでは問題ありません。これはapiの後ろにあり、私はJSONとしてワイヤーを送りたいと思っています。 –

0

私はこの問題を解決しました。興味がある人のために、ここで私はそれを解決方法は次のとおりです。

私が示したようにインタフェースを内蔵:

public class LineItem : IInventoryReportItem 
{ 

    public LineItem(string title, int quota, int totalTicketsSold, int totalUnitsSold, int totalCheckedIn, 
     decimal totalSalesAmount) 
    { 
     Title = title; 
     Quota = quota; 
     TotalUnitsSold = totalUnitsSold; 
     TotalTicketsSold = totalTicketsSold; 
     TotalCheckedIn = totalCheckedIn; 
     TotalSalesAmount = totalSalesAmount; 
    } 

    public string Title { get; set; } 
    public int Quota { get; } 
    public int TotalTicketsSold { get; } 
    public int TotalUnitsSold { get; } 
    public int TotalCheckedIn { get; } 
    public decimal TotalSalesAmount { get; } 

} 
を次のように私はのLineItemと呼ばれるクラスで、このインタフェースを実装し

public interface IInventoryReportItem 
{ 
    string Title { get; set; } 
    int Quota { get; } 
    int TotalTicketsSold { get; } 
    int TotalUnitsSold { get; } 
    decimal TotalSalesAmount { get; } 
} 

私はまた、LineItemsというカスタムコレクションクラスを以下のように作成しました。コレクションはタイプIInventoryReportItemそのものです。

public class LineItems : IInventoryReportItem 
{ 
    public string Title { get; set; } 
    public int Quota => Contents?.Sum(x => x.Quota) ?? 0; 
    public int TotalTicketsSold => Contents?.Sum(x => x.TotalTicketsSold) ?? 0; 
    public int TotalUnitsSold => Contents?.Sum(x => x.TotalUnitsSold) ?? 0; 
    public decimal TotalSalesAmount => Contents?.Sum(x => x.TotalSalesAmount) ?? 0; 

    public readonly List<IInventoryReportItem> Contents; 

    public LineItems(List<IInventoryReportItem> lineItems) 
    { 
     Contents = lineItems ?? new List<IInventoryReportItem>(); 
    } 

} 

このコレクションクラスレベルですべての集計が行われます。次のように

レポートクラスは次のとおりです。

public class InventoryReport 
{ 
    public DateRange DateRange { get; set; } 
    public IInventoryReportItem LineItems { get; set; } 

} 

私はそのようにのようなレポートを作成することができました:

Report = new InventoryReport(); 
     var week1 = new LineItems(new List<IInventoryReportItem> 
     { 
      new LineItem("Day1", 10, 10, 10, 4, 100), 
      new LineItem("Day2", 10, 5, 5, 1, 50) 
     }) 
     {Title = "Week1"}; 

     var week2 = new LineItems(new List<IInventoryReportItem> 
     { 
      new LineItem("Day1", 20, 20, 20, 20, 200), 
      new LineItem("Day2", 20, 5, 5, 5, 50) 
     }) {Title = "Week2"}; 

     var month1 = new LineItems(new List<IInventoryReportItem> {week1, week2}) {Title = "January"}; 
     Report.LineItems = new LineItems(new List<IInventoryReportItem> {month1}) {Title = "Daily Report"}; 

私は私のAPIから受け取った最終出力(JSON)が似ていますso:

{ 
"lineItems": { 
"contents": [ 
    { 
    "contents": [ 
     { 
     "contents": [ 
      { 
      "title": "Day1", 
      "quota": 10, 
      "totalTicketsSold": 10, 
      "totalUnitsSold": 10, 
      "totalCheckedIn": 4, 
      "totalSalesAmount": 100 
      }, 
      { 
      "title": "Day2", 
      "quota": 10, 
      "totalTicketsSold": 5, 
      "totalUnitsSold": 5, 
      "totalCheckedIn": 1, 
      "totalSalesAmount": 50 
      } 
     ], 
     "title": "Week1", 
     "quota": 20, 
     "totalTicketsSold": 15, 
     "totalUnitsSold": 15, 
     "totalSalesAmount": 150 
     }, 
     { 
     "contents": [ 
      { 
      "title": "Day1", 
      "quota": 20, 
      "totalTicketsSold": 20, 
      "totalUnitsSold": 20, 
      "totalCheckedIn": 20, 
      "totalSalesAmount": 200 
      }, 
      { 
      "title": "Day2", 
      "quota": 20, 
      "totalTicketsSold": 5, 
      "totalUnitsSold": 5, 
      "totalCheckedIn": 5, 
      "totalSalesAmount": 50 
      } 
     ], 
     "title": "Week2", 
     "quota": 40, 
     "totalTicketsSold": 25, 
     "totalUnitsSold": 25, 
     "totalSalesAmount": 250 
     } 
    ], 
    "title": "January", 
    "quota": 60, 
    "totalTicketsSold": 40, 
    "totalUnitsSold": 40, 
    "totalSalesAmount": 400 
    } 
], 
"title": "Daily Report", 
"quota": 60, 
"totalTicketsSold": 40, 
"totalUnitsSold": 40, 
"totalSalesAmount": 400 
    } 
} 

この方法を使用すると、集計を実行するオーバーヘッドをなくすことができました。同じ署名を使用してコレクションまたは個々のアイテムを引き続き使用することができます。

誰かがこの情報を参考にしてくれたらうれしいですね。