查询EDMX中的多对多join表
本文关键字:join EDMX 查询 | 更新日期: 2023-09-27 18:01:48
当我访问一个实体的导航属性时,我目前面临性能问题。
我有三个表:UserCategory
, User
和UserCategoryUser
。User
表与UserCategory
表之间存在多对多关系。UserCategoryUser
表是joiner表,它有两列UserId和UserCategoryId,即User
和UserCategory
表的主键。join表UserCategoryUser
用于维护User
和UserCategory
表之间的多对多关系。
我使用数据库优先的方法。因此在我的EDMX中,对于User
实体,我有一个导航属性UserCategories
。类似地,对于UserCategory
实体,有一个导航属性Users
。
我想添加一个用户到一个用户类别。所以在添加之前,我要检查用户是否已经添加到usercategory。在我的数据库中,我有大约100k用户记录,只有一个用户类别。与唯一usercategory关联的所有用户。
我正在访问Users
导航属性,如下所示:
var userCategory = Context.UserCategories.FirstOrDefault(uc => uc.UserCategoryId == userCategoryId);
if (userCategory != null)
{
if (userCategory.Users.Any(u => u.Username == username))
{
//Other operations
}
}
这段代码之前是工作的,但现在它挂起了,因为我们有很多用户数据。特别是它是挂userCategory.Users.Any(u => u.Username == username))
线。我也试着让用户count
,但它仍然挂着!
userCategory.Users.Count();
我无法在LINQ中对实体进行连接查询,因为join表(UserCategoryUser
)未作为实体添加到EDMX中。
如何解决这个问题?我可以使用纯SQL或存储过程进行此检查,但我希望在这种情况下远离这些。
您的问题是启用延迟加载后,对userCategory.Users
的调用将所有Users加载到内存中。我想,考虑到分类很少,我会用另一种方式来做。即获取User,然后检查用户的Category集合是否包含要添加的类别。
但是,如果您有非常多的类别,那么您可以显式地过滤集合。首先在集合上关闭延迟加载(例如,通过删除virtual
关键字),然后尝试:
Context.Entry(userCategory)
.Collection(uc => uc.Users)
.Query()
.Where(u => u.Username == username)//I'd put an index on username too
.Load();
if(userCategory.Users.Any())
{
//Other operations
}
参考:https://msdn.microsoft.com/en-us/data/jj574232.aspx explicitFilter