将两个linq查询重构为一个查询

时间:2014-05-28 13:29:23

标签: linq

我有一个带有两个linq语句的方法,只有一个区别。一个查询按3个参数进行分组,另一个只按2个组进行分组。我确信有更好的方法可以将这两个linq查询重构为一个,但不确定如何?

 public List<ReportEntry> GetReportData(DateTime startDate, DateTime endDate, int companyId, bool groupByVATandPatAcc)
    {
        var results =
            from cy in _dc.Companies
            join cyv in _dc.CompanyVersions on cy.CompanyId equals cyv.CompanyId
            join cyd in _dc.CompanyDetails on cyv.CompanyVersionId equals cyd.Id
            join cd in _dc.CustomerDetails on cy.CompanyId equals cd.CompanyId
            join d in _dc.Documents on cd.CustomerId equals d.CustomerId
            join di in _dc.DocumentItems on d.DocumentId equals di.DocumentId
            join dd in _dc.DocumentDetails on di.DocDetailsId equals dd.DocumentDetailsId
            join vt in _dc.Vats on dd.VATCode equals vt.VATCode
            join a in _dc.Automobiles on d.AutomobileId equals a.AutomobileId into other2
            from o2 in other2.DefaultIfEmpty()
            join v in _dc.Vouchers on dd.DocumentDetailsId equals v.DocDetailID into other1
            from o1 in other1.DefaultIfEmpty()
            where (d.DocDate >= startDate && d.DocDate <= endDate) &&
                  (d.DocNumber > 0)
                  && (d.CompanyVersionId == cyv.CompanyVersionId)
                  && (d.isDeleted == false || d.isDeleted == null)
                  && (cy.CompanyId == companyId)
            select new
                   {
                       d.DocumentId,
                       d.DocTypeId,
                       cyd.Name,
                       dd.FisCostCenter,
                       dd.FisAccountCode,
                       dd.PatAccCode,
                       dd.VATCode,
                       cd.CustomerId,
                       cd.CustomerName,
                       d.DocNumber,
                       o2.Code,
                       d.DocDate,
                       d.GrossAmount,
                       o1.FromVoucNbr,
                       dd.VATAmount,
                       dd.NetAmount,
                       vt.VATDescr,
                       d.LastModUser,
                       d.StampValue
                   };


        // GA can have a single doc with multiple doc details 
        // Month End reports needs to SUM the multiple details into single doc
        if (groupByVATandPatAcc)
        {
            var singleDocuments = from d in results
                group d by new {d.DocumentId, d.VATCode, d.PatAccCode}
                into g
                select new
                       {
                           docId = g.Key,
                           g.First().DocTypeId,
                           g.First().DocDate,
                           g.First().Name,
                           g.First().CustomerId,
                           g.First().CustomerName,
                           g.First().DocNumber,
                           VATCode = g.First().VATCode.Trim(),
                           VATAmount = g.Sum(x => x.VATAmount),
                           NetAmount = g.Sum(x => x.NetAmount),
                           g.First().GrossAmount,
                           g.First().FisCostCenter,
                           g.First().FisAccountCode,
                           g.First().PatAccCode,
                           Code = g.First().Code.ToString(),
                           g.First().FromVoucNbr,
                           g.First().VATDescr,
                           g.First().LastModUser,
                           g.First().StampValue
                       };

            return singleDocuments.Select(
                d =>
                    new ReportEntry((Enums.DocTypes) d.DocTypeId, d.DocDate, d.Name, d.CustomerId, d.CustomerName,
                        d.DocNumber, d.VATCode.Trim(), d.VATAmount, d.NetAmount, d.GrossAmount
                        , d.FisCostCenter, d.FisAccountCode, d.PatAccCode, d.Code.ToString(), d.FromVoucNbr,
                        d.VATDescr, d.LastModUser, d.StampValue)).ToList();
        }
        else
        {
            var singleDocuments = from d in results
                                  group d by new { d.DocumentId, d.VATCode }
                                      into g
                                      select new
                                      {
                                          docId = g.Key,
                                          g.First().DocTypeId,
                                          g.First().DocDate,
                                          g.First().Name,
                                          g.First().CustomerId,
                                          g.First().CustomerName,
                                          g.First().DocNumber,
                                          VATCode = g.First().VATCode.Trim(),
                                          VATAmount = g.Sum(x => x.VATAmount),
                                          NetAmount = g.Sum(x => x.NetAmount),
                                          g.First().GrossAmount,
                                          g.First().FisCostCenter,
                                          g.First().FisAccountCode,
                                          g.First().PatAccCode,
                                          Code = g.First().Code.ToString(),
                                          g.First().FromVoucNbr,
                                          g.First().VATDescr,
                                          g.First().LastModUser,
                                          g.First().StampValue
                                      };

            return singleDocuments.Select(
                d =>
                    new ReportEntry((Enums.DocTypes)d.DocTypeId, d.DocDate, d.Name, d.CustomerId, d.CustomerName,
                        d.DocNumber, d.VATCode.Trim(), d.VATAmount, d.NetAmount, d.GrossAmount
                        , d.FisCostCenter, d.FisAccountCode, d.PatAccCode, d.Code.ToString(), d.FromVoucNbr,
                        d.VATDescr, d.LastModUser, d.StampValue)).ToList();
        }
    }

1 个答案:

答案 0 :(得分:0)

这应该有用吗?

// The original query with filters
var results = ...

// Group by 3 or 2 fields
results = groupByVATandPatAcc
    ? results.GroupBy(d => new { d.DocumentId, d.VATCode, d.PatAccCode });
    : results.GroupBy(d => new { d.DocumentId, d.VATCode });

// Return list
return results.Select(g => new ReportEntry(
      g.First().DocTypeId,
      g.First().DocDate,
      g.First().Name,
      g.First().CustomerId,
      g.First().CustomerName,
      g.First().DocNumber,
      VATCode = g.First().VATCode.Trim(),
      VATAmount = g.Sum(x => x.VATAmount),
      NetAmount = g.Sum(x => x.NetAmount),
      g.First().GrossAmount,
      g.First().FisCostCenter,
      g.First().FisAccountCode,
      g.First().PatAccCode,
      Code = g.First().Code.ToString(),
      g.First().FromVoucNbr,
      g.First().VATDescr,
      g.First().LastModUser,
      g.First().StampValue))
    .ToList();