使用 Entity Framework 4.1 Code-First 获取多对多关系中的关联记录
我正在使用 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在多对多映射中,缺少反向导航属性的明确规范。它应该如下所示:
您的映射将让 EF 在
Member
和MemberPosition
之间创建额外的一对多关系。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:
Your mapping will let EF create an additional one-to-many relationship between
Member
andMemberPosition
.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 likeMemberPosition_Id
or similar in yourMember
table which belongs to this one-to-many relationship you don't want to have. If that foreign key isNULL
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.