在 EDMX 中查询多对多连接器 table
Query to many-to-many joiner table in EDMX
我目前在访问实体的导航 属性 时遇到性能问题。
我有三个 table:UserCategory
、User
和 UserCategoryUser
。在 User
和 UserCategory
table 之间存在 多对多 关系。 UserCategoryUser
table 是连接器 table 它有两列 UserId 和 UserCategoryId 即主键User
和 UserCategory
table 秒。 joiner table UserCategoryUser
用于维护 User
和 UserCategory
tables.
之间的多对多关系
我正在使用数据库优先方法。因此在我的 EDMX 中,对于 User
实体,我有一个导航 属性 UserCategories
。同样,对于 UserCategory
实体,有一个导航 属性 Users
。
我想将用户添加到用户类别。所以在添加之前,我正在检查用户是否已经添加到用户类别中。在我的数据库中,我有大约 100k 条用户记录,并且只有一个用户类别。与唯一用户类别关联的所有用户。
我正在访问 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 to Entity 中执行连接查询,因为加入者 table(UserCategoryUser
) 未作为实体添加到 EDMX 中。
如何解决这个问题?我可以使用纯 SQL 或存储过程进行此检查,但我想远离这种情况。
您的问题是,启用延迟加载后,对 userCategory.Users
的调用会将所有用户加载到内存中。我认为,鉴于类别很少,我会反过来做。即获取用户然后检查用户的类别集合是否包含正在添加的类别。
但是,如果您有非常多的类别,则可以显式过滤集合。首先关闭集合的延迟加载(例如通过删除 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
我目前在访问实体的导航 属性 时遇到性能问题。
我有三个 table:UserCategory
、User
和 UserCategoryUser
。在 User
和 UserCategory
table 之间存在 多对多 关系。 UserCategoryUser
table 是连接器 table 它有两列 UserId 和 UserCategoryId 即主键User
和 UserCategory
table 秒。 joiner table UserCategoryUser
用于维护 User
和 UserCategory
tables.
我正在使用数据库优先方法。因此在我的 EDMX 中,对于 User
实体,我有一个导航 属性 UserCategories
。同样,对于 UserCategory
实体,有一个导航 属性 Users
。
我想将用户添加到用户类别。所以在添加之前,我正在检查用户是否已经添加到用户类别中。在我的数据库中,我有大约 100k 条用户记录,并且只有一个用户类别。与唯一用户类别关联的所有用户。
我正在访问 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 to Entity 中执行连接查询,因为加入者 table(UserCategoryUser
) 未作为实体添加到 EDMX 中。
如何解决这个问题?我可以使用纯 SQL 或存储过程进行此检查,但我想远离这种情况。
您的问题是,启用延迟加载后,对 userCategory.Users
的调用会将所有用户加载到内存中。我认为,鉴于类别很少,我会反过来做。即获取用户然后检查用户的类别集合是否包含正在添加的类别。
但是,如果您有非常多的类别,则可以显式过滤集合。首先关闭集合的延迟加载(例如通过删除 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