@@linq left join group

发布时间 2023-06-02 19:19:15作者: dreamw

@@linq left join group

如何实现LINQ的left join group by语法?

 

在LINQ下这样写

var query = (from st in db.Student
                             join sc in db.Score on st.id equals sc.sid into g1
                             from in g1.DefaultIfEmpty()
                             group new { st, t } by new { st.id, st.name, t.sid } into g2
                             select new result()
                             {
                                 id = g2.Key.id,
                                 name = g2.Key.name,
                                 list = g2.Where(s => s.t != null).Select(s => new ScoreDto() { id = s.t.id, score = s.t.score })
                             }).OrderBy(o => o.id).ToList();

结果如下:

1656922529395.png

[
  {
    "id": 1,
    "name""张三",
    "list": [
      {
        "id": 1,
        "score": 90.00
      }
    ]
  },
  {
    "id": 2,
    "name""李四",
    "list": [
      {
        "id": 7,
        "score": 70.00
      },
      {
        "id": 11,
        "score": 75.00
      }
    ]
  },
  {
    "id": 3,
    "name""王五",
    "list": [
      {
        "id": 13,
        "score": 60.00
      }
    ]
  },
  {
    "id": 4,
    "name""TOM",
    "list": []
  },
  {
    "id": 5,
    "name""Lucy",
    "list": []
  }
]

 

SqlSugar中如何实现呢?

 

 

热忱回答(14

  • fate stafate sta VIP0
    2022/7/4

    你可以看一下thenmapper写法,先用一个普通的group select然后在查二级对象

     0  回复
  • fate stafate sta VIP0
    2022/7/4
    var list = db.Queryable<StudentA>().ToList();//这儿也可以联表查询
    db.ThenMapper(list, stu =>
    {
      //如果加Where不能带有stu参数,stu参数写到 SetContext
      stu.SchoolA=db.Queryable<SchoolA>().SetContext(scl=>scl.SchoolId,()=>stu.SchoolId,stu).FirstOrDefault();
       
      //可以联查询的
      //stu.xxxx=db.Queryable<SchoolA>().LeftJoin<XXX>().Select(xxxx).SetContext(....).ToList();
    });
    // SetContext不会生成循环操作,高性能  和直接Where性能是不一样的

     

     0  回复
  • @fate sta:

    我用了ThenMapper报错了,我的业务需求是这样的,我有一张日志表R,里面记录了所有设备的每小时整点的情况。

    比如

    DeviceId DataTime value

    D001       2022-06-01 09:00 30

    D002       2022-06-01 09:00 35

    D001       2022-06-01 10:00 20

    大概是这样的一个结构

    现在需要根据传入的查询参数:时间范围,设备编号列表

    得到每个时间范围内每个整点,所选设备的情况。

    比如

    image.png

    我是这样写的,但是现在报错,提示有语法错误。

    1. 1.首先让时间范围内的日期时间列表分页

    2. 2.让所选设备的列表和记录表R左连接查询,保证每个整点中的设备都是有记录的,只是记录结果可能为空。

                            DateTime dtStartTime = strStartTime.ToDate();
                            DateTime dtEndTime = strEndTime.ToDate();
                            var hours = (int)(dtEndTime.AddHours(1) - dtStartTime).TotalHours;
                            var hourArray = Enumerable.Range(0, hours).Select(it => dtStartTime.AddHours(it)).ToList();
                            //获取小时分页列表
                            data = _db.Reportable(hourArray).ToQueryable<DateTime>().Select(s => new LCS_DataSiteReportOutput()
                            {
                                DateTime = s.ColumnName.ToString("yyyy-MM-dd HH:mm:00")
                            }).OrderBy("ColumnName " + input.sort).ToPagedList(input.currentPage, input.pageSize);
                            //获取设备列表
                            var queryDevices = _db.Reportable(input.DeviceId).ToQueryable<string>();
                            //获取每个小时设备明细数据
                            _db.ThenMapper(data.list, res =>
                            {
                                res.list = queryDevices.LeftJoin(_db.Queryable<LCS_HourDataRecordEntity>(), (d, s) => d.ColumnName == s.DeviceId)
                                .Select((d, s) => new LCS_DataSiteReportListOutput()
                                {
                                    DateTime = s.DataTime.Value.ToString("yyyy-MM-dd HH:mm:00"),
                                    DeviceId = s.DeviceId,
                                    Value=s.Value
                                }).SetContext(d => d.DateTime, () => res.DateTime, res).ToList();
                            });

     

    image.png

     

    现在报错提示如下

    image.png

     0  回复
  • 加了as之后,倒是不报这个错误了,但是变了其他错误信息

    image.png

    同时发现一个奇怪的事情,代码中的使用(d, s)会提示别名不一致,我查看了生成的SQL语句发现,别名是用的t,于是换成(t, s)就好了

     0  回复
  • image.png

     0  回复
  • fate stafate sta VIP0
    2022/7/5

    @摇曳的风筝: As<string>(xxx) 全部删掉,他不是一个表你AS什么

     0  回复
  • @fate sta:没加as这里会报错的,LEFT 左边是一个包起来的子查询,但是没有使用别名,导致这里报LEFT语法错误。

     0  回复
  • fate stafate sta VIP0
    2022/7/5

    直接.LeftJoin<表>()

     0  回复
  • @fate sta:image.png

    会报这个错误

     0  回复
  • image.png

    直接修改SQL语句加个别名好了

     

     

     0  回复
  •  

    这样写会导致LEFT语法错误

    image.png

     0  回复
  • fate stafate sta VIP0
    2022/7/5

    image.png

     

    我这边用最新版本测试可以

     0  回复
  • @fate sta:升级到最新版之后,确实不报错了,生成的语句也对了

    image.png

     

     

    但是,出现一个新的错误

    image.png

     0  回复
  • @fate sta:

    没有什么是循环不能解决的,如果有,就再循环一次。哈哈哈

    image.png

     

     

    转 https://www.donet5.com/ask/9/16286