实体框架将Pure Junction查找表转换为多对多关系

时间:2013-03-29 20:30:27

标签: asp.net .net sql entity-framework orm

我刚刚开始在一个ASP.NET项目中使用Entity Framework(我最近也开始使用它,所以我最近有点不知所措)

我有一个包含4个查找表的数据库。当我将ADO.Net实体添加到我的asp.net项目时,我起初很困惑为什么我的查找表已经消失了。做了一些看后,我偶然发现了这个:

Entity Framework lookup table

并意识到查找没有其他列的表,但外键成为多对多的关系。这一切都很好。我可能会在这里遗漏一些简单的东西,我担心情况可能就是这样,但现在我迷失了如何查询我最初没有问题的数据遍历查找表来查找。

这是我的数据库的通用模型(不是EDM)

人: PID

组: GID

要求: RID

操作: AID

人/组: PID GID

组/需求: GID RID

要求/操作: RID AID

人/操作: PID AID

现在,在Person,Group,Requirement和Action之间存在多对多的关系 我不确定如何在我的ASP.Net Web表单项目代码中构建语句,以遍历像我以前使用查找表的关系。

我以前能够查询其中PID =“所需人员ID”的人/组,然后使用GID从组/要求中查找所有RID。然后使用RID从Requirement / Action中查找所有AID。然后将这些AID与人员/行动中的所有AID进行比较,其中AID匹配以检查是否满足要求。

如果你告诉我这是ASP.NET中我忽略的一些基本内容,我不会受到侮辱,但我想如果我在这里问过并且得到了回答,那么对于任何从SQL切换的人来说,至少会有一个简明的答案对实体框架的查询。

3 个答案:

答案 0 :(得分:1)

每当您获得Person对象时,您将拥有Actions和Groups的属性。

组也应具有Requirement属性。

所以我认为你要找的是像

list<int> personIds = {1,2,3};
List<Requirement> requirements = dbContext.Groups.Where(x => x.Person.Count(y => personIds.Contains(y.PersonId) > 0).Select(x => x.Requirements);
List<Action> actions = requirements.Actions;

你可能能够做到这一点是一种更加光滑的方式,当我在EF工作时,许多关系也会出现一种痛苦。

答案 1 :(得分:1)

在EntityFramework中,您可以选择添加所谓的“导航属性”。例如,让我们从假设的Person类中查看这些代码片段。

1:1或1:从1个角度看很多

public class Person
{
  public virtual Group Group {get;set;}
}

很多:很多或者1:许多人从很多角度来看

public class Person
{
  public virtual ICollection<Group> Groups {get;set;}
}

如果有多对多关系,您可以使用 EntityFramework FluentAPI 来设置Person和Group类之间的关系。对于1对1或1对多,您可以使用FluentAPI, DataAnnotations 或让EntityFramework猜测(我相信它会猜到PropertyName_ID)。

属性声明中的virtual意味着当我实际使用它时,我允许EntityFramework 延迟加载集合,而不是在我查询上下文时。您可以在没有virtual关键字的情况下声明导航属性,但是您不能延迟加载它。

希望这可以帮助您了解导航您的实体。我加粗了一些我认为应该谷歌的术语,以帮助进一步了解EntityFramework的运作方式。

根据您为特定人员获取群组所需的所有操作的问题:

var requiredActions = myPerson.Groups.SelectMany(x => x.Requirements).SelectMany(x => x.Actions);

一个人采取的行动将是:

var performedActions = myPerson.Actions;

这两行都假定您已设置了相应的导航属性。

答案 2 :(得分:0)

如前所述,通过多对多关联,您可以在实体中找到集合属性。拥有PersonGroups的{​​{1}}将Group

如果您进行类似

的查询
Persons

您将获得db.Persons.Where(p => p.PID == 1).SelectMany(p => p.Groups) 的所有组.1。EF构建一个连接Person联结表两次的查询。

综合(或“查询”)语法可能更适合您:

Person/Group

现在您的案例可以通过像这样的查询来解决:

from p in db.Persons
from g in p.Groups
where p.PID == 1
select g

但我无法从你的问题中说出来。这应该可以帮助你了解它的主旨。