Sql-Server
由於觸發器,實體框架 SaveChanges 失敗
嘗試為現有數據庫(SQL Server 2012)實現實體框架。我有一個 VB 應用程序正在執行並試圖將其轉換為基於 EF 的 Web API。
當我將數據插入到列中
InboundEquipment
時InboundEquipmentID
。IDENTITY
我也有這個表的插入觸發器,用於InboundEquipmentID
插入另一個表Message214Status
。這些表之間沒有 FK 關係。數據庫對象:
CREATE TABLE [dbo].[InboundEquipment]( [InboundEquipmentID] [bigint] IDENTITY(1,1) NOT NULL, ... CREATE TABLE [dbo].[Message214Status]( [InboundEquipmentID] [bigint] NOT NULL, ... ALTER TRIGGER [dbo].[InboundEquipment] ON [dbo].[InboundEquipment] FOR INSERT AS DECLARE @biInbndEquip_ID BIGINT, @iCust_ID INT, ... SELECT @biInbndEquip_ID= InboundEquipmentID,@iCust_ID= c.Cust_ID, ... FROM INSERTED I JOIN sometable c WITH(NOLOCK)ON ... INSERT INTO dbo.Message214Status (InbndEquip_ID, Cust_ID) VALUES (@biInbndEquip_ID,@iCust_ID ) ...
我的 VB 程式碼:
db.InboundEquipment.Add(ibData); try { db.SaveChanges(); var IBEquipID = ibData.InboundEquipmentID; } catch (Exception ex) { return ResponseMessage(Request.CreateErrorResponse (HttpStatusCode.InternalServerError, "ERROR:" + ex.Message)); } public partial class InboundEquipment { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long InboundEquipmentID { get; set; } ...
DBContext.db.SaveChanges()
失敗並出現此異常:InnerException {“無法將值 NULL 插入列 ‘InboundEquipmentID’,表 ‘dbo.Message214Status’;列不允許空值。INSERT 失敗。\r\n語句已終止。”} System.Exception {System.Data.SqlClient .SqlException}
基本上插入觸發器失敗。我無法更改數據庫對象,因為有另一個依賴於無法更改的數據庫的現有應用程序。
當我禁用插入觸發器時,保存成功完成。
觸發失敗的原因可能是什麼?
JOIN 很可能存在問題,
sometable
即從匹配中過濾掉任何行,因此該@biInbndEquip_ID
變數永遠不會被填充。然而,即使你解決了這個問題,你仍然有一個更大的問題需要處理:你的觸發邏輯是為了處理單行而編寫的。如果完成了多行 INSERT,則觸發器只會抓取插入到
Message214Status
表中的值之一。去掉觸發器中的@biInbndEquip_ID
,@iCust_ID
, 等局部變數,改寫成簡單的INSERT...SELECT
. 例如:INSERT INTO dbo.Message214Status (InbndEquip_ID, Cust_ID, ...) SELECT ins.[InboundEquipmentID], ins.[CustID], ... FROM INSERTED ins INNER JOIN sometable c ON c.[join_column] = ins.[join_column];