我有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
答案 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;
}