Entity Framework 4.1 Code First, комбинированный первичный ключ как внешний ключ - PullRequest
1 голос
/ 17 октября 2011

У меня проблема с Entity Framework, где у меня есть что-то похожее на следующий макет:

public class ClassA
{
  public int ClassAID { get; set; }
}

public class ClassB
{
  public int ClassBID { get; set; }
}

public class ClassC
{
  public int ClassAID { get; set; } //Foreign Keys combined as Primary Key
  public int ClassBID { get; set; }

  public virtual ClassA SomeA { get; set; }
  public virtual ClassB SomeB { get; set; }
  public virtual ClassD SomeD { get; set; }
}

public class ClassD
{
  public int ClassAID { get; set; } //Primary Key and also references Class C Primary Key
  public int ClassBID { get; set; }

  public virtual ClassC SomeC { get; set; }
}

В ClassD возникает проблема, я хочу, чтобы свойства, представляющие первичный ключ в ClassC, были первичным ключом в ClassD, но также являлись ссылкой на внешний ключ. (Предположим, что имена свойств выше совпадают с именами столбцов таблицы)

В базовой базе данных соответствующие таблицы для ClassC и ClassD имеют отношение один к одному, где как ClassA к ClassC и ClassB к ClassC - отношение один ко многим.

Однако, когда дело доходит до Entity Framework, он не может обрабатывать несколько свойств одного и того же имени, выступая в качестве первичного ключа и внешнего ключа одновременно, в базовом SQL, который он генерирует, я вижу, что он ищет столбцы ClassD_ClassAID , ClassD_ClassBID - есть ли способ, используя конфигурацию модели, чтобы указать правильное отображение?

Я пробовал:

this.HasKey(c => new { c.ClassAID, c.ClassBID });
this.HasRequired(c => c.ClassC)
.WithRequiredDependent();

Я также пробовал:

this.HasKey(c => new { c.ClassAID, c.ClassBID });
this.HasRequired(c => c.ClassC)
.WithRequiredDependent()
.Map(m => m.MapKey("ClassAID", "ClassBID"));

Любая попытка представить отображение пока встречается с

«Имя свойства xxx уже существует в метаданных».

1 Ответ

4 голосов
/ 17 октября 2011

Я не уверен, что следующее решит вашу проблему, потому что я не понимаю, откуда возникло исключение, которое вы упомянули:

modelBuilder.Entity<ClassC>()
    .HasKey(c => new { c.ClassAId, c.ClassBId });

modelBuilder.Entity<ClassD>()
    .HasKey(d => new { d.ClassAId, d.ClassBId })
    .HasRequired(d => d.SomeC)
    .WithRequiredDependent(c => c.SomeD);

Важной частью здесь является то, что вы задаете свойство навигации вДругая сторона отношений в WithRequiredDependent.Если вы используете перегрузку без параметров, EF создаст второе отношение между ClassC и ClassD, а SomeD будет принадлежать этому отношению, а не тому, которое вы настраиваете.

I, если вы не укажетелюбое дальнейшее сопоставление для ClassA и ClassB EF создаст следующие три взаимосвязи на основе приведенного выше сопоставления и соглашений:

  • ClassA -> ClassC (FK = ClassAId в ClassC)
  • ClassB -> ClassC (FK = ClassBId в ClassC)
  • ClassC -> ClassD (FK = ClassAId, ClassBId в ClassD)

Итак, ClassD имеет составнойпервичный ключ, который является составным внешним ключом для ClassC одновременно.

...