Code First 和父子引用

发布于 2024-10-17 21:51:39 字数 1860 浏览 1 评论 0原文

我正在使用 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 添加记录时,我得到错误“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'testA' 中插入标识列的显式值。”

好的。由于无法识别 Id 是身份列,因此在 Code First 中删除 1。我们可以解决这个问题,因此我们告诉 CodeFirst testa.id 是一个标识:

    modelBuilder.Entity<testa>()
        .Property(p => p.id)
        .HasDatabaseGenerationOption(DatabaseGenerationOption.Identity);

完成后,我们再次运行它并收到另一个错误:“ReferentialConstraint 中的依赖属性映射到存储生成的列。列:'id'” 。那么——这张照片有什么问题吗?

我做错了什么以及如何解决它???

I'm using Code First CTP 5. I have a fairly simple setup between a parent table and child tables

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

To refer to these table using Code First, we have the following construct:

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; }
    }
}

When I try to add a record to testa, I get the error "Cannot insert explicit value for identity column in table 'testA' when IDENTITY_INSERT is set to OFF."

Ok. Strike 1 to Code First for not recognizing that Id is an identity column. We can fix this, so we tell CodeFirst that testa.id is an identity:

    modelBuilder.Entity<testa>()
        .Property(p => p.id)
        .HasDatabaseGenerationOption(DatabaseGenerationOption.Identity);

That done we run it again and get another error: "A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column: 'id'". So - what's wrong with this picture?

What am I doing wrong and how do I fix it???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

筱武穆 2024-10-24 21:51:39

在 1:1 关联中,Code First 将其中一个实体视为主体,将另一个实体视为从属实体。然后它使主体 PK 作为身份,并且在插入从属表时需要注意有效的唯一 PK。在您的情况下,它选择 testb 作为主体,但看起来您希望 testa 成为此关联中的主体。这可以通过使用 Fluent 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 部分 – 共享主键关联

In a 1:1 association, Code First recognize one of the entities as principal and the other one as dependent. Then it makes the principal PK as identity and you need to take care of a valid unique PK when inserting into the dependent table. In your case it picks testb as the principal but it looks like that you want testa to be the principal end in this association. This could be achieved by using fluent API and basically giving hint to Code First about which one is principal and which one is dependent:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<testb>()
                .HasRequired(b => b.testa)
                .WithOptional(a => a.testb);                
}

For more information, take a look at this article:

Associations in EF Code First CTP5: Part 2 – Shared Primary Key Associations

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文