EF 7身份插入问题



我必须能够设置我试图在我的列表"final_zones"中添加的实体的主键。我有一个控制器构造函数如下:

    public UtilController(CFETSContext context)
    {
        _context = context; 
    }
     ......Then in a web api method.........
        using (var transaction = _context.Database.BeginTransaction())
        {
            _context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [CFETSWeb].[dbo].[Zone] ON");             
            _context.SaveChanges();
            transaction.Commit();
        }

       using (var transaction = _context.Database.BeginTransaction())
        {             
            _context.Zones.AddRange(final_zones);
            _context.SaveChanges(); //ERROR HERE
            transaction.Commit();
        }

无论我做什么,我似乎不能得到IDENTITY_INSERT打开。我得到以下错误:

{"Cannot insert explicit value for identity column in table 'Zone' when IDENTITY_INSERT is set to OFF."}

我好像就是关不掉它。我可以将实体添加到控制器中的DB中,这样我就知道其他一切都在工作。我试过在没有事务的情况下这样做,结果也是一样的。

 _context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [CFETSWeb].[dbo].[Zone] ON"); 
_context.Zones.AddRange(final_zones);
        _context.SaveChanges();

任何想法?我不知道下一步该做什么。谢谢。

我用以下方法解决了这个问题:

       using (var dbContextTransaction = _context.Database.BeginTransaction())
        {
            try
            {
                _context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [CFETSWeb].[dbo].[Zone] ON");
                _context.Zones.AddRange(final_zones);
                _context.SaveChanges();          
                dbContextTransaction.Commit();
            }
            catch (Exception e)
            {
                dbContextTransaction.Rollback();
            }
        }

注意:您必须对每个表执行此操作。IDENTITY_INSERT似乎一次只能为一个表设置,所以您可以这样做,也可以在同一事务中将其切换为OFF。

另外,IDENTITY_INSERT必须在事务中,因为它只在事务期间保持打开状态。

SET IDENTITY_INSERT语句的作用域是一个SQL会话,这实际上相当于在一个打开的连接上发送的一组语句。

然而,默认情况下,EF上下文将为它执行的每个数据库交互语句打开和关闭一个连接。因此在ExecuteSqlCommand语句之后,连接被关闭,IDENTITY_INSERT被重置。

现在有一个隐藏的特性,EF 不会关闭连接如果你在上下文执行语句之前打开它。所以如果你这样做…

try
{
    _context.Database.Connection.Open();
    _context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [CFETSWeb].[dbo].[Zone] ON");
    _context.Zones.AddRange(final_zones);
    _context.SaveChanges();
}
finally
{
    _context.Database.Connection.Close();
}

…您将注意到IDENTITY_INSERT设置将在ExecuteSqlCommand语句中"存活"。

最新更新