【问题标题】:Cannot insert value for identity when Identitt_insert is set to OFF当 Identity_insert 设置为 OFF 时,无法插入身份值
【发布时间】:2017-12-04 13:10:44
【问题描述】:

我知道我不是第一个在这里提出这个问题的人。但是在经历了很多关于这个的答案之后,我仍然无法解决我的问题。

原来如此。

我的 Code First 模型中有多个派生模型,共享相同的 Idenity 属性。

这是我的模型示例

public class Foo 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FooId { get; set; }

    public string SomeProperty{get;set;}
}

public class DerivedFoo : Foo
{
    public string SomeOtherProperty {get;set;}
}

public class EvenMordeDerivedFoo : DerivedFoo 
{
    public string AndAnotherProperty {get;set;}
}

所以据我了解,我的 FooContext 覆盖应该如下所示:

public class FooContext : DbContext
{
   public DbSet<Foo> Foos{get;set;}
   public DbSet<DerivedFoo> DerivedFoos{get;set;}
   public DbSet<EvenMordeDerivedFoo > EvenMordeDerivedFoos{get;set;}

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<DerivedFoo>().ToTable("DerivedFoo");
        modelBuilder.Entity<EvenMordeDerivedFoo >().ToTable("EvenMordeDerivedFoo ");
    }
}    

有了这个,我可以毫无问题地使用 Foo 创建和运行 context.SaveChanges()。但是当我尝试通过以下方式创建 DerivedFoo 时:

var derivedFoo= _context.DerivedFoos.Create();
_context.DerivedFoos.Add(derivedFoo);
_context.SaveChanges();

我最终遇到了臭名昭著的错误:

"无法为表中的标识列插入显式值 IDENTITY_INSERT 设置为 OFF 时的 'DerivedFoo'。"

据我了解,Entity Framework 试图解释如果我将 Identity_Insert 设置为 true,我不应该自己修改 FooId 属性。

我同意 EF 的观点,因为我希望每次创建新的 Foo、DerivedFoo 或 EvenMordeDerivedFoo 时都设置这个 FooId 属性,这解释了我添加该行的原因

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

所以如果有人能解释我做错了什么可以解释,那就太好了。

编辑:我仍然找不到答案,经过验证,我的模型大多匹配this tutorial模型。所以我很确定答案很简单,但我找不到我错过的东西

【问题讨论】:

  • 是从上述模型迁移生成的数据库模式(我看到的 TPT)。如果是,DerivedFooEvenMordeDerivedFoo 等中的 FooId 列应该是身份。
  • 是的,数据库是从模型中生成的。因此,如果我理解正确,我应该在 DerivedFoo 和 EvenMoreDerivedFoo 中添加一些 ID 属性?

标签: entity-framework inheritance identity


【解决方案1】:

我应该在 DerivedFoo 和 EvenMoreDerivedFoo 中添加一些 ID 属性

没有。实体很好。派生类型的表不需要有 IDENTITY 属性。

EG,这将创建只有 Foo 的 ID 列具有 IDENTITY 属性的表:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;

namespace Ef6Test
{

    public class Foo
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int FooId { get; set; }

        public string SomeProperty { get; set; }
    }

    public class DerivedFoo : Foo
    {
        public string SomeOtherProperty { get; set; }
    }

    public class EvenMordeDerivedFoo : DerivedFoo
    {
        public string AndAnotherProperty { get; set; }
    }
    class Db : DbContext
    {
        public DbSet<Foo> Foos { get; set; }
        public DbSet<DerivedFoo> DerivedFoos { get; set; }
        public DbSet<EvenMordeDerivedFoo> EvenMordeDerivedFoos { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<DerivedFoo>().ToTable("DerivedFoo");
            modelBuilder.Entity<EvenMordeDerivedFoo>().ToTable("EvenMordeDerivedFoo ");
        }
    }




    class Program
    {
        static void Main(string[] args)
        {

            Database.SetInitializer(new DropCreateDatabaseAlways<Db>());

            using (var db = new Db())
            {

                db.Database.Log = m => Console.WriteLine(m);
                db.Database.Initialize(true);

                var derivedFoo = db.DerivedFoos.Create();
                db.DerivedFoos.Add(derivedFoo);
                db.SaveChanges();

            }

            Console.WriteLine("Hit any key to exit");
            Console.ReadKey();
        }
    }
}

【讨论】:

  • 似乎工作正常!我不确定我失败的地方,因为我几乎可以肯定在某个时候尝试过以这种方式实现它,也许我没有正确更新我的数据库。非常感谢!
猜你喜欢
  • 2018-06-22
  • 2016-05-13
  • 2017-10-26
  • 2019-03-10
  • 2016-08-18
  • 2018-06-29
  • 2011-08-26
相关资源
最近更新 更多