LINQ:等同于PostgreSql中的string_agg

时间:2017-04-07 09:24:32

标签: c# entity-framework linq npgsql

我需要将多个列值连接到单个值(例如用逗号分隔)。我可以在PostgreSql中通过string_agg(u.name, ',') as Users来完成。我尝试在linq查询语法中执行此操作,但是我失败了 - 所有时间我只获得带有拆分值的列表,而不是一行,其值在一个字段中连接。

我们假设我只有三张桌子:

Doc                            User                 Doc_User
+----+--------------------+    +----+-----------+   +----+-----------+
| Id | Path               |    | Id | Name      |   | DocId | UserId |   
+----+--------------------+    +----+-----------+   +----+-----------+    
|  1 | "C:\\Files\\A.txt" |    |  1 | "Adam"    |   |  1    | 1      |   
|  2 | "C:\\Files\\B.txt" |    |  2 | "Benny"   |   |  1    | 2      |    
|  3 | "C:\\Files\\C.txt" |    |  3 | "Charlie" |   |  2    | 1      | 
+----+--------------------+    +----+-----------+   |  2    | 2      |
                                                    |  2    | 3      |
                                                    +-------+--------+

一开始我正在尝试简单的加入:

var model = (from d in db.Docs
                  join du in db.DU on d.Id equals du.DocId
                  join u in db.Users on du.UserId equals u.Id
                  select new DataModel() { DocPath = d.Path, UserName = u.Name }).ToList();

我怀疑我得到了分隔行的列表:

C:\Files\A.txt | Adam 
C:\Files\A.txt | Benny 
C:\Files\B.txt | Adam
C:\Files\B.txt | Benny 
C:\Files\B.txt | Charlie

但我想获得的是:

C:\Files\A.txt | Adam, Benny
C:\Files\B.txt | Adam, Benny, Charlie
EF无法识别

string.Join(),我无法在linq查询中使用它,Aggregate()也无法正常工作。我怎样才能做到这一点?

我已准备好玩它的例子:.Net Fiddle

1 个答案:

答案 0 :(得分:1)

下面的代码groups使用LINQ按路径分隔公共文档,然后使用string.Join加入分组文档的UserNames。如果您打算使用此解决方案,我也认为您在此行ToList()中不需要select new DataModel() { DocPath = d.Path, UserName = u.Name }).ToList();,因为我们将再次使用LINQ。

var grouped = model.GroupBy(x => x.DocPath);
foreach (var iGrouped in grouped){
    string.Join(",",iGrouped.Select(x => x.UserName));
    Console.WriteLine(iGrouped.Key + " | " + string.Join(",",iGrouped.Select(x => x.UserName)));
}