カスタム ORM を使用して EF 4.3 を使用するレガシー システムをアップグレード中です。
レガシ システムは、ハイブリッド '保存' ストアド プロシージャを使用します。これにより、プロシージャ自体が、主キーの存在に基づいて、エンティティを挿入または更新するかどうかを次のように決定します。
-- Hybrid Insert if not exist / Update if does exist
CREATE PROC dbo.SaveEntity
@EntityId INT = NULL, -- This field is specified on an update,
-- and left to its default on inserts
@Field1 NVARCHAR(50)
-- @Field2 etc etc
AS
BEGIN
-- IF Exists (Entity with PK @EntityId) then insert ...
-- BEGIN
-- INSERT INTO Entity(Field1, ...) VALUES (@Field1, ...)
-- SELECT @EntityId = SCOPE_IDENTITY()
-- END
-- ELSE
-- BEGIN
-- UPDATE Entity SET Field1 = @Field1, ... WHERE EntityId = @EntityId
-- END
-- Return the PK Here
SELECT @EntityId AS EntityId
END
EF では、「保存」ストアド プロシージャをモデルに追加し、それぞれのエンティティのマッピングの詳細で、挿入関数と更新関数の両方を「保存」プロシージャにマップしました。
Update 関数は問題なく動作します。返される結果は変わらないため、エンティティにマップし直す必要はありません。
ただし、挿入マッピングでキャッチ 22 状況に陥りました。Insert 関数では、SProc によって返された割り当てられた PK Identity 値をエンティティ PK にマッピングする必要があります。ただし、(オプションの @EntityId パラメーターを持つ) Proc の性質上、@EntityId がオプションであり、既定値であっても、EF ではすべてのパラメーターをマップする必要があります。
EntityId を PROC フィールドにマップしないと、コンパイル エラーが発生します。
A mapping function bindings specifies a function Model.Store.SaveEntity
but does not map the following function parameters: EntityId
そして、EntityId を proc フィールドにバインドし、結果列のバインドとして実行すると、実行時エラーが発生します (フィールドは入力マッピングまたは出力マッピングのいずれかのみであり、両方ではないため)。
Unable to determine a valid ordering for dependent operations.
Dependencies may exist due to foreign key constraints, model requirements,
or store-generated values.
だから私の質問は、どうすればこの状況を回避できますか? . たとえば、定数 (ゼロまたは NULL) を Insert Proc フィールド マッピングにバインドする方法はありますか?
注: これらの proc の一部には追加のロジック (ハウスキーピング、監査など) が含まれているため、それらを完全に破棄したり、PROCS を個別の INSERT / UPDATE procs に書き直したりするのは気が進まない。アップグレードの義務の一部ではありません。