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

时间:2017-05-18 18:45:51

标签: entity-framework entity-framework-6

我有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

4 个答案:

答案 0 :(得分: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(“在显式加载相关实体时应用过滤器”部分)

答案 1 :(得分: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;

答案 2 :(得分: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()


                });

答案 3 :(得分: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