【问题标题】:How to flatten an SQL join with collection using LINQ query?如何使用 LINQ 查询将 SQL 连接与集合展平?
【发布时间】:2020-04-29 22:01:56
【问题描述】:

假设我有两个表:Users 和 UserRoles:

Users:
+----+
| Id |
+----+
|  1 |
|  2 |
|  3 |
+----+

UserRoles:
+--------+----------+
| UserId | Name     |
+--------+----------+
|      1 | A        |
|      1 | B        |
|      2 | A        |
|      3 | C        |
+--------+----------+

我需要能够将上述数据选择到如下所示的用户对象列表中:

class User
{
   public int Id { get; set; }
   public List<string> Roles { get; set; }
}

我能想到的最好的方法如下,但它最终会生成一个嵌套的 select 语句,我不知道这是否会影响性能:

List<Device> usersWithRoles = from user in Users
   select new Device
   {
      Id = user.Id,
      Roles = (from role in UserRoles where role.UserId == user.Id select role.Name).ToList()
   }.ToList();

有没有更好(更高效)的方法来实现这一点?例如加入,我在想这样的事情,但不知道如何从加入中填充角色:

List<Device> usersWithRoles = from user in Users
   join user_role in UserRoles on user.Id equals user_role.UserId
   select new Device
   {
      Id = user.Id,
      Roles = ??? // how do I populate this
   }.ToList();

谢谢。

【问题讨论】:

  • 您使用的是 EF 吗?如果是这种情况,您应该通过 UserRole 关系在用户及其关联角色之间创建关系。这是 EF 的基本部分,它可以轻松处理,因此您不必处理复杂的分组或连接逻辑。
  • @silkfire 我正在使用 EF。问题是有一堆没有外键定义的遗留表,无法触及数据库。此外,这只是更大查询的一小部分。我假设您建议我可以使用导航属性执行 Roles = user.Roles 之类的操作?
  • 没错。所以你无权访问数据库本身?我会尝试在您的数据层中使用经典的 SQL + LINQ。
  • 在 LINQ to SQL 中,可以通过在 join 上使用 into 创建 GroupJoin

标签: c# linq linq-to-sql linq-to-entities


【解决方案1】:

使用GroupJoinLINQ to SQL 方法:

List<Device> usersWithRoles = from user in Users
   join user_role in UserRoles on user.Id equals user_role.UserId into roles
   select new Device
   {
      Id = user.Id,
      Roles = roles.ToList()
   }.ToList();

【讨论】:

  • 很酷,'into' 是我缺少的部分(尽管在将其分配给角色时,我仍然必须在角色上调用 'ToList()')。
  • @Eternal21 对不起,是的,这是因为类中 Roles 的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2021-06-21
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多