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 - Ассоциации общего первичного ключа

Другие вопросы по тегам