在实体框架中通过ID获取元素列表

50
如何根据ID获取另一个列表中的所有元素? 我有一个名为roles的列表;我想通过它们的Id从数据库中获取所有在这个列表里的roles。 我正在使用code-first。 我尝试了下面的代码,但是出现了错误:
var roles = db.Roles.Where(r => user.Roles.Any(ur => ur.RoleId == r.RoleId));

RoleId 是 int 类型。

错误:

无法创建类型为“SampleMVC.Domain.Role”的常量值。 在此上下文中,仅支持原始类型(例如 Int32、String 和 Guid)。

3个回答

121
var listOfRoleId = user.Roles.Select(r => r.RoleId);
var roles = db.Roles.Where(r => listOfRoleId.Contains(r.RoleId));

应该检查生成的 SQL,或在 LinqPad 中尝试它。 - moi_meme
如果user是已加载的实体并且它已经加载了Roles,那么这将是一个查询。 - Ladislav Mrnka
5
对于小的数据集,这样做很好,但如果ID列表很大,您会想要另一种方法。https://dev59.com/nnI-5IYBdhLWcg3wZ3jC - Jess
这个也可以用于连接吗?我尝试了同样的方法,但是它给我返回了这个错误:无法比较类型为'System.Collections.Generic.List`1 [[System.Int32, mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]'的元素。仅支持基本类型、枚举类型和实体类型。 - Amit Andharia
@AmitAndharia,你解决了那个问题吗?当使用连接时,我也遇到了相同的错误。 - Rolando Retana
@RolandoPérez - 是的,像上面答案中所示使用Contains函数。 - Amit Andharia

15

如果user.Roles是一个整数列表,那么这样的代码应该可以工作:

var roles = db.Roles.Where(r => user.Roles.Contains(r.RoleId));

这会将其转换为 SQL 中的"SELECT WHERE IN (x, y, z...)"。


我无法使用 r.RoleId,因为Roles是一个类而RoleId是一个整数。 - Shawn Mclean
1
想法不错!你可以在 ...user.Roles.......Contains... 之间插入 .Select(ur => ur.RoleId).。我很好奇查询是否能正常工作。 - Slauma

3
您不能将本地列表与远程数据结合起来,因为在客户端上数据已经存在,因此数据库无法从中读取任何信息。
我认为有更好的解决方案来实现您的需求;
看起来您正在尝试获取分配给特定用户的所有角色。如果是这样,我建议您将当前用户ID传递到数据库,并使用INNER JOIN获取分配的角色。
根据您的数据库,它可能类似于以下内容(如果通过名为'UserRoles'的表连接用户和角色):
var roles = db.UserRoles.Where(x => x.UserID == <insert id>).Select(x => x.Role)

(当然,如果您喜欢,也可以在数据库中创建返回“Role”列表的存储过程,并进行映射。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接