EF CF 4.2和SQL而不是插入触发器

时间:2012-01-28 13:06:28

标签: sql-server entity-framework concurrency triggers ef-code-first

我有一个CF课程:

public class A
{
  [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int Id {get;set;}
  [Required]
  public string Name {get;set;}
  public string LoweredName {get;set;}
  [Timestamp]
  public byte[] RowVersion {get;set;}
}

在数据库中我有一个触发器:

CREATE TRIGGER IOI_LoweredName
   ON  Abc
   INSTEAD OF INSERT
AS; 
BEGIN;
    SET NOCOUNT ON;

    INSERT INTO Abc(Name, LoweredName) SELECT Name, LOWER(Name) FROM inserted
END;

现在,如果我尝试插入记录:

dc.Names.Add(new A { Name = "Test" });
dc.SaveChanges();

我收到以下错误:

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

任何想法如何解决这个问题? 我的所有类都继承自具有RowVersion(Timestamp)列的基类。在时间戳字段上使用并发时,我不能使用EF这么简单的触发器吗?

更新

有一个主键(也将其添加到上面的示例中)。

更新2

这来自SQL Profiler:

declare @0 nvarchar(100)
set @0=N'Test'
insert [dbo].[abc]([Name], [LoweredCompanyName]) values (@0, null)
select [Id], [RowVersion] from [dbo].[Abc] where @@ROWCOUNT > 0 and [Id] = scope_identity()

问题是select不会返回任何内容。

3 个答案:

答案 0 :(得分:1)

该实体没有主键。 EF不喜欢它。

要修复当前错误,请尝试在触发器结束时添加此错误:

SELECT @@ROWCOUNT

如果您更改代码以支持自动生成的PK,您将使用此代码:

SELECT SCOPE_IDENTITY()

我不确定这是否真的可以使用而不是触发器,但是在将存储过程映射到EDMX中的修改操作时是必要的。

目前有可能这个操作将由EF直接执行,但它不会计算触发器创建或修改的记录,因为触发器在不同的范围内执行 - 这可能是一个大问题。

答案 1 :(得分:1)

@ Patrick

试试这个

SELECT SCOPE_IDENTITY() as [EXAMPLE]

其中[EXAMPLE]是标识列的名称

我遇到了同样的问题,这对我有用。

答案 2 :(得分:1)

CREATE TRIGGER IOI_LoweredName 
   ON  Abc 
   INSTEAD OF INSERT 
AS;  
BEGIN; 
    SET NOCOUNT ON; 

    INSERT INTO Abc(Name, LoweredName)
    OUTPUT INSERTED.Id,INSERTED.RowVersion,
    SELECT Name, LOWER(Name) 
    FROM inserted 
END;