Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 筛选实体集合_C#_Linq - Fatal编程技术网

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对象

例如,如果my
environmentId
变量的值为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()
;