如何使用Linq创建包含集合的唯一Collection

时间:2017-02-21 14:21:37

标签: c# linq

我正在从数据库中检索记录并创建以下对象:

       public class RemittanceBatchProcessingModel
      {
            public string FileId { get; set; }
            public string SourceFileName { get; set; }
            public string BatchCode { get; set; }
            public string BatchType { get; set; }
            public decimal PaymentAmount { get; set; }
            public string BillingSystemCode { get; set; }
       }

db read之后创建的示例对象:

FileId | SourceFileName | BatchCode | BatchType | PaymentAmt |BillingCode
    1  | test.file1.txt | 100       | S         | 1000.00    | Exc
    1  | test.file1.txt | 100       | S         | 2000.00    | Exc 
    1  | test.file1.txt | 200       | N         |  500.00    | Adc 
    2  | test.file2.txt | 300       | S         | 1200.00    | Exc 
    2  | test.file2.txt | 300       | S         | 1500.00    | Exc 

我想创建一个对象,该对象具有一组唯一文件,这些文件包含文件中每个汇总批处理的集合。例如,

  Collection of Unique Files:
FileId | SourceFileName | BatchCode | BatchType | BatchTotal |RecordCount
    1  | test.file1.txt | 100       | S         | 3000.00    | 2
    1  | test.file1.txt | 200       | N         |  500.00    | 1
    2  | test.file2.txt | 100       | S         | 1700.00    | 2

我能够创建我的批次集合而没有问题我正在弄清楚如何创建具有正确批次的唯一文件集合。我尝试使用以下内容:

    private static RemittanceCenterFilesSummaryListModel SummarizeFiles(RemittanceCenterSummaryListModel remittanceCenterSummaryListModel)
    {
       var summarizedBatches = SummarizeBatches(remittanceCenterSummaryListModel);

                   var fileResult = remittanceCenterSummaryListModel.RemittanceBatchSummaryRecord.GroupBy(x => new { x.FileId, x.SourceFileName })
            .Select(x => new RemitanceCenterFileSummarizedModel()
            {
                FileId = x.Key.FileId,
                SourceFileName = x.Key.SourceFileName,
                ScannedBatchCount = x.Count(y => y.BatchType == "S"),
                ScannedBatchAmount = x.Where(y => y.BatchType == "S").Sum(y => y.PaymentAmount),
                NonScannedBatchCount = x.Count(y => y.BatchType != "S"),
                NonScannedBatchAmount = x.Where(y => y.BatchType != "S").Sum(y => y.PaymentAmount),
            });

        var summaryListModel = CreateSummaryFilesListModel(fileResult);
        summaryListModel.Batches = summarizedBatches.RemittanceBatchSummary; 
        return summaryListModel;
    }
    private static RemittanceCenterFilesSummaryListModel CreateSummaryFilesListModel(IEnumerable<RemitanceCenterFileSummarizedModel> summaryModels)
    {
        var summaryModelList = new RemittanceCenterFilesSummaryListModel();

        foreach (var summaryFileRec in summaryModels)
        {
            var summaryModel = new RemitanceCenterFileSummarizedModel
            {
                FileId = summaryFileRec.FileId.ToString(CultureInfo.InvariantCulture),
                SourceFileName = summaryFileRec.SourceFileName.ToString(CultureInfo.InvariantCulture),
                ScannedBatchCount = summaryFileRec.ScannedBatchCount,
                ScannedBatchAmount = summaryFileRec.ScannedBatchAmount,
                NonScannedBatchCount = summaryFileRec.NonScannedBatchCount,
                NonScannedBatchAmount = summaryFileRec.NonScannedBatchAmount
            };

            summaryModelList.RemittanceFilesSummary.Add(summaryModel);
        }

        return summaryModelList;
    }

3 个答案:

答案 0 :(得分:0)

您也可以将其分为4列,包括BatchTypeBatchCode,然后选择Count并将金额汇总为:

 var fileResult = remittanceCenterSummaryListModel.RemittanceBatchSummaryRecord
                     .GroupBy(x => new 
                                  { 
                                    x.FileId,
                                    x.SourceFileName,
                                    x.BatchType,
                                    x.BatchCode 
                                  })
                     .Select(x => new
                                 {
                                   FileId = x.Key.FileId,
                                   SourceFileName = x.Key.SourceFileName,
                                   BatchType = x.Key.BatchType,
                                   BatchCode = x.Key.BatchCode,
                                   BatchTotal= x.Sum(y=>y.PaymentAmt),
                                   RecordCount = x.Count()
                             });

答案 1 :(得分:0)

我猜你需要GroupBy FileId&amp; BatchType代替FileName: -

var fileResult = remittanceCenterSummaryListModel.RemittanceBatchSummaryRecord
            .GroupBy(x => new { x.FileId, x.BatchType })
            .Select(x => 
            { 
                var firstObj = x.FirstOrDefault();
                return new RemitanceCenterFileSummarizedModel()
                { 
                   FileId = x.Key.FileId,
                   SourceFileName = firstObj.SourceFileName,
                   BatchCode = firstObj.BatchCode,
                   BatchType  = x.Key.BatchType,
                   BatchTotal  = x.Sum(z => z.PaymentAmt),
                   RecordCount = x.Count()
                };
            });

考虑将FileId映射到SourceFileName&amp; BatchCode映射到BatchType您可以将第一个集合存储在变量中,就像我在firstObj中一样,以获取未分组的相关值。请在访问相关属性之前检查空值,因为如果未找到任何设置,可能会导致 NRE

答案 2 :(得分:0)

纯粹的linq非流利

 var files = new[] { 
                new { FileId = 1, SourceFileName =  "test.file1.txt" , BatchCode = 100 , BatchType = "S", PaymentAmt = 1000.00 , BillingCode = "Exc" },
                new { FileId = 1, SourceFileName =  "test.file1.txt" , BatchCode = 100 , BatchType = "S", PaymentAmt = 2000.00 , BillingCode = "Exc" },
                new { FileId = 1, SourceFileName =  "test.file1.txt" , BatchCode = 200 , BatchType = "N", PaymentAmt = 500.00 , BillingCode = "Adc" },
                new { FileId = 1, SourceFileName =  "test.file2.txt " , BatchCode = 300 , BatchType = "S", PaymentAmt = 1200.00 , BillingCode = "Exc" },
                new { FileId = 1, SourceFileName =  "test.file2.txt " , BatchCode = 300 , BatchType = "S", PaymentAmt = 1500.00 , BillingCode = "Exc" }
            };

            var result = from file in files
                         group file by new { file.FileId, file.BatchCode } into fileBachGroups
                         select new 
                         { 
                             FileId = 1, 
                             SourceFileName = fileBachGroups.First().SourceFileName, 
                             BatchCode = fileBachGroups.Key.BatchCode,
                             BatchType = fileBachGroups.First().BatchType,
                             BatchTotal = fileBachGroups.Sum(f => f.PaymentAmt),
                             RecordCount = fileBachGroups.Count()
                         };

            Console.WriteLine("FileId | SourceFileName | BatchCode | BatchType | BatchTotal |RecordCount");

            foreach (var item in result)
            {
                Console.WriteLine("{0} | {1} | {2} | {3} | {4} | {5}",item.FileId,item.SourceFileName, item.BatchCode, item.BatchType, item.BatchTotal, item.RecordCount);
            }