从关联集访问记录

时间:2013-05-17 20:06:51

标签: c# entity-framework

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

在这个数据库中,我有一个表Group,其中GroupId作为主键,另一个表UserInfo,其中UserId作为其主键,另一个表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);

感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

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

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

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

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

但是,这不是最佳解决方案,因为 - 如上所述 - 它将导致两个查询(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