Linq,EF Core - 按一个字段分组并使用其他字段从其他表中获取数据列表
Posted
技术标签:
【中文标题】Linq,EF Core - 按一个字段分组并使用其他字段从其他表中获取数据列表【英文标题】:Linq, EF Core - group by on one field and use other field to get list of data from other table 【发布时间】:2019-09-15 11:47:42 【问题描述】:我正在尝试从 Linq 获取特定格式的输出。 这个问题已经改写了-
SQL 视图 - SomeView
编号 T_Id 4 2 6 5 6 7SQL 表 - 用户
T_Id fname lname 2 玛丽·史密斯 5 约翰教皇 7 史蒂夫·布莱尔SomeView 是 QueryType,我使用 DbQuery 来映射它。
公共类 SomeView 公共 int ID get;私人集; 公共 int T_Id 获取;私人套装; 公共用户用户获取;放; //这里不能导航 公共类用户 公共 int T_Id 获取;放; 公共字符串 fname get;放; 公共字符串 lnameget;放; 公共 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”:“布莱尔” ] ]【问题讨论】:
您的表格暗示了从SomeTable
到User
的多对一 关系。因此,视图模型中的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;
映射到 HasOne
和 T_Id
映射到 HasForeignKey
.这就是我们在 EF Core 查询中访问数据的方式。如果您想要常规 LINQ,请查看 C# join clause
您不能为 QueryType SQL 视图使用导航属性。我正在为上面的问题添加详细信息
【参考方案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 lnameget; set;
public class SomeViewModel
public int Id get; set;
public List<User> Usersget; 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()
这很容易:)
【讨论】:
以上是关于Linq,EF Core - 按一个字段分组并使用其他字段从其他表中获取数据列表的主要内容,如果未能解决你的问题,请参考以下文章
C# LINQ NET 3.5 SP1:使用 LINQ 按两个字段分组,并为组的所有成员分配一个相关的唯一 ID(整数)