如何在EF6.1中过滤掉子集合

问题描述 投票:0回答:4

我有一个Apps,AppRoles,UserAppRoles和用户。我正在尝试获取所有用户,但只想要AppRd = AppId = 1的AppRoles。如何过滤子集合?

using (var context = new dbContext())
            {
                var rv = context.Users
                       .Include(u => u.AppRoles);                           

            }

我试过这个但抛出异常:Include路径表达式必须引用在类型上定义的导航属性。使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性

public static async Task<List<User>> GetAllAsync()
        {
            var rv = new List<User>();

            using (var context = new dbContext())
            {
                rv = await (context.Users.AsNoTracking()
                    .Include(a => a.AppRoles.Where(a2 => a2.AppId == 1)).ToListAsync());
            }

           return rv;

        }

我可以弄清楚如何让它工作的唯一方法就是这样,我可能只是在那时使用存储过程:

var rv = new List<User>();

            using (var context = new dbContext())
            {
               rv = context.Users.AsNoTracking()
                    .Include(a => a.AppRoles).ToList();


            }

            foreach (var user in rv)
            {
                if (user.AppRoles.Any())
                {
                    user.AppRoles = user.AppRoles.Where(r2 => r2.AppId == 1).ToList();
                }
            }

我怎么用EF写这个?

SELECT        
Users.UserId, 
Users.UserName
FROM          
Users 

INNER JOIN UserAppRoles ON Users.UserId = UserAppRoles.UserId 
INNER JOIN AppRoles ON UserAppRoles.AppRoleId = AppRoles.AppRoleId
WHERE AppRoles.AppId = 1
entity-framework entity-framework-6
4个回答
0
投票

试试这个:

context.Entry(user) 
        .Collection(b => b.AppRoles) 
        .Query() 
        .Where(r => r.AppId==1) 
        .Load(); 

其中user是来自上下文的AppUser实体(如您的foreach示例中所示)。

更多信息:

https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx(“在显式加载相关实体时应用过滤器”部分)


0
投票

您可以查询AppRoles

var arQuery = from ar in context.AppRoles
              where ar.AppId == 1
              select ar;

var query = from u in context.Users
            join uar in context.UserAppRoles on u.UserId equals uar.UserId
            join ar in arQuery on uar.AppRoleId equals ar.AppRoleId
            select u;

0
投票

我有这样的工作,但仍然看起来效率低但是猜测它比往返数据库更好。这不是一个常见的模式吗?我不敢相信EF中没有包含简单的内部连接,但是我正在映射到DTO,所以我猜这个现在可以使用,直到我查看一些支持过滤的开源包含过滤器。

var rv = context.Users.Include(r => r.AppRoles).ToList().Select(u => new User()
                {
                    UserId = u.UserId,
                    AppRoles = u.AppRoles.Where(x=>x.AppId == 1).ToList()


                });

0
投票

免责声明:我是Entity Framework Plus项目的所有者

EF + Query IncludeFilter允许轻松过滤包含的实体。

public static async Task<List<User>> GetAllAsync()
{
    var rv = new List<User>();

    using (var context = new dbContext())
    {
        rv = await (context.Users.AsNoTracking()
            .IncludeFilter(a => a.AppRoles.Where(a2 => a2.AppId == 1)).ToListAsync());
    }

   return rv;
}

维基:EF+ Query Include Filter

© www.soinside.com 2019 - 2024. All rights reserved.