C# 筛选实体集合
我希望能够筛选子集合并仅返回该子集合中符合特定条件的项。以下是我现在掌握的代码:C# 筛选实体集合,c#,linq,C#,Linq,我希望能够筛选子集合并仅返回该子集合中符合特定条件的项。以下是我现在掌握的代码: var q = from u in context.DbContext.Users select u; q = q.Include(u => u.UserRoles.Select(ur => ur.Role)) .Where(u=> u.UserRoles.Any(ur=> ur.EnvironmentId == environmentId) ); 我对这段代码的问题是,它还返回
var q = from u in context.DbContext.Users select u;
q = q.Include(u => u.UserRoles.Select(ur => ur.Role))
.Where(u=> u.UserRoles.Any(ur=> ur.EnvironmentId == environmentId)
);
我对这段代码的问题是,它还返回UserRole集合中不匹配的UserRole对象
例如,如果myenvironmentId
变量的值为1,则仅当environmentId属性的值为1时,才希望在集合中返回UserRoles
现在,它将返回每个UserRole,而不考虑EnvironmentId值
编辑
正如格特·阿诺德所说,这不是一个重复的问题。我不想创建新的或匿名的对象,下面我提出的解决方案解决了这个问题,而Gert Arnold链接的文章却没有解决这个问题。您的
中的条件未应用于正确的集合。这里,您将Where
应用于用户集合,以便它只返回至少具有一个角色的用户,其中EnvironmentId
为1。相反,您要做的是将其应用于您的角色集合,以便只加入您想要的角色集合。这不起作用我认为这样的方法应该起作用:
q = q.Include(
u => u.UserRoles.Where(ur => ur.EnvironmentId == environmentId)
.Select(ur => ur.Role))
相反,您可以通过select返回一个新对象(我现在正进入一个不确定的领域:)
现在奇怪的部分来了。。。这将返回一个匿名对象,其中用户属性是返回的用户,角色是返回的角色。如果希望创建一个新类,以便可以将该值带到该块范围之外
新类
public class UserWithRoles
{
Public User User {get; set;}
IEnumarable<Roles> Roles {get; set;}
}
这样,您就可以声明一个List UserList
,并且可以执行UserList=q.ToList()代码>这可能不是(可能不是)最好的方法,但我相信这是一种可行的方法。如果有人比我在LINQ的《代码》中有更多的知识,请参阅并知道如何使这项工作更好,请在这里发布另一个答案或评论,我也想知道: < p>你可以考虑只返回一个用户角色列表,如果你需要用户对象,你可以从这个列表中选择用户。
var roles = from ur in context.DbContext.UsersRoles.Include("User")
where ur.EnvironmentId == environmentId
select ur;
var users = roles.SelectMany(a => a.Users).Distinct();
使用这里提供的示例,我提出了一个似乎清晰而优雅的问题解决方案。这只会加载集合中匹配的项,不需要创建任何匿名对象。(注意:要使显式加载工作,必须关闭LazyLoading)
这似乎将我引向了正确的方向,但在运行此代码时,我遇到了一个错误:Include path表达式必须引用在类型上定义的导航属性。使用虚线路径作为参考导航属性,选择运算符作为集合导航属性。我相信这是因为没有包含角色对象?如何在选择退出之前包含它?@KCCoder我不太熟悉include
函数,但我会尝试包含UserRoles,然后再包含Roles。我真的不确定这是否可行,但是,您可能需要执行选择
。我不确定需要在此处执行什么操作才能将其更改为选择
。我查看了您更新的示例,我感谢您的努力,但是的,我需要在不返回新对象/不同对象的情况下执行此操作。我需要返回相同的Users对象集合,其中只包含匹配的UserRoles。如果有人可以提供一个例子,而不必声明一个新对象,那就太好了。不幸的是,我试图在网上寻找其他方法来过滤包含的,除了我在更新的答案中为什么这样做之外,我找不到任何东西。否则,我的建议是执行两个单独的查询并同时使用它们。这不是重复的,因为我不希望以新的或匿名的对象结束。我提出的解决方案解决了这个问题,而你链接到的另一个主题却没有。anon.类型只是一个中间结果。Load()的问题在于,您只能使用它来加载一个实体的部分集合。当然,它确实可以工作,但是很难重用代码来选择多个实体。顺便说一句,这里真正的问题是EF从未实现过过滤包含,尽管它实际上是一个不可或缺的功能。
q => q.Select(u =>
new UserWithRoles() {
User = u,
Roles = u.UserRoles.Where(ur => ur.EnvironmentId == environmentId)
};
var roles = from ur in context.DbContext.UsersRoles.Include("User")
where ur.EnvironmentId == environmentId
select ur;
var users = roles.SelectMany(a => a.Users).Distinct();
User user;
var data = from u in context.DbContext.Users select u;
user = data.FirstOrDefault();
// load UserRoles and UserRoles.Role
context.Entry(user)
.Collection(u => u.UserRoles)
.Query()
.Include(ur => ur.Role)
.Where(ur => ur.EnvironmentId == environmentId)
.Load()
;