实体框架4.2,无法设置身份插入

本文关键字:设置 身份 插入 框架 实体 | 更新日期: 2023-09-27 18:10:49

我想将记录批量添加到具有给定ID的表中,以便我可以构建用于以树视图方式显示记录的层次结构。我可以单独添加记录,这很好,我不设置ID。我想只批量设置id,所以我将id列中的DatabaseGenerated选项设置为None,我的实体为None

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
     foreach (ErrorCode ec in errorCodesStep3.errorcodesUsers)
     {
           errorCode.ID = ec.ID;
           errorCode.ParentID = ec.ParentID;
           errorCode.ErrorDescription = ec.ErrorDescription;
           db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ErrorCode ON");
           db.ErrorCode.Add(errorCode);
           db.SaveChanges();    
           scope.Complete();
     }
}

错误代码

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }

我得到的错误是:

当标识插入为OFF时

不能设置标识。

不知道什么是错的,因为我看到的例子,身份插入可以打开。我使用EF版本4.2.0.0和运行时版本v4.0.30319。我可以通过带有参数化变量的executeSQL轻松添加INSERT语句,但我想用实体框架来做。似乎db.Database.ExecuteSqlCommand在一个单独的作用域中,它立即关闭,当db.savechanged执行时不可用。

实体框架4.2,无法设置身份插入

Try this: Entity Framework with Identity Insert

也许是这样:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
    using (var db = new Context()) // your Context
    {
        db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ErrorCode ON");
        ErrorCode errorCode = db.ErrorCode.First(); // for example
        foreach (ErrorCode ec in errorCodesStep3.errorcodesUsers)
        {
            errorCode.ID = ec.ID;
            errorCode.ParentID = ec.ParentID;
            errorCode.ErrorDescription = ec.ErrorDescription;    
            db.ErrorCode.Add(errorCode);
        }
        db.SaveChanges();
        db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ErrorCode OFF");
        scope.Complete();
    }
}

我遇到了同样的问题,我们有一个表,它的身份被设置。然后我们需要将标识转换为false,(我的意思是将其设置为如下)

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }

但是,在完成迁移和更新数据库之后,这不起作用。在谷歌上搜索了这个问题之后,我写了这篇文章这表明切换ON/OFF标识不是一个简单的操作,并且现在不被实体框架支持。

所以解决方案(对我有效)是以下

在Visual Studio中打开设计器视图中的表,选择代表主键的列,(在你的情况下是"ID"),然后从属性面板中找到"Identity Specification"属性(它的值必须为true),将其设置为false,不要忘记更新表,通过单击update按钮在表上执行SQL语句。(更新按钮存在于表工具栏中)

然后试着运行你的代码,它应该工作。

我希望这是有帮助的。如果您有任何问题,请告诉我。

这是我验证了你想要的代码。这个想法是为ExecuteSqlCommand和插入操作使用单个连接,似乎BeginTransaction()调用做到了这一点:

using (var db = new TestEntities()) { 
    using (var tran = db.Database.BeginTransaction()) {
       db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Error ON");
            foreach (var id in Enumerable.Range(1, 20)) {
                var ec = new Error();
                ec.ErrorID = id;
                db.Errors.Add(ec);
            }
            db.SaveChanges();
            db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Error OFF");
            tran.Commit();
        }
    }
}

添加另一列来管理层次结构。标识列不应用于此目的。

对不起,我没有回答这个问题,但我认为你的解决方案不正确。