Code First и Parent-Child ссылки
Я использую Code First CTP 5. У меня довольно простая настройка между родительской таблицей и дочерней таблицей
Create table testA (
id int not null identity(1,1),
stuff varchar(200),
primary key (id)
);
go
create table testB (
id int not null
foreign key references testA(id),
morestuff varchar(200),
primary key (id)
);
go
Чтобы обратиться к этим таблицам с помощью Code First, у нас есть следующая конструкция:
namespace Test.Models
{
public class TestEntities : DbContext
{
public DbSet<testa> testa { get; set; }
public DbSet<testb> testb { get; set; }
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<testa>().ToTable("testa");
modelBuilder.Entity<testa>()
.Property(p => p.id)
.HasDatabaseGenerationOption(DatabaseGenerationOption.Identity);
modelBuilder.Entity<testb>().ToTable("testb");
}
}
public class testa
{
public int id { get; set; }
public String stuff { get; set; }
public virtual testb testb { get; set; }
}
public class testb
{
public int id { get; set; }
public string morestuff { get; set; }
public virtual testa testa { get; set; }
}
}
Когда я пытаюсь добавить запись в testa, я получаю сообщение об ошибке "Невозможно вставить явное значение для столбца идентификаторов в таблице" testA ", когда для IDENTITY_INSERT установлено значение OFF".
Хорошо. Ударь 1 в Code First, чтобы не распознать, что Id является столбцом идентификаторов. Мы можем это исправить, поэтому сообщаем CodeFirst, что testa.id - это личность:
modelBuilder.Entity<testa>()
.Property(p => p.id)
.HasDatabaseGenerationOption(DatabaseGenerationOption.Identity);
После этого мы запускаем его снова и получаем еще одну ошибку: "Зависимое свойство в ReferentialConstraint отображается в столбец, созданный хранилищем. Столбец: 'id'". Итак - что не так с этой картиной?
Что я делаю не так и как мне это исправить???
1 ответ
В связи 1:1 Code First распознает один из объектов как основной, а другой - как зависимый. Затем он делает основной PK идентификатором, и вам нужно позаботиться о действительном уникальном PK при вставке в зависимую таблицу. В вашем случае это выбирает testb
в качестве основного, но похоже, что вы хотите testa
быть главным концом в этой ассоциации. Этого можно достичь, используя свободный API и, в основном, давая подсказку Code First о том, какой из них является основным, а какой - зависимым:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<testb>()
.HasRequired(b => b.testa)
.WithOptional(a => a.testb);
}
Для получения дополнительной информации, посмотрите на эту статью:
Ассоциации в EF Code First CTP5: Часть 2 - Ассоциации общего первичного ключа