You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET EDMX导入存储过程遗漏表类型参数及调用报错问题

问题原因及解决方案

1 关于EDMX无法导入表值参数的问题

EF 6及更早版本的EDMX设计器原生不支持自动导入包含表值参数(TVP)的存储过程,所以自动生成的方法会缺失表类型参数,属于已知限制,无需修改EDMX配置,直接用以下方案调用即可,无需手动管理连接状态。

2 可行实现代码

步骤1:构造符合要求的DataTable

注意必须显式指定列类型,和SQL自定义表类型定义完全匹配,可空字段需要将C#的null转换为DBNull.Value:

DataTable data = new DataTable();
// 列类型、列名必须和SQL自定义表类型完全对应
data.Columns.Add("LowerValue", typeof(decimal));
data.Columns.Add("HigherValue", typeof(decimal));
data.Columns.Add("UnitToDeliver", typeof(decimal));

foreach (SlidingScaleProtocol.Entry entry in formData.GetEntries()) {
    var row = data.NewRow();
    row.ItemArray = new object[] {
        entry.LowerValue,
        entry.HigherValue ?? DBNull.Value, // 可空字段必须转DBNull
        entry.UnitToDeliver
    };
    data.Rows.Add(row); // 不要遗漏将行添加到DataTable
}

步骤2:调用存储过程(EF自动管理连接)

使用EF内置的Database.ExecuteSqlCommand方法,无需手动开闭连接:

// 构造表值参数
var newEntriesParam = new SqlParameter("@newEntries", SqlDbType.Structured)
{
    TypeName = "oprSlidingScaleProtocolEntrySet", // 必须和SQL中定义的表类型名完全一致
    Value = data
};

// 执行存储过程
db.Database.ExecuteSqlCommand(
    "EXEC oprUpdateSlidingScaleProtocol @PrescriptionId, @newEntries",
    new SqlParameter("@PrescriptionId", prescriptionId),
    newEntriesParam
);

3 之前报错的原因说明

  • 直接用SqlCommand报错是因为你获取的EF上下文默认连接是关闭状态,EF仅在执行自身封装的方法时才会自动管理连接开闭,手动创建SqlCommand需要额外调用Open()方法,改用ExecuteSqlCommand即可避免该问题
  • ObjectContext.ExecuteFunction报错是因为ObjectParameter不支持Structured类型的表值参数,该方法本身不适用当前场景
  • 如果未指定DataTable的列类型,或者未将构造的行添加到DataTable,也会引发参数类型不匹配错误

内容的提问来源于stack exchange,提问作者B. Bergeron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:45:03