Объединение и перемещение нескольких списков с помощью LINQ - PullRequest
2 голосов
/ 02 февраля 2012

Привет, у меня есть следующий код, который возвращает мне правильные данные, но, похоже, должен быть лучший способ объединить 3 списка, основанные на их общих полях, и перенести результаты в новый список заданного типа.используя LINQ, вместо того, чтобы прибегать к foreach в конце.Любые идеи?

  public IEnumerable<StagSummaryByCflHistoricalItem> GetSummaryByCflHistorical(DateTime currentDate)
  {
     var allRecords =
        this.preGrantSummaryHistoricalRepository
           .AllWithFetch(this.preGrantSummaryHistoricalRepository.All, x => x.CaseFileLocation)
           .Where(
           x => x.Date >= currentDate.FirstDayOfQuarterFromDateTime()
           && x.Date <= currentDate.LastDayOfQuarterFromDateTime())
           .ToList();

     var summaryForQuarter =
        allRecords.GroupBy(x => new { x.CaseFileLocation.Id, x.CaseFileLocation.Name }).Select(
           x =>
           new
              {
                 CaseFileLocationId = x.Key.Id,
                 Description = x.Key.Name,
                 TotalCasesEnteredCfl = x.Sum(y => y.TotalCasesEntered),
                 TotalNetFeeEnteredCfl = x.Sum(y => y.TotalNetFeeEntered),
                 TotalCasesLeftCfl = x.Sum(y => y.TotalCasesLeft),
                 TotalNetFeeLeftCfl = x.Sum(y => y.TotalNetFeeLeft)
              })
              .OrderBy(x => x.CaseFileLocationId)
              .ToList();

     var summaryForMonth =
        allRecords.Where(x => x.Date >= currentDate.FirstDayOfMonthFromDateTime())
        .GroupBy(x => new { x.CaseFileLocation.Id, x.CaseFileLocation.Name }).Select(
           x =>
           new
              {
                 CaseFileLocationId = x.Key.Id,
                 Description = x.Key.Name,
                 TotalCasesEnteredCfl = x.Sum(y => y.TotalCasesEntered),
                 TotalNetFeeEnteredCfl = x.Sum(y => y.TotalNetFeeEntered),
                 TotalCasesLeftCfl = x.Sum(y => y.TotalCasesLeft),
                 TotalNetFeeLeftCfl = x.Sum(y => y.TotalNetFeeLeft)
              })
              .OrderBy(x => x.CaseFileLocationId)
              .ToList();

     var summaryForWeek =
        allRecords.Where(x => x.Date >= currentDate.FirstDayOfWeekFromDateTime(DayOfWeek.Monday)).GroupBy(
           x => new { x.CaseFileLocation.Id, x.CaseFileLocation.Name }).Select(
              x =>
              new
                 {
                    CaseFileLocationId = x.Key.Id,
                    Description = x.Key.Name,
                    TotalCasesEnteredCfl = x.Sum(y => y.TotalCasesEntered),
                    TotalNetFeeEnteredCfl = x.Sum(y => y.TotalNetFeeEntered),
                    TotalCasesLeftCfl = x.Sum(y => y.TotalCasesLeft),
                    TotalNetFeeLeftCfl = x.Sum(y => y.TotalNetFeeLeft)
                 })
                 .OrderBy(x => x.CaseFileLocationId)
                 .ToList();

     var finalList = summaryForQuarter
        .Select(x => new StagSummaryByCflHistoricalItem()
           {
              CaseFileLocationId = x.CaseFileLocationId,
              Description = x.Description,
              QuarterTotalCasesEnteredCfl = x.TotalCasesEnteredCfl,
              QuarterTotalCasesLeftCfl = x.TotalCasesLeftCfl,
              QuarterTotalNetFeeEnteredCfl = x.TotalNetFeeEnteredCfl,
              QuarterTotalNetFeeLeftCfl = x.TotalNetFeeLeftCfl
           })
           .OrderBy(x => x.CaseFileLocationId)
           .ToList();

     foreach (var qrt in finalList)
     {

        var mnthData = summaryForMonth.FirstOrDefault(x => x.CaseFileLocationId == qrt.CaseFileLocationId);

        if (mnthData != null)
        {
           qrt.MonthTotalCasesEnteredCfl = mnthData.TotalCasesEnteredCfl;
           qrt.MonthTotalCasesLeftCfl = mnthData.TotalCasesLeftCfl;
           qrt.MonthTotalNetFeeEnteredCfl = mnthData.TotalNetFeeEnteredCfl;
           qrt.MonthTotalNetFeeLeftCfl = mnthData.TotalNetFeeLeftCfl;
        }

        var weekData = summaryForWeek.FirstOrDefault(x => x.CaseFileLocationId == qrt.CaseFileLocationId);
        if (weekData == null)
        {
           continue;
        }
        qrt.WeekTotalCasesEnteredCfl = weekData.TotalCasesEnteredCfl;
        qrt.WeekTotalCasesLeftCfl = weekData.TotalCasesLeftCfl;
        qrt.WeekTotalNetFeeEnteredCfl = weekData.TotalNetFeeEnteredCfl;
        qrt.WeekTotalNetFeeLeftCfl = weekData.TotalNetFeeLeftCfl;
     }

     return finalList;
  }

Примечание: я намеренно получаю данные за весь квартал сначала в виде списка, а затем работаю над ним, чтобы получить итоги за месяц и квартал, но это главным образом потому, что я не могу понятьчтобы получить конечный результат от объединенного LINQ IQuerable.

Я использую NHibernate, синтаксис метода LINQ, шаблон репозитория и SQL Server 2008

1 Ответ

1 голос
/ 10 февраля 2012

Если я правильно читаю ваш код, вы проецируете свои результаты на анонимные типы с одинаковыми результирующими членами, что упрощает объединение ваших результатов.Я недавно сделал нечто подобное с Союзом.Вот упрощенный пример, который я только что написал, чтобы продемонстрировать:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace ConsoleApplication1 {
    public class Month {
        public int MonthID { get; set; }
        public string MonthName { get; set; }
        public int NoDays { get; set; }
    }

    internal class Program {
        private static void Main(string[] args) {
            // Build up months
            var months = new List<Month>();
            for (var i = 1; i <= 12; i++) {
                months.Add(new Month {
                    MonthID = i,
                    MonthName = DateTimeFormatInfo.CurrentInfo.GetMonthName(i),
                    NoDays = DateTime.DaysInMonth(2012, i)
                });
            }

            var w = months.Select(m => new {
                m.MonthName
            });

            var x = months.Select(m => new {
                m.MonthName
            });

            var y = months.Select(m => new {
                m.MonthName
            });

            var z = w.Union(x).Union(y);

            foreach (var m in z) {
                Console.WriteLine(m.MonthName);
            }
            Console.Read();
        }
    }
}

Имейте в виду, что «Союз» (например, предложение SQL UNION) удалит любые дубликаты из вашего списка.Если вы не хотите удалять дубликаты (т.е. выполнять «объединение всех»), используйте «Concat» следующим образом:

var z = w.Concat(x).Concat(y);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...