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();
}
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
MemberandMemberPosition.MemberPosition.Membersis 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_Idor similar in yourMembertable which belongs to this one-to-many relationship you don’t want to have. If that foreign key isNULLin 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.