3

次のLinqクエリがあります:

List<MonthlySales> monthlySales = (from sale in Sales
                     group sale by new { sale.DateSold.Month, sale.Product.Shop } into ds
                     select new MonthlyTitleSales
                     {
                         Shop = ds.Select(it => it.Product.Shop).FirstOrDefault(),
                         Month = ds.Select(it => it.DateSold.Month).FirstOrDefault(),
                         Year = ds.Select(it => it.DateSold.Year).FirstOrDefault(),
                         USDNumberItemsSold = ds.Where(it => it.USDCut.HasValue).Where(it => it.USDCut != 0).Count(),
                         GBPNumberItemsSold = ds.Where(it => it.GBPCut.HasValue).Where(it => it.GBPCut != 0).Count(),
                         EURNumberItemsSold = ds.Where(it => it.EURCut.HasValue).Where(it => it.EURCut != 0).Count(),
                         USDRevenueTotal = PerformCurrencyConversion(ds.Sum(it => it.USDCut.HasValue ? it.USDCut.Value : 0), 0M, 0M, Currency, endDate),
                         GBPRevenueTotal = PerformCurrencyConversion(0M, ds.Sum(it => it.GBPCut.HasValue ? it.GBPCut.Value : 0), 0M, Currency, endDate),
                         EURRevenueTotal = PerformCurrencyConversion(0M, 0M, ds.Sum(it => it.EURCut.HasValue ? it.EURCut.Value : 0), Currency, endDate),
                     }).OrderBy(it => it.DateSold.Month).ToList();

このクエリは、各リスト アイテムに次の要素を含むリストを返します: Shop、Month、Year、Revenue Made

最終的に必要なのは、各月の全店舗の売上の中央値を計算することなので、それができるようにデータを準備する必要があります。

このリストを月ごとに小さなリストに分割するのが 1 つの方法かもしれないと考えましたが、これが最も効率的な解決策であるかどうかは疑問です。

これについて何か考えている人はいますか?

見る必要がある人のための毎月のセールスクラス:

public class MonthlySales
    {
        public int Month { get; set; }
        public int Year { get; set; }

        public Shop Shop { get; set; }

        public int USDNumberItemsSold { get; set; }
        public int GBPNumberItemsSold { get; set; }
        public int EURNumberItemsSold { get; set; }
        public int TotalNumberItemsSold { get { return USDNumberItemsSold + GBPNumberItemsSold + EURNumberItemsSold; } }

        public decimal USDRevenueTotal { get; set; }
        public decimal GBPRevenueTotal { get; set; }
        public decimal EURRevenueTotal { get; set; }
        public decimal OverallEarnings { get { return USDRevenueTotal + GBPRevenueTotal + EURRevenueTotal; } }
    }
4

2 に答える 2

6

を使用GroupByして、リストを月ごとにグループ化できます。たとえば、次の例では、月 (実際には月 + 年) でグループ化し、月ごとのすべての値をコンソールに書き出します。

var grouped = monthlySales.GroupBy(ms => string.Format("{0}-{1}", ms.Month, ms.Year));

foreach(var group in grouped)
{
     Console.WriteLine("Values in month-year of {0}:", group.Key);
     foreach(var ms in group)
         Console.WriteLine("   {0}", ms.USDRevenueTotal);
}
于 2012-05-16T22:36:21.193 に答える
1

GroupByは、この問題に最適です。ToLookupも検討してください(同じコードを使用して、GroupByをToLookupに変更するだけです)。

違い:

  • GroupByは怠惰です。
  • ToLookupは熱心です。

  • GroupByは、その怠惰な性質のため、結果を生成するためにぶらぶらしているソースに依存します。ソースが変更された場合、GroupByの結果には変更が含まれます-接続されています。
  • ToLookupは、その熱心な性質により、ソースが変更されても消えてもかまいません。切断されています。

  • GroupByは、を返しますIEnumerable<IGrouping<TKey, TValue>>。これは、ループスルーにのみ適しています。
  • ToLookupは、を返します。これは、であることに加えて、キーによるシークをサポートするという点でILookup<TKey, TValue>類似しています。Dictionary<TKey, List<TValue>>IEnumerable<IGrouping<TKey, TValue>>

また、キーの文字列の代替案を検討してください。キーとして機能する匿名クラスは次のとおりです。

var grouped = monthlySales.GroupBy(ms => new {ms.Month, ms.Year}); 
于 2012-05-17T01:35:00.300 に答える