如何用 linq to EF 填充我的类对象?
Posted
技术标签:
【中文标题】如何用 linq to EF 填充我的类对象?【英文标题】:How to populate my class object with linq to EF? 【发布时间】:2020-08-30 18:28:04 【问题描述】:我的班级,
public class User
public string Username
get;
set;
public string Password
get;
set;
public string [] Roles
get;
set;
我的查询是,
var innerJoinQuery =
(from u
in db.Users
join ur in db.UserRoles
on u.UserID equals ur.UserID
join r in db.Roles on ur.RoleID equals r.RoleID
select new
Username=u.Username,
Password=u.Password,
RoleName = r.RoleName
).ToList();
上面查询中得到的数据是这样的,
username password RoleName
john 123 user
john 123 admin
john 123 super user
David 12345 super user
petter 123456 user
我想使用 Linq 在我的用户类对象中获取这些数据,
应该是这样的,
username password RoleName
john 123 "user", "admin", "super user"
David 12345 "super user"
petter 123456 "user"
我已经尝试了很多来自网络的例子,但我没有得到答案。
希望您的解决方案。
【问题讨论】:
【参考方案1】:您正在寻找GroupBy
方法。不确定您的 ORM 是否支持它,但您始终可以在查询 db 后进行分组:
var innerJoinQuery = (....)
.ToList()
.GroupBy(u => u.Username)
.Select(g => new User
Username=g.Key,
Password=g.Select(i => i.Password).First(),// can be moved to grouping clause
Roles = g.Select(i => i.RoleName).ToArray()
)
.ToList();
要尝试在对 db 的查询中执行 group by,您可以查看 this 问题,例如。
【讨论】:
我试过它给出了错误(方法'First'只能用作最终查询操作。考虑在这种情况下使用方法'FirstOrDefault'。) @Doc 抱歉,复制粘贴到 little,查询后添加.ToList()
,重试。
它现在可以工作了,我可以将此查询的结果移动到我的类“用户”对象
@Doc 查看更新。只需将最后一个选择从 new ..
更改为 new User
并更改 RoleNames
的一部分。
我了解您的查询我明白了我的意思是问,我有类似的对象 (private List您可以尝试以下使用子查询来选择所有角色名称的方法:
var innerJoinQuery = (
from u in db.Users
select new User
Username = u.Username,
Password = u.Password,
Roles = (from ur in db.UserRoles
join r in db.Roles on ur.RoleID equals r.RoleID
where ur.UserID == u.UserID
select r.RoleName).ToArray()
).ToList();
或者,您可以使用group...by...into
:
var innerJoinQuery = (
from u in db.Users
join ur in db.UserRoles on u.UserID equals ur.UserID
join r in db.Roles on ur.RoleID equals r.RoleID
group r by u into g
select new User
Username = g.Key.Username,
Password = g.Key.Password,
Roles = g.Select(c => c.RoleName).ToArray()
).ToList();
假设您的 ORM 支持这一点,它可能生成比聚合键然后从聚合组中进行子选择更好的查询。
如果 ORM 不能翻译 ToArray
/ToList
(Linq-To-SQL 不能),你可以
-
将
User.Roles
的类型更改为IEnumerable<string>
而不是string[]
,然后删除上面的ToArray
调用,或者
选择匿名类型首先,具体化查询 (ToList
),然后将结果重新投影到您的 User
类型中
#2
如下所示:
var innerJoinQuery = (
from u in db.Users
select new
u.Username,
u.Password,
Roles = (from ur in db.UserRoles
join r in db.Roles on ur.RoleID equals r.RoleID
where ur.UserID == u.UserID
select r.RoleName)
).ToList();
var users = innerJoinQuery.Select(c => new User
UserName = c.UserName,
Password = c.Password,
Roles = c.Roles.ToArray()
);
或者使用group...by
变体:
var innerJoinQuery= (
from u in db.Users
join ur in db.UserRoles on u.UserID equals ur.UserID
join r in db.Roles on ur.RoleID equals r.RoleID
group r by u into g
select new
g.Key.Username,
g.Key.Password,
Roles = g.Select(c => c.RoleName)
).ToList();
var users = innerJoinQuery.Select(c => new User
UserName = c.UserName,
Password = c.Password,
Roles = c.Roles.ToArray()
);
请注意,所有这些解决方案的优势在于它们在数据库中执行分组和/或子查询,而另一个答案是在内存中
【讨论】:
收到此错误(LINQ to Entities 无法识别方法 'System.String[] ToArray[String](System.Collections.Generic.IEnumerable`1[System.String])' 方法,以及此方法无法转换为商店表达式。)以上是关于如何用 linq to EF 填充我的类对象?的主要内容,如果未能解决你的问题,请参考以下文章
Linq to EF 系统不支持异常 System.NotSupportedException
如何用另一个observable填充observable并返回observable