0

我们正在升级具有自定义 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 中,我已将“保存”存储过程添加到模型中,并将插入和更新函数映射到各个实体的映射详细信息中的“保存”过程。

更新函数工作正常 - 因为返回结果没有改变,它不需要映射回实体。

但是,我遇到了使用 Insert 映射的 catch-22 情况。对于插入函数,我需要将 SProc 返回的分配的 PK 标识值映射回实体 PK。但是,由于 Proc 的性质(具有可选的 @EntityId 参数),EF 还要求映射所有参数,即使 @EntityId 是可选的并且是默认的。

如果我未能将 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 字段映射?

请注意:其中一些 procs 中有额外的逻辑(内务管理、审计等),所以我不愿意完全放弃它们,或者将 PROCS 重写为单独的 INSERT / UPDATE procs,因为它们已经过充分证明并改变了底层的 DB DDL不是我们升级任务的一部分。

4

0 回答 0