【问题标题】:Linq, EF Core - group by on one field and use other field to get list of data from other tableLinq,EF Core - 按一个字段分组并使用其他字段从其他表中获取数据列表
【发布时间】:2019-09-15 11:47:42
【问题描述】:

我正在尝试从 Linq 获取特定格式的输出。 这个问题已经改写了-

SQL 视图 - SomeView

编号 T_Id 4 2 6 5 6 7

SQL 表 - 用户

T_Id fname lname 2 玛丽·史密斯 5 约翰教皇 7 史蒂夫·布莱尔

SomeView 是 QueryType,我使用 DbQuery 来映射它。

公共类 SomeView { 公共 int ID {get;私人集;} 公共 int T_Id { 获取;私人套装; } 公共用户用户{获取;放; } //这里不能导航 } 公共类用户 { 公共 int T_Id { 获取;放; } 公共字符串 fname {get;放;} 公共字符串 lname{get;放;} 公共 SomeView SomeView{ 得到;放; } //这里不能导航 }

由于 SomeView 是 SQL 视图,因此数据库中没有定义外键约束。 您不能将 Navigation 与 QueryType 一起使用。所以 User 和 SomeView 之间的映射是不可能的,或者我不知道该怎么做。

公共类 SomeViewModel { 公共 int ID { 获取;放; } 公共列表用户{get;放;} } 最后我的linq正在进行中- 来自 SomeView 中的 t 按 t.Id 将新 {t} 分组到 grp 选择新的 SomeViewModel{ Id = grp.Key, 用户 = grp.Select(x => x.t.User).ToList() //此处需要帮助以根据 T_Id 获取用户 }

最终的 API 数据输出应采用以下格式。

[{ “身份证”:“4”, “用户”:[{ “T_Id”:2, “fname”:“玛丽”, “lname”:“史密斯” }] }, { “身份证”:“6”, “用户”:[{ “T_Id”:5, “fname”:“约翰”, “lname”:“教皇” }, { “T_Id”:7, “fname”:“史蒂夫”, “lname”:“布莱尔” } ] }]

【问题讨论】:

  • 您的表格暗示了从SomeTableUser多对一 关系。因此,视图模型中的List<User> Users 没有意义——SomeTable 中的每条记录都可以有 0 或 1 个 User。您最好显示 实体模型 - 使用适当的 导航属性 LINQ 查询应该是微不足道的 - 类似于 db.SomeTable.Select(t => new SomeViewModel { Id = t.Id, User = t.User })
  • 但是 SomeTable 是一个视图。不能在 QueryTypeBuilder 上使用 HasMany。
  • 修改问题。 SomeViewObj 是 QueryType 用 DbQuery 来映射的。我无法使用 QueryTypeBuilder 上的 HasMany 映射它。
  • 我的第一条评论仍然适用。 SomeViewObj 是关系的 many 方,因此您需要一个 reference 导航属性 public User User { get; set; } 映射到 HasOneT_Id 映射到 HasForeignKey .这就是我们在 EF Core 查询中访问数据的方式。如果您想要常规 LINQ,请查看 C# join clause
  • 您不能为 QueryType SQL 视图使用导航属性。我正在为上面的问题添加详细信息

标签: linq entity-framework-core


【解决方案1】:

首先,我认为您可以使用任何序列化程序将对象转换为您想要的格式。

var serialized = JsonConvert.SerializeObject(data)

其次,回到你的问题,这里是代码。但是,您需要在变量周围添加 " 并去掉我为便于阅读而添加的字符串连接。此外,此代码非常针对您的问题,对于更通用的解决方案,请使用第一种方法。

var mainData = string.Join(',', data.Select(x => $" {{ {nameof(x.Id)} :  {x.Id}, " +
                                                           $"{nameof(User)}s: " +
                                                           $"[ {string.Join(',', x.Users.Select(y => $"{{ {nameof(User.T_Id)} : {y.T_Id} }}"))}]" +
                                                           $"}}"));
var result = $"[{mainData}]" ;

当您更改问题时,我更新了答案。因此,您需要先加入 someView 和 user 以将它们组合在一起,然后按 someView.id 分组。这是代码

        var someViewsUsersJoin = someViews.Join(users, l => l.t_id, r => r.t_id, (someView, user) => new {someView, user});

        var result = someViewsUsersJoin.GroupBy(x => x.someView.id).Select(x => new SomeViewModel()
        {
            Id = x.Key,
            Users = x.Select(y => y.user).ToList()
        });

【讨论】:

  • 谢谢,但我需要有关 Linq 查询的帮助。我重新表述了我的问题,希望现在很容易理解。
【解决方案2】:

终于这样解决了——

 public class SomeView
{
   public int Id {get; private set;}
   public int T_Id { get; private set; }

}

public class User
{
   public int T_Id { get; set; }
   public string fname {get; set;}
   public string lname{get; set;}
}

public class SomeViewModel
{
   public int Id { get;  set; }
   public List<User> Users{get; set;}
}

   from t in SomeView
   join u in User on v.T_Id equals u.T_Id
   group new {t, u} by t.Id into grp
   select new SomeViewModel{
      Id = grp.Key,
      Users = grp.Select(x => x.u).ToList()
  }

这很容易:)

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多