拦截并重写Entity Framework INSERT语句

时间:2014-01-14 15:54:23

标签: c# sql-server entity-framework

tl; dr

我正在使用EF将项目插入可更新的视图,而不是表格。 EF不能很好地处理这种情况,但如果我可以在SQL发送到数据库之前重新编写SQL,这是一个简单的修复。任何人都知道我是否有任何地方可以注入一些重写代码?

深度

我有一个名为[VW_Item]的视图,而不是名为[Item]的表。

当我尝试插入时,Entity Framework会像这样生成SQL;

01 exec sp_executesql N'INSERT [dbo].[vw_Item]([ItemName]) VALUES (@0)
02 SELECT [ItemId] FROM [dbo].[vw_Item]
03 WHERE @@ROWCOUNT > 0 AND [ItemId] = scope_identity()',N'@0 nvarchar(256)',@0=N'my item name'
EF似乎像这样工作;

  1. 在线01,插入新记录
  2. 在线02,使用scope_identity()找出刚刚插入的记录的ID。
  3. 但是,由于我正在插入视图,并且涉及INSTEAD OF INSERT触发器,scope_identity()最终为NULL,而不是我的新记录的ID。 EF感到困惑并认为插入失败了。

    我可以轻松地重写这样的代码;

    01 exec sp_executesql N'INSERT [dbo].[vw_Item]([ItemName]) VALUES (@0)
    02 SELECT [ItemId] FROM [dbo].[vw_Item]
    03 WHERE @@ROWCOUNT > 0 AND [ItemId] = (select top(1) ItemId from [vw_Item])',N'@0 nvarchar(256)',@0=N'my item name'
    

    所以在03行的末尾有一个小的改动。但是,我找不到改变发送到服务器的INSERT语句的方法。有人有任何想法吗?

1 个答案:

答案 0 :(得分:0)

在模型上,更改Item实体的映射以使用已添加到模型中的函数(作为存储过程)。

然后,您可以完全控制用于插入/更新/删除实体的sql。 一句警告:如果你改变了一个映射,你必须提供它们 - 你不能使用auto-sql进行更新/删除和插入函数映射。