将多个PARTITION BY转换为LINQ

时间:2017-04-13 19:13:06

标签: c# entity-framework linq

EF Core还没有SqlQuery()方法(史诗失败)所以我无法在我的数据库上运行查询/存储过程来获取“摘要”数据。以下是我需要转换为LINQ的多个PARTITION BY的摘要查询:

SELECT 
    s.Name,
    SUM(CASE WHEN pc.WorkflowStateId <> 99 THEN 1 ELSE 0 END) 
        OVER (PARTITION BY s.SiteId) 'RegisteredCount',     
    SUM(CASE WHEN pc.WorkflowStateId = 99 THEN 1 ELSE 0 END) 
        OVER (PARTITION BY s.SiteId) 'ScreenFailedCount'
FROM Sites s 
JOIN Patients p ON p.SiteId = s.SiteId 
JOIN PatientCycles pc ON pc.PatientId = p.PatientId

SitesPatientsPatientCycles是DbSets。

如何将其转换为C#LINQ查询?

更新 这是我提出的解决方案:

var summaries = from site in context.Sites
                let registered = (from pc in context.PatientCycles
                                    where site.SiteId == pc.Patient.SiteId && pc.WorkflowStateId != WorkflowStateType.Terminated
                                    select pc).Count()
                let terminated = (from pc in context.PatientCycles
                                    where site.SiteId == pc.Patient.SiteId && pc.WorkflowStateId == WorkflowStateType.Terminated
                                    select pc).Count()
                select new SiteSummary { Site = site, RegisteredCount = registered, ScreenFailedCount = terminated };

1 个答案:

答案 0 :(得分:2)

Linq的替代方案就是这样:

var query= from s in context.Sites
           join p in context.Patiens on s.SiteId equals p.SiteId
           join pc in context.PatientCycles on p.PatiendId equals p.PatiendId 
           group pc.WorkflowStateId by new{s.SiteId,s.Name} into g
           select new {Name=g.Key.Name,
                       RegisteredCount=g.Sum(e=>e!=99?1:0),
                       ScreenFailedCount=g.Sum(e=>e==99?1:0)
                      }

更新

要避免这种问题,请使用nav。属性:

var query= from s in context.Sites
           select t new SiteSummary
            {
                SiteId = s.SiteId,
                Name = s.Name,
                Code = s.Code,
                RegisteredCount =s.Patiens.SelectMany(e=>e.PatientCycles.Select(y=>y.WorkflowStateId ))
                                          .Sum(x => x!= WorkflowStateType.Terminated ? 1 : 0),
                ScreenFailedCount = s.Patiens.SelectMany(e=>e.PatientCycles.Select(y=>y.WorkflowStateId ))
                                             .Sum(x => x== WorkflowStateType.Terminated ? 1 : 0)
            };

我还建议初始化实体构造函数中的集合导航属性:

public class Sites
{
  //...
  public virtual ICollection<Patient> Patients{get;set;}
  public Sites()
  { 
    Patients=new List<Patient>();
  }
}