如何在EF6.1中过滤掉子集合
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在EF6.1中过滤掉子集合相关的知识,希望对你有一定的参考价值。
我有一个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
答案
试试这个:
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(“在显式加载相关实体时应用过滤器”部分)
另一答案
您可以查询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;
另一答案
我有这样的工作,但仍然看起来效率低但是猜测它比往返数据库更好。这不是一个常见的模式吗?我不敢相信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()
});
另一答案
免责声明:我是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;
}
以上是关于如何在EF6.1中过滤掉子集合的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中使用 Firestore 创建子集合