Cannot insert value for identity in table when IDENTITY_INSERT is set to OFF

时间:2019-04-08 13:02:07

标签: c# sql-server entity-framework entity-framework-core

I am getting the error above when I call SaveChanges() using an instance of my Context. Now I understand what the error is pointing to, but I simply do not understand why it occurs for this particular situation.

The error occurs because I save an instance of the TestMember into the TestMember field in the Report class (which is the model for my table). Since TestMember is the foreign key this should not be a problem should it? For my own clarity I wrote raw SQL and explicitly put a valid int into the ForeignKey field and it worked fine. INSERT INTO [TestMemberReports].[dbo].[TestReports] (TestMemberId,Date,IsSuccess) values (3, '2019-05-09', 0).

However when done in code like shown below. It throws the SqlException: Cannot insert explicit value for identity column in table 'TestMembers' when IDENTITY_INSERT is set to OFF. error. For the purpose of the question please assume:

  • CreateReports() is called from main()
  • Code

    public class TestReportService
    {
        private TestMemberReportContext Context { get; }
        public void SaveChanges() => Context.SaveChanges();
    
        public TestReportService(TestMemberReportContext context)
        {
            Context = context;
        }
    
        public void CreateReports()
        {
            var reports = AddReport();
            Context.TestReports.Add(reports);
            SaveChanges();
        }
    
        private TestReport AddReport()
        {
            return new TestReport { IsSuccess = 0, TestMember = GetTestMember("Member 1"), Date = DateTime.Now() });            
        }
    
        public TestMember GetTestMember(string name)
        {
            return Context.TestMembers.Single(c => c.Name == name);
        }
    }
    

    Models

    public class TestReport
    {
        public int Id { get; set; }
        public TestMember TestMember { get; set; }
        public DateTime Date { get; set; }
        public bool IsSuccess{ get; set; }
    }
    
    public class TestMember
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string FileName { get; set; }
        public ICollection<TestRecipient> Recipients { get; set; }
    }
    

    1 个答案:

    答案 0 :(得分:0)

    对于将来遇到此错误的任何人,此修复程序都使用另一种模式来存储外键。使用SQL事件探查器,我确定当我将一个成员对象存储为用作Reports对象中的FK时,EF Core实际上在对数据库运行INSERT查询(因此错误消息指向了一个从未在代码中调用的表) )。

    旧报表模型

    public class TestReport
    {
        public int Id { get; set; }
        public TestMember TestMember { get; set; }
        public DateTime Date { get; set; }
        public bool IsSuccess{ get; set; }
    }
    

    新报告模型

    public class TestReport
    {
        public int Id { get; set; }
    
        public int? TestMemberId { get; set; }
    
        [ForeignKey(nameof(TestMemberId))]
        public virtual TestMember TestMember { get; set; }
    
        public DateTime Date { get; set; }
    
        public bool IsSuccess { get; set; }
    }
    

  • 这样,每当您要将TestMember对象存储在TestReport对象中时,只需将ID存储在TestMemberId字段中即可。
  • 每当您想从TestMember对象中获取TestReport对象时,只需使用Id作为谓词,然后在LINQ中使用.Include(x => x.TestMember)(如果重新使用LINQ很明显)

    希望对您有所帮助!

  • 相关问题