Entity Framework 4.1 Сначала код, объединенный первичный ключ в качестве внешнего ключа

#entity-framework-4 #entity-framework-4.1 #ef-code-first #composite-primary-key

#entity-framework-4 #entity-framework-4.1 #ef-code-first #составной первичный ключ

Вопрос:

У меня проблема с 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:

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

 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 будет принадлежать этому отношению, а не тому, которое вы настраиваете.

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

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

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

Комментарии:

1. Похоже, все, чего мне не хватало, это явно указать это сопоставление: используя ‘.WithRequiredDependent(c => c.SomeD);’ Спасибо!