Entity Framework 存储过程表值参数
Entity Framework 本身并不直接支持向存储过程传递表值参数。但是,可以使用 ObjectContext
的 ExecuteStoreQuery
方法来实现变通方案。
以上代码中,存储库中存在一个通用的 ExecuteStoredProcedure
方法:
<code class="language-csharp">public IEnumerable<T> ExecuteStoredProcedure<T>(string procedureName, params object[] parameters) { StringBuilder command = new StringBuilder(); command.Append("EXEC "); command.Append(procedureName); command.Append(" "); // 为每个传入的参数添加占位符 for (int i = 0; i < parameters.Length; i++) { if (i > 0) command.Append(","); command.Append("{" + i + "}"); } return this.context.ExecuteStoreQuery<T>(command.ToString(), parameters); }</code>
使用此方法传递表值参数时,可能会出现错误,例如“表类型参数 p6 必须具有有效的类型名称”。要解决此问题,必须将 SqlDbType
指定为 Structured
,并将 SqlParameter.TypeName
设置为数据库中用户定义类型 (UDT) 的名称。
但是,即使进行了这些修改,您仍然可能会遇到与无效语法相关的错误。
自定义扩展方法
ObjectContext
类的一个自定义扩展方法可以简化此过程:
<code class="language-csharp">public static void ExecuteStoredProcedure(this ObjectContext context, string storedProcName, params object[] parameters) { string command = "EXEC " + storedProcName + " @caseid, @userid, @warnings"; context.ExecuteStoreCommand(command, parameters); }</code>
此扩展方法允许您直接使用表值参数调用存储过程。示例用法如下:
<code class="language-csharp">var entities = new NewBusinessEntities(); var dt = new DataTable(); dt.Columns.Add("WarningCode"); dt.Columns.Add("StatusID"); dt.Columns.Add("DecisionID"); dt.Columns.Add("Criticality"); dt.Rows.Add("EO01", 9, 4, 0); dt.Rows.Add("EO00", 9, 4, 0); dt.Rows.Add("EO02", 9, 4, 0); var caseId = new SqlParameter("caseid", SqlDbType.Int); caseId.Value = 1; var userId = new SqlParameter("userid", SqlDbType.UniqueIdentifier); userId.Value = Guid.Parse("846454D9-DE72-4EF4-ABE2-16EC3710EA0F"); var warnings = new SqlParameter("warnings", SqlDbType.Structured); warnings.Value = dt; warnings.TypeName = "dbo.udt_Warnings"; entities.ExecuteStoredProcedure("usp_RaiseWarnings_rs", userId, warnings, caseId);</code>
限制条件
使用此扩展方法或类似的自定义方法时,请考虑以下限制:
以上是如何将表值参数传递给实体框架中的存储过程?的详细内容。更多信息请关注PHP中文网其他相关文章!