当Identitt_insert设置为OFF

时间:2017-12-04 13:10:44

标签: entity-framework inheritance identity

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

所以就是这样。

我的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();

我最终得到了臭名昭着的错误:

  

&#34;无法在表中插入identity列的显式值   &#39; DerivedFoo&#39;当IDENTITY_INSERT设置为OFF时。&#34;

根据我的理解,实体框架试图解释如果我将Identity_Insert设置为true,我不应该自己修改属性FooId。

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

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

所以,如果有人能解释我做错了可以解释的内容,那将是非常好的。

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

1 个答案:

答案 0 :(得分: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();
        }
    }
}