LINQ将前5行转移到列

时间:2015-07-26 13:34:10

标签: c# linq

所需的输出是一组行,其中包含有关医生的详细信息以及他们执行的前5个程序(按体积计算),这些程序不在我们的基准测试表中 - 每月至少一个。即使我有限的LINQ经验,我已经设法让这个工作,但表现糟透了。本着在LINQ上变得更好的精神,我想我会看到是否有更好的方法来解决这个问题(除了在SQL中编码)。

这是整个方法,虽然我认为这是最后的声明(var report =)值得最多关注。

//Get the Providers for the selected AccessLevel & Report Period
var providerRiskLevels = GetProviderRiskLevelForAccessLevel(userAccessLevelId, reportPeriodId, providerNamePiece);

short benchmarkYear = (
        from rp in db.ReportPeriods
        where rp.ReportPeriodId == reportPeriodId
        select rp.BenchmarkDataYear
        ).FirstOrDefault();

byte Duration = (
        from rp in db.ReportPeriods
        where rp.ReportPeriodId == reportPeriodId
        select rp.Duration
        ).FirstOrDefault();

//Summarize counts by procedure code (ignoring modifiers)
var codeCounts =
    from pp in db.ProviderProductions
    //332 - restrict to valid codes
    join pc in db.ProcedureCodes on pp.ProcedureCode equals pc.ProcedureCode1
    where pp.ReportPeriodId == reportPeriodId
        //show deleted codes as potential issue
        && pc.TerminatedDate == null
        && (codeFilter == null || pp.ProcedureCode == codeFilter)
    join pc in db.PspsProcedures
        on new { col1 = pp.ProcedureCode, col2 = benchmarkYear } equals new { col1 = pc.ProcedureCode, col2 = pc.Year } into left
    from l_d in left.DefaultIfEmpty()
    where l_d == null
    group pp by
        new { pp.ProviderId, pp.ProcedureCode }
        into g
        orderby g.Key.ProviderId, g.Sum(x => x.Volume) descending
        where g.Sum(x => x.Volume) > Duration
        select new NewCodesEntity
        {
            ProviderId = g.Key.ProviderId,
            ProcedureCode = g.Key.ProcedureCode,
            Volume = g.Sum(x => x.Volume)
        };

//Get top 5 procedures performed by provider
var newCodes =
    from cc in codeCounts
    group cc by
        new { cc.ProviderId }
        into g
        select new ProviderNewCodesEntity
        {
            ProviderId = g.Key.ProviderId,
            Codes = g.OrderByDescending(x => x.Volume).Take(5).ToList()
        };

//Build the report
var report =
    from pr in providerRiskLevels
    join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
    where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
        && (filterRiskLevelNums.Contains(pr.RiskLevelNum))
        && (filterSpecialtyId == 0 || pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
    select new ProbeAuditEntity
    {
        ProviderId = pr.Provider.ProviderId,
        ProviderName = pr.Provider.Name,
        ProviderCode = pr.Provider.ProviderCode,
        SpecialtyName = pr.Provider.Specialty.Name,
        SpecialtyCode = pr.Provider.Specialty.SpecialtyCode,
        VisibleRisk = pr.RiskScore,
        NewCode1 = nc.Codes.OrderByDescending(c => c.Volume).FirstOrDefault().ProcedureCode,
        NewCode2 = nc.Codes.OrderByDescending(c => c.Volume).Skip(1).FirstOrDefault().ProcedureCode,
        NewCode3 = nc.Codes.OrderByDescending(c => c.Volume).Skip(2).FirstOrDefault().ProcedureCode,
        NewCode4 = nc.Codes.OrderByDescending(c => c.Volume).Skip(3).FirstOrDefault().ProcedureCode,
        NewCode5 = nc.Codes.OrderByDescending(c => c.Volume).Skip(4).FirstOrDefault().ProcedureCode
    };
return report;

感谢您的建议。

1 个答案:

答案 0 :(得分:0)

尝试报告:

//Build the report
var report =
    (from pr in providerRiskLevels
    join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
    where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
        && filterRiskLevelNums.Contains(pr.RiskLevelNum)
        && (filterSpecialtyId == 0 
            || pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
    select new 
    {
        RiskLevel = pr,
        NewCodes = nc.Codes.OrderByDescending(c => c.Volumn).Select(c => c.ProcedureCode).Take(5)
    })
    .AsEnumerable()
    .Select(x => new ProbeAuditEntity
    {
        ProviderId = x.RiskLevel.Provider.ProviderId,
        ProviderName = x.RiskLevel.Provider.Name,
        ProviderCode = x.RiskLevel.Provider.ProviderCode,
        SpecialtyName = x.RiskLevel.Provider.Specialty.Name,
        SpecialtyCode = x.RiskLevel.Provider.Specialty.SpecialtyCode,
        VisibleRisk = x.RiskLevel.RiskScore,
        NewCodes = x.NewCodes.Concat(Enumerable.Repeat(<DefaultProcedureCodeHere>, 5)).Take(5)
    });

或者,如果ProbeAuditEntity是一个类,你可以这样做:

//Build the report
var report =
    (from pr in providerRiskLevels
    join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
    where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
        && filterRiskLevelNums.Contains(pr.RiskLevelNum)
        && (filterSpecialtyId == 0 
            || pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
    select new ProbeAuditEntity
    {
        ProviderId = x.RiskLevel.Provider.ProviderId,
        ProviderName = x.RiskLevel.Provider.Name,
        ProviderCode = x.RiskLevel.Provider.ProviderCode,
        SpecialtyName = x.RiskLevel.Provider.Specialty.Name,
        SpecialtyCode = x.RiskLevel.Provider.Specialty.SpecialtyCode,
        VisibleRisk = x.RiskLevel.RiskScore,
        NewCodes = nc.Codes.OrderByDescending(c => c.Volumn).Select(c => c.ProcedureCode).Take(5)
    })
    .ToList();

report
.ForEach(x => x.NewCodes = x.NewCodes.Concat(Enumerable.Repeat(<DefaultProcedureCodeHere>, 5)).Take(5);