LINQ 中的 LISTAGG 等效项不起作用

问题描述 投票:0回答:1

我有一个 SQL 查询

SELECT  
    M.EMPLOYEEID, LISTAGG(L.NAME, ',') WITHIN GROUP (ORDER BY L.NAME) AS Locations
FROM
    EMPLOYEEOFFICES M 
LEFT JOIN 
    OFFICELIST L ON M.OFFICELISTID = l.officelistid 
GROUP BY 
    M.EMPLOYEEID

我正在尝试运行的 Linq 等效项:

var empOfficeLocations = (from om in _dbContext.EMPLOYEEOFFICES 
                          join ol in _dbContext.Officelists
                                  on om.Officelistid equals ol.Officelistid into grps
                          from grp in grps
                          group grp by om.Employeeid into g
                          select new
                                 {
                                     EmployeeId = g.Key,
                                     Locations = string.Join(",", g.Select(x => x.Name))
                                 }).ToList();

我尝试了上述 LINQ 的多个版本,但没有任何运气。

我得到的错误:

LINQ 表达式“GroupByShaperExpression”的处理:
键选择器:e.EMPLOYEEID,
元素选择器:ProjectionBindingExpression:EmptyProjectionMember
通过“RelationalProjectionBindingExpressionVisitor”失败。这可能表明实体框架中存在错误或限制。请参阅 https://go.microsoft.com/fwlink/?linkid=2101433 了解更多详细信息。

翻译:

Compiling query expression:
      'DbSet<EMPLOYEEOFFICES>()
          .Join(
              inner: DbSet<Officelist>(),
              outerKeySelector: e => e.Officelistid,
              innerKeySelector: o => o.Officelistid,
              resultSelector: (e, o) => new {
                  e = e,
                  o = o
               })
          .GroupBy(
              keySelector: <>h__TransparentIdentifier0 => <>h__TransparentIdentifier0.e.Employeeid,
              elementSelector: <>h__TransparentIdentifier0 => <>h__TransparentIdentifier0.o.Name)
          .Select(g => new {
              EMPLOYEEID = g.Key,
              Locations = string.Join(
                  separator: ", ",
                  values: g)
           })

我想要的结果很简单:

员工ID 地点
emp1 loc1,loc2
emp2 loc1,loc3,loc4

我搜索过 Stackoverflow,尝试过 chat gpt;内存版本似乎可以工作,但是在数据库上下文中尝试相同的代码,一切都会崩溃。

PS:使用的数据库是Oracle数据库,版本11g

我怎样才能让它发挥作用?我不想在内存中执行此操作。

c# linq linq-to-sql entity-framework-6 listagg
1个回答
0
投票

我以不同的方式重建。你想尝试使用正确的_dbContext吗? 第一部分是你的

void Main()
{

    var EMPLOYEEOFFICES = new List<EMPLOYEEOFFICE>();
    EMPLOYEEOFFICES.Add(new EMPLOYEEOFFICE() { Employeeid = 1, Officelistid = 1 });
    EMPLOYEEOFFICES.Add(new EMPLOYEEOFFICE() { Employeeid = 1, Officelistid = 2 });
    EMPLOYEEOFFICES.Add(new EMPLOYEEOFFICE() { Employeeid = 2, Officelistid = 1 });
    EMPLOYEEOFFICES.Add(new EMPLOYEEOFFICE() { Employeeid = 2, Officelistid = 3 });
    EMPLOYEEOFFICES.Add(new EMPLOYEEOFFICE() { Employeeid = 2, Officelistid = 4 });

    var Officelists = new List<Officelist>();
    Officelists.Add(new Officelist() { Officelistid = 1, Name = "loc 1" });
    Officelists.Add(new Officelist() { Officelistid = 2, Name = "loc 2" });
    Officelists.Add(new Officelist() { Officelistid = 3, Name = "loc 3" });
    Officelists.Add(new Officelist() { Officelistid = 4, Name = "loc 4" });

    var empOfficeLocations = (from om in EMPLOYEEOFFICES
                              join ol in Officelists
                                      on om.Officelistid equals ol.Officelistid into grps
                              from grp in grps
                              group grp by om.Employeeid into g
                              select new
                              {
                                  EmployeeId = g.Key,
                                  Locations = string.Join(",", g.Select(x => x.Name).ToList())
                              }).ToList();
    empOfficeLocations.Dump();


    EMPLOYEEOFFICES
        .Join(
            Officelists,
            emp => emp.Officelistid,
            ol => ol.Officelistid,
            (ol, emp) => new { Officelists = ol, empOfficeLocations = emp }
        )
        .Select(s => new
        {
            s.Officelists.Employeeid,
            s.empOfficeLocations
        })
        .GroupBy(g => g.Employeeid)
        .Select(r => new {
            r.Key, 
            Locations = string.Join(", ", r.Select(m=> m.empOfficeLocations.Name).ToList())})
        .Dump();

}



public class EMPLOYEEOFFICE{
    public int Officelistid {get;set;}
    public int Employeeid {get;set;}
    
}

public class Officelist{
    public int Officelistid {get;set;}
    public string Name {get;set;}
    
}
© www.soinside.com 2019 - 2024. All rights reserved.