2013-05-17 95 views
0

我开发与ASP.net MVC Web应用程序和我有我与ADO.NET实体框架连接的数据库。从关联访问一个记录集

在这个数据库中,我有一个以GroupId作为主键的组表,另一个表UserInfo以UserId作为其主键,另一个表GroupUser不被视为实体,这意味着Group和User之间有多对多的关系。

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

随着你,以测试提供的起点,如果用户是该组中,你可以使用:

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

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

它会工作,因为当你(在这种情况下,与Any扩展方法)访问group.UserInfo1实体框架将运行第二个查询(第一个是Find)给定group的所有相关UserInfo实体加载到group.UserInfo1集合。此查询基于在延迟加载在缺省情况下,如果导航集合声明为virtual(它是在你的例子)启用。加载集合后,Any通话是在内存中进行检查(无数据库查询在这里了)如果group.UserInfo1集包含的满足提供的条件至少一个实体,即包含与userId用户。

然而,这是不是最好的解决方案,因为 - 因为说 - 这将导致两个查询(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

+0

非常感谢@Slauma的详细解答!你帮我充分理解了这一点。 +1 :) – Bernice