Получите связанные записи в отношениях «многие ко многим», используя Entity Framework 4.1 Code-First - PullRequest
1 голос
/ 22 января 2012

Сначала я использую 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 возвращается с соответствующим списком, но коллекция «Члены» для каждой позиции показывает счет 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();
}

1 Ответ

2 голосов
/ 03 февраля 2012

В вашем отображении «многие ко многим» отсутствует точная спецификация свойства обратной навигации. Это должно выглядеть так:

 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 создать дополнительные отношения один-ко-многим между Member и MemberPosition. MemberPosition.Members является частью этого отношения, а не отношения многих ко многим. Вы должны увидеть это в созданной схеме базы данных. Я ожидал бы, что внешний ключ, такой как MemberPosition_Id или аналогичный в вашей таблице Member, относится к этим однозначным отношениям, которые вы не хотите иметь. Если этот внешний ключ NULL в базе данных (это должен быть обнуляемый столбец), ваши позиции не имеют членов. Поэтому ваш второй запрос не работает должным образом и возвращает пустые коллекции элементов для всех позиций.

...