【问题标题】:convert SQL query with multiple join on multiple tables using group by on multiple columns and with aggregate function into LINQ使用多列上的 group by 和聚合函数将 SQL 查询与多个表上的多个连接转换为 LINQ
【发布时间】:2017-06-30 05:19:39
【问题描述】:

请帮我把下面的查询转换成 LINQ 语法。

select am.areaid, am.AreaName, MAX(am.pincode),count(ua.ApartmentID) from areamaster am 
inner join MerchantServiceAreas msa on am.areaid = msa.areaid
left join apartmentmaster apm on am.areaid = apm.areaid
left join useraddress ua on apm.apartmentid = ua.apartmentid
group by am.areaid,am.areaname

我尝试了以下语法但不起作用

(from ar in Entities.AreaMasters
    join mrs in Entities.MerchantServiceAreas on ar.AreaID equals mrs.AreaID

    join ap in Entities.ApartmentMasters on mrs.AreaID equals ap.AreaID into apl
    from ap1 in apl.DefaultIfEmpty()

    join ua in Entities.UserAddresses on ap1.ApartmentID equals ua.ApartmentID into ual
    from ua1 in ual.DefaultIfEmpty()

    where mrs.MerchantID == MerchantID
    group ar 
    by new
    {
      ar.AreaID,
      ar.AreaName,
      ar.Pincode
    } into uag
    select new AreaComplex
    {
      AreaID = uag.Key.AreaID,
      AreaName = uag.Key.AreaName,
    }).ToList();

【问题讨论】:

  • 什么不起作用?意外结果、异常?
  • 意外结果
  • 那么请描述更多。解释您的数据是什么样的、您目前正在获得什么以及您期望获得什么
  • ORM 用于执行报告查询。将此报告查询转换为 LINQ 是个坏主意。您需要所有这些代码这一事实是一个非常非常强烈的警告,表明您做错了
  • 至少创建一个隐藏连接并仅显示报告所需列的视图。将 EF 映射到该查询,因此您可以创建一个不需要任何连接的简单 LINQ 查询。

标签: c# asp.net-mvc entity-framework linq sql-server-2008


【解决方案1】:

在您的分组中删除 ar.Pincode

   group ar 
    by new
    {
      ar.AreaID,
      ar.AreaName,
      ***ar.Pincode***
    } into uag

【讨论】:

    【解决方案2】:

    试试这个语法,

    (from am in Entities.AreaMasters.GetQueryable()
     join msa in Entities.MerchantServiceAreas.GetQueryable()
    .Where(a=> a.MerchantID == MerchantID) on am.AreaID equals msa.AreaID
    join apm in Entities.ApartmentMasters.GetQueryable() on am.AreaID equals 
    apm.AreaID into apmjoin from apmlj into apmjoin.DefaultIfEmpty()
    join ua in Entities.UserAddresses.GetQueryable() on apmlj.ApartmentID equals 
    ua.ApartmentID into uajoin from ualj in uajoin.DefaultIfEmpty()
    select new { newAreaID = am.AreaID,newAreaName =  am.AreaName, newPincode= 
    am.Pincode})
    .GroupBy(a=> new {AreaID = a.newAreaID,AreaName = a.newAreaName,Pincode= 
    a.newPincode})
    .Select(x=> new AreaComplex { AreaID = x.FirstOrDefault().AreaID,
    AreaName = x.FirstOrDefault().AreaName,Pincode = x.Sum(a=>a.Pincode) }).toList();
    

    【讨论】:

    • 它只是实体的一个实例,如果我们应用GetQueryable(),那么它就会变成IQueryable,否则你也不能使用Where()
    • 除非你坐在 OP 旁边,否则你怎么知道?在any LINQ to EF 查询中,这些是Queryables。事实上,OP 的查询已经 不需要任何GetQueryable() 方法
    • DbSetIQueryable 都没有 GetQueryable 方法。其他不相关的类,例如 QueryableFilterUserControl 或 QueryExtender 控件使用的表达式类。当您已经可以访问上下文时,这些都不是必需的
    【解决方案3】:

    试用代码:

    var result=  (from ar in Entities.AreaMasters
    join mrs in Entities.MerchantServiceAreas on ar.AreaID equals mrs.AreaID
    
    join ap in Entities.ApartmentMasters on mrs.AreaID equals ap.AreaID into apl
    from ap1 in apl.DefaultIfEmpty()
    
    join ua in Entities.UserAddresses on ap1.ApartmentID equals ua.ApartmentID into ual
    from ua1 in ual.DefaultIfEmpty()
    
    where mrs.MerchantID == MerchantID
    group new { ar,mrs,ap1,ua1 }
    by new
    {
      ar.AreaID,
      ar.AreaName      
    } into uag
    select new AreaComplex
    {
      AreaID = uag.FirstOrDefault().ar.AreaID,
      AreaName = uag.FirstOrDefault().ar.AreaName,
      Pincode=  uag.Max(c=>c.ar.pincode),
      Pincode=  uag.Count(c=>c.ua1.ApartmentID),
    }).ToList();
    

    【讨论】:

    • .AsEnumerable() 执行由 IQueryable 表示的查询。您调用它 4 次,导致执行 4 次。
    猜你喜欢
    • 2017-06-08
    • 1970-01-01
    • 2021-09-26
    • 2017-09-16
    • 2013-02-22
    • 2013-12-31
    • 2021-07-11
    • 1970-01-01
    • 2013-06-28
    相关资源
    最近更新 更多