使用 Entity Framework 4.1 Code-First 获取多对多关系中的关联记录

发布于 2024-12-28 06:45:34 字数 1893 浏览 3 评论 0原文

我正在使用 Entity Framework 4.1 代码优先,并且在检索多对多关系中的关联记录时遇到了一个小问题。我有一个主要的 Member 实体,它有一个关联的 MemberStatus (一对多关系)和一个关联的 MemberPosition (多对关系)许多关系)。

对于管理控制台,我正在检索 MemberStatuses 或 MemberPositions 的列表,但我需要知道是否有成员分配给这些值,以便我可以确定是否可以删除该值。

我在管理控制台中使用以下代码:

var statusList = MemberStatusRepository.AllIncluding(x => x.Members).ToList(); // This works...
var positionList = MemberPositionRepository.AllIncluding(x => x.Members).ToList(); // This doesn't...

statusList 值按预期返回,状态集合包括分配的成员数量的计数。但是,postionList 会返回相应的列表,但当我知道已分配成员时,每个职位的 Members 集合显示的计数为 0。

奇怪的是,我能够获得每个成员的位置列表,因此我相信我的 MemberMap 中的映射是正确的。我只是无法得到相反的结果,即每个职位的成员列表。此外,EF 创建的数据库看起来是正确的,具有正确的架构来实现成员与职位的多对多关系。

以下是我的实体和 EF 映射代码(继承自 EntityTypeConfiguration)。我在 MemberPosition 地图上缺少什么,因此当我调用上面的代码时,会返回每个位置的成员列表?

public class Member : Entity
{
  public string Email { get; set; }
  public int StatusId { get; set; }
  public virtual MemberStatus Status { get; set; }
  public virtual List<MemberPosition> Positions { get; set; }
}

public class MemberStatus : Entity
{
  public string Name { get; set; }
  public ICollection<Member> Members { get; set; }
}

public class MemberPosition : Entity
{
  public string Name { get; set; }
  public ICollection<Member> Members { get; set; }
}

public MemberMap()
{
  ToTable("Members");
  Property(m => m.Email).IsRequired().HasMaxLength(255);
  HasMany(m => m.Positions).WithMany() .Map(m => m.ToTable("Member_MemberPositions").MapLeftKey("MemberId").MapRightKey("PositionId"));
  HasRequired(m => m.Status).WithMany(s => s.Members).WillCascadeOnDelete(false);
}

public MemberStatusMap()
{
  ToTable("MemberStatuses");
}

public MemberPositionMap()
{
  ToTable("MemberPositions");
  HasMany(p => p.Members).WithMany();
}

I'm using Entity Framework 4.1 code-first and I'm having a slight issue with retriving associated records in a many-to-many relationship. I have a main Member entity which then has an associated MemberStatus (one-to-many relationship) and an associated MemberPosition (many-to-many relationship).

For an admin console, I am retreiving a list of MemberStatuses or MemberPositions, but I need to know if there are members assigned to those values so that I can determine if the value can be deleted.

I have the following code that I am using in my admin console:

var statusList = MemberStatusRepository.AllIncluding(x => x.Members).ToList(); // This works...
var positionList = MemberPositionRepository.AllIncluding(x => x.Members).ToList(); // This doesn't...

The statusList value comes back as expected and the collection of statuses includes a count of how many members are assigned. However, the postionList comes back with the appropriate list, but the Members collection for each position is showing a count of 0 when I know there are members assigned.

What's wierd is that I am able to get a list of positions for each member, so I belive the mapping is correct in my MemberMap. I just can't get the reverse which is a list of members for each position. Also, the DB that is created by EF looks correct with the proper schema for a many-to-many relationship for Members to Positions.

The following is my code for the entities and the EF mapping (inheriting from EntityTypeConfiguration). What am I missing on the MemberPosition map so that when I call the above code, a list of members is returned with each position?

public class Member : Entity
{
  public string Email { get; set; }
  public int StatusId { get; set; }
  public virtual MemberStatus Status { get; set; }
  public virtual List<MemberPosition> Positions { get; set; }
}

public class MemberStatus : Entity
{
  public string Name { get; set; }
  public ICollection<Member> Members { get; set; }
}

public class MemberPosition : Entity
{
  public string Name { get; set; }
  public ICollection<Member> Members { get; set; }
}

public MemberMap()
{
  ToTable("Members");
  Property(m => m.Email).IsRequired().HasMaxLength(255);
  HasMany(m => m.Positions).WithMany() .Map(m => m.ToTable("Member_MemberPositions").MapLeftKey("MemberId").MapRightKey("PositionId"));
  HasRequired(m => m.Status).WithMany(s => s.Members).WillCascadeOnDelete(false);
}

public MemberStatusMap()
{
  ToTable("MemberStatuses");
}

public MemberPositionMap()
{
  ToTable("MemberPositions");
  HasMany(p => p.Members).WithMany();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绮烟 2025-01-04 06:45:34

在多对多映射中,缺少反向导航属性的明确规范。它应该如下所示:

 HasMany(m => m.Positions)
.WithMany(p => p.Members)   // <- important to specify the navigation property
.Map(m => m.ToTable("Member_MemberPositions")
           .MapLeftKey("MemberId")
           .MapRightKey("PositionId"));

您的映射将让 EF 在 MemberMemberPosition 之间创建额外的一对多关系。 MemberPosition.Members 是此关系的一部分,而不是多对多关系。您实际上应该在创建的数据库模式中看到这一点。我希望您的 Member 表中有一个像 MemberPosition_Id 或类似的外键,它属于您不希望拥有的一对多关系。如果该外键在数据库中为 NULL(它应该是可为空的列),则您的仓位没有成员。因此,您的第二个查询无法按预期工作,并返回所有职位的空成员集合。

In your many-to-many mapping the explicite specification of the inverse navigation property is missing. It should look like this:

 HasMany(m => m.Positions)
.WithMany(p => p.Members)   // <- important to specify the navigation property
.Map(m => m.ToTable("Member_MemberPositions")
           .MapLeftKey("MemberId")
           .MapRightKey("PositionId"));

Your mapping will let EF create an additional one-to-many relationship between Member and MemberPosition. MemberPosition.Members is part of this relationship and not the many-to-many relationship. You should actually see this in the created database schema. I would expect a foreign key like MemberPosition_Id or similar in your Member table which belongs to this one-to-many relationship you don't want to have. If that foreign key is NULL in the database (it should be a nullable column), your positions have no members. Therefore your second query doesn't work as expected and returns empty member collections for all positions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文