如果table已定义触发器,则实体框架将抛出​​DBUpdateConcurrencyException

时间:2017-08-29 10:33:29

标签: asp.net sql-server entity-framework

在ASP.NET中支持实体框架和SQL Server 2014作为数据库引擎的RESTful服务时,我遇到了一些意想不到的障碍。

我准备了一些虚拟案例,它准确地解释了我现在遇到的问题。

我在SQL Server中有一个名为“dummy_database”的数据库。它只包含一个表 - Person - 和一个触发器 - TR_Person_Insert - 它负责在将记录添加到“Person”表之前,将一些额外数据(在这种特定情况下的当前日期和时间)添加到每个记录。数据库结构代码包括在下面:

USE dummy_database;
GO

IF EXISTS (SELECT * FROM sys.tables WHERE name LIKE 'person')
    DROP TABLE [person];
GO

IF EXISTS (SELECT * FROM sys.triggers WHERE name LIKE 'TR_Person_Insert')
    DROP TRIGGER [TR_Person_Insert];
GO

CREATE TABLE [dbo].[person]
(
    [id] INT IDENTITY(1, 1),
    [name] NVARCHAR(256) NOT NULL,
    [surname] NVARCHAR(256) NOT NULL,
    [age] INT NOT NULL,
    [valid_from] DATETIME2 (7),

    CONSTRAINT PK_Person_ID PRIMARY KEY ([id])
)
GO

CREATE TRIGGER TR_Person_Insert ON [dbo].[person]
INSTEAD OF INSERT
AS
BEGIN
    INSERT INTO [dbo].[person] ([name], [surname], [age], [valid_from])
    SELECT i.[name], i.[surname], i.[age], GETDATE()
    FROM inserted i
END
GO

然后我使用ASP.NET创建了虚拟RESTful服务,并添加了Entity Framework和Database First方法。该服务的唯一现有方法的代码如下:

[RoutePrefix("api/person")]
public class DummyController : ApiController
{
    [HttpPost, Route("")]
    public IHttpActionResult AddPerson(PersonDto data)
    {
        using (var ctx = new DummyDatabaseModel())
        {
            var person = new person
            {
                name = data.Name,
                surname = data.Surname,
                age = data.Age
            };

            ctx.people.Add(person);
            ctx.SaveChanges();
        }

        return Ok();
    }
}

问题在于在数据库的上下文中调用保存更改方法。此方法抛出DBUpdateConcurrencyException异常,并提供以下附加信息:

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException' occurred in EntityFramework.dll but was not handled in user code

Additional information: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.

我知道这个异常是由触发器引起的,触发器在数据库端被触发而不是常规的'insert'例程。

我问的问题是 - 如何在不放弃数据库触发器的情况下摆脱这种异常。如果您在过去遇到同样的问题,我会缺乏想法并坦率地说 - 我依靠您的提示或解决方案。

感谢您的帮助。

0 个答案:

没有答案