查询EDMX中的多对多join表

本文关键字:join EDMX 查询 | 更新日期: 2023-09-27 18:01:48

当我访问一个实体的导航属性时,我目前面临性能问题。

我有三个表:UserCategory, UserUserCategoryUserUser表与UserCategory表之间存在多对多关系。UserCategoryUser表是joiner表,它有两列UserIdUserCategoryId,即UserUserCategory表的主键。join表UserCategoryUser用于维护UserUserCategory表之间的多对多关系。

我使用数据库优先的方法。因此在我的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或存储过程进行此检查,但我希望在这种情况下远离这些。

查询EDMX中的多对多join表

您的问题是启用延迟加载后,对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