Linq To Entities - 如何过滤子实体

问题描述 投票:13回答:5

我有实体GroupUserGroup实体有Users属性,这是一个用户列表。 用户有一个名为IsEnabled的属性。

我想编写一个返回Groups列表的linq查询,该列表仅包含其User为真的IsEnableds。

例如,对于下面的数据 AllGroups A组 用户1(IsEnabled = true) 用户2(IsEnabled = true) 用户3(IsEnabled = false)

B组 用户4(IsEnabled = true) 用户5(IsEnabled = false) 用户6(IsEnabled = false)

我想得到 FilteredGroups A组 用户1(IsEnabled = true) 用户2(IsEnabled = true)

B组 用户4(IsEnabled = true)

我尝试了以下查询,但Visual Studio告诉我 [无法将属性或索引器'用户'分配给 - 它是只读的]

FilteredGroups = AllGroups.Select(g => new Group()
                    {
                        ID = g.ID,
                        Name = g.Name,
                        ...
                        Users = g.Users.Where(u => u.IsInactive == false)
                    });

谢谢您的帮助!

linq entity-framework linq-to-entities wcf-ria-services
5个回答
9
投票

我设法通过颠倒查询来完成此操作:

var users = (from user in Users.Include("Group")
             where user.IsEnabled
             select user).ToList().AsQueryable()

from (user in users
      select user.Group).Distinct()

通过使用ToList(),您可以强制执行到数据库的往返,因为否则延迟执行会妨碍。第二个查询仅重新排序检索到的数据。

注意:之后您可能无法更新您的实体!


13
投票

这样做没有“好”的方法,但你可以试试这个 - 将Group和过滤的Users投射到一个匿名对象上,然后Select只是Groups

var resultObjectList = AllGroups.
                       Select(g => new
                               {
                                   GroupItem = g,
                                   UserItems = g.Users.Where(u => !u.IsInactive)
                               }).ToList();

FilteredGroups = resultObjectList.Select(i => i.GroupItem).ToList();

这不是一个记录的功能,而是与EF构造SQL查询的方式有关 - 在这种情况下,它应该过滤掉子集合,因此您的FilteredGroups列表将只包含活动用户。

如果这样可行,您可以尝试合并代码:

FilteredGroups = AllGroups.
                 Select(g => new
                               {
                                   GroupItem = g,
                                   UserItems = g.Users.Where(u => !u.IsInactive)
                               }).
                 Select(r => r.GroupItem).
                 ToList();

(这是未经测试的,结果取决于EF将如何处理第二个Select,所以如果你在尝试之后告诉我们哪种方法有效,那将会很好。)


1
投票

尝试这样的东西,你仍然会有你的实体:

FilteredGroups = AllGroups.Select(g => new
{
    Group = g,
    Users = g.Users.Where(u => u.IsInactive == false)
}).AsEnumerable().Select(i => i.Group);

那样你仍然可以使用Group.Users


0
投票

如果要保留实体结构,请尝试以下操作:

var userGroups = context.Users.Where(u => !u.IsInactive).GroupBy(u => u.Group);

foreach (var userGroup in userGroups)
{
    // Do group stuff, e.g.:
    foreach (var user in userGroup)
    {
    }
}

你当然可以修改你的实体!


0
投票

使用内部linq查询

var FilteredGroups = (from g in AllGroups
                      select new Group()
                        {
                            ID = g.ID,
                            Name = g.Name,
                            ...
                            Users = (from user in g.Users
                                     where user.IsInactive == false
                                     select user).ToList()
                        });
© www.soinside.com 2019 - 2024. All rights reserved.