既存のデータベース(SQL Server 2012)にEntity Frameworkを実装しようとしています。 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'に挿入できません。列はnullを許可しません。INSERTは失敗します。\ r\nステートメントが終了しました。」} System.Exception {System.Data.SqlClient .SqlException}
基本的に、挿入トリガーは失敗します。変更できないこのデータベースに依存する別の既存のアプリケーションがあるため、データベースオブジェクトを変更できません。
挿入トリガーを無効にすると、保存が正常に完了します。
トリガーが失敗した理由は何ですか?
ほとんどの場合、sometable
へのJOINに問題があり、行が一致しないように除外されているため、@biInbndEquip_ID
変数が入力されることはありません。
ただし、それを修正しても、対処する必要がある大きな問題があります。トリガーロジックは、単一の行を処理するように記述されています。複数行のINSERTが実行されると、トリガーはMessage214Status
テーブルに配置するために挿入された値の1つのみを取得します。トリガーの@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];