#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);’ Спасибо!