.NET - EDMX/Auto-generated DbContext 在过程导入期间跳过 table 类型的参数

.NET - EDMX/Auto-generated DbContext skips table-type parameters during procedure import

我有以下 SQL 程序和类型:

CREATE TYPE oprSlidingScaleProtocolEntrySet AS TABLE (
    LowerValue DECIMAL(4,2) NOT NULL,
    HigherValue DECIMAL(4,2),
    UnitToDeliver DECIMAL(18,4) NOT NULL);
GO

CREATE PROCEDURE oprUpdateSlidingScaleProtocol
    @PrescriptionId INT,
    @newEntries oprSlidingScaleProtocolEntrySet READONLY
-- ...

使用 Entity Framework 的 EDMX,我应该能够将程序作为 C# 函数导入,包括参数。但这是 EDMX 的结果:

public virtual int oprUpdateSlidingScaleProtocol(Nullable<int> prescriptionId)

newEntries 丢失,也许导入数据类型参数超出了 EF 的能力? 我尝试使用 SqlCommand class 代替,但在运行时出现以下异常:

DataTable data = new DataTable("oprSlidingScaleProtocolEntrySet");
data.Columns.Add("LowerValue");
data.Columns.Add("HigherValue");
data.Columns.Add("UnitToDeliver");
// (populate table)
var sqlCmd = new SqlCommand("oprUpdateSlidingScaleProtocol", (SqlConnection)db.Database.Connection) {
    CommandType = CommandType.StoredProcedure
};
sqlCmd.Parameters.AddWithValue("@prescriptionId", prescriptionId);
SqlParameter paramNewEntries = sqlCmd.Parameters.AddWithValue("@newEntries", data);
paramNewEntries.SqlDbType = SqlDbType.Structured;

sqlCmd.ExecuteNonQuery(); // RUNTIME ERROR: System.InvalidOperationException: 'ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.'

这很奇怪,但我不想弄乱古怪的连接,所以我继续使用自动生成的 DbContext:[=22 中使用的相同方法编写自己的过程导入=]

((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext.ExecuteFunction(
    "oprUpdateSlidingScaleProtocol",
    new ObjectParameter("prescriptionId", prescriptionId),
    new ObjectParameter("newEntries", data)
);

但我得到以下异常:

System.InvalidOperationException: 'The DbType 'Object' is not valid for the EntityParameter.DbType property on the 'newEntries' object.'

我的代码中唯一的 object 是那些用于定义“数据”的代码:

foreach (SlidingScaleProtocol.Entry entry in formData.GetEntries()) {
    var row = data.NewRow();
    row.ItemArray = new object[] {
        entry.LowerValue,
        entry.HigherValue,
        entry.UnitToDeliver
    };
}

但是我需要这些对象来创建我的行!

关于该主题的文档非常有限,所以我不确定我还应该尝试什么。有什么解决方案或想法吗?

您必须在 运行 SqlCommands 之前打开连接。

db.Database.Connection.Open();
var sqlCmd = new SqlCommand("oprUpdateSlidingScaleProtocol", (SqlConnection)db.Database.Connection) {
    CommandType = CommandType.StoredProcedure
};

当 DbContext 被释放时,EF 会为您关闭连接。