0

我正在使用 ASP.net MVC 开发一个 Web 应用程序,并且我有一个与 ADO.NET 实体框架连接的数据库。

在这个数据库中,我有一个以 GroupId 作为主键的表 Group,另一个以 UserId 作为主键的表 UserInfo 和另一个表 GroupUser,它不被视为实体,而是作为关联集,因为它被用作拥有组和用户之间的多对多关系。

GroupUser包含GroupIdUserId作为复合键,两者都是各自表的外键。

这些是生成的GroupUser类(关于这种关系)

// Group
public Group()
{
    this.UserInfo1 = new HashSet<UserInfo>();
}

public virtual UserInfo UserInfo { get; set; }
public virtual ICollection<UserInfo> UserInfo1 { get; set; }

// UserInfo
public UserInfo()
{
   this.Group = new HashSet<Group>();
   this.Group1 = new HashSet<Group>();
}

public virtual ICollection<Group> Group { get; set; }
public virtual ICollection<Group> Group1 { get; set; }

要将记录添加到此GroupUser表中,我正在执行此操作

int ownerId = Convert.ToInt32(WebSecurity.CurrentUserId);
group.UserInfo1.Add(conn.UserInfo.Find(ownerId));

但是我被困在如何在这张表中找到一条记录。如何通过在此处提供 groupId 和 userId 来检查特定用户是否属于该组?

Group group = conn.Group.Find(id);
int userId = Convert.ToInt32(WebSecurity.CurrentUserId);

谢谢你的帮助 :)

4

1 回答 1

1

使用您提供的起点以测试用户是否在该组中,您可以使用:

Group group = conn.Group.Find(id);
int userId = Convert.ToInt32(WebSecurity.CurrentUserId);

bool isUserInGroup = group.UserInfo1.Any(u => u.UserId == userId);

它将起作用,因为当您访问group.UserInfo1Any在这种情况下使用扩展方法)时,Entity Framework 将运行第二个查询(第一个是Find)以将给定的所有相关UserInfo实体加载groupgroup.UserInfo1集合中。此查询基于延迟加载virtual,如果导航集合被声明为(在您的示例中),则默认启用该延迟加载。加载集合后,如果集合包含至少一个满足所提供条件的实体,即包含具有该条件的用户,则Any调用是内存检查(这里不再有数据库查询)。group.UserInfo1userId

但是,这不是最好的解决方案,因为 - 如前所述 - 它会导致两个查询(Find以及集合的延迟加载)。实际上,您可以仅通过单个数据库查询来测试用户是否在组中,您甚至不需要为该测试加载任何实体,只需直接bool从数据库返回结果:

int userId = Convert.ToInt32(WebSecurity.CurrentUserId);

bool isUserInGroup = conn.Group
    .Any(g => g.GroupId == id && g.UserInfo1.Any(u => u.UserId == userId));

结果将是false如果具有 的组id不存在或者它没有具有 的相关用户userId

于 2013-05-17T21:47:55.113 回答