EF Core 使用许多用户定义的表类型执行过程

Posted

技术标签:

【中文标题】EF Core 使用许多用户定义的表类型执行过程【英文标题】:EF Core execute procedure with many User-Defined Table Type 【发布时间】:2021-10-29 10:41:13 【问题描述】:

您好,我在 EF Core 中执行存储过程时遇到问题。 程序有3个参数: Procedure

用户定义的表类型如下所示: User-Defined Table Type

当我尝试执行程序时,我总是出错:

找不到与 CLR 类型“SqlParameter[]”的关系类型的映射。

C#代码:

            List<SqlParameter> parameters = new List<SqlParameter>(); ;
        parameters.Add(
            new SqlParameter("@id_zmiennej", 138)
            
                SqlDbType = SqlDbType.Int
            
        );
        using (var dt = new DataTable())
        
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("wartosc", typeof(int));
            DataRow dr = dt.NewRow();
            dr["id"] = 2010;
            dr["wartosc"] = 2010;
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr["id"] = 2011;
            dr["wartosc"] = 2011;
            dt.Rows.Add(dr);

            SqlParameter parameter = new SqlParameter("@lata", dt)
            
                SqlDbType = SqlDbType.Structured,
                TypeName = "[dbo].[TabIntType]"
            ;
            parameters.Add(parameter);
        
        using (var dt = new DataTable())
        
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("wartosc", typeof(int));
            DataRow dr = dt.NewRow();
            dr["id"] = 10;
            dr["wartosc"] = 10;
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr["id"] = 11;
            dr["wartosc"] = 11;
            dt.Rows.Add(dr);
            SqlParameter parameter = new SqlParameter("@okresy", dt)
            
                SqlDbType = SqlDbType.Structured,
                TypeName = "[dbo].[TabIntType]"
            ;
            parameters.Add(parameter);           
        
        var data = _context.Data.FromSqlRaw("dbo.GetData 0", parameters).ToList();

有人可以帮我解决这个问题吗?

【问题讨论】:

您似乎在混合使用 EntityFramework 和非 EF 方法。虽然您可以在 EF 中调用 SPROC,但您似乎只是在使用 EF 来提供连接字符串。 这能回答你的问题吗? How to use the Procedure with User Defined Table Type in Entity Framework 我可以看到的问题:你需要FromSqlRaw("dbo.GetData 0", parameters.ToArray&lt;object&gt;())。不要丢弃DataTable,这是不必要的,会导致它在执行命令之前被清空。您还需要设置parameter.Direction = ParameterDirection.Input; 谢谢@Charlieface,我只需添加Direction = ParameterDirection.Input; 并将_context.Data.FromSqlRaw("dbo.GetData 0", parameters).ToList(); 更改为_context.Data.FromSqlRaw("dbo.GetData 0,1,2", parameters.ToArray()).ToList();,它就开始工作了。 【参考方案1】:

您将参数作为List&lt;SqlParameter&gt; 传递,而FromSqlRaw 需要SqlParameter[] 数组(或可变长度params)。所以你需要把它转换成一个数组。

另外,你有三个参数并且只传递一个,理想情况下你应该按名称传递

FromSqlRaw(@"
EXEC dbo.GetData
  @id_zmiennej = 0,
  @lata = 1,
  @okresy = 2;
", parameters.ToArray<object>())

另一个问题:你应该在 TVP 参数上设置Direction

        SqlParameter parameter = new SqlParameter("@lata", dt)
        
            SqlDbType = SqlDbType.Structured,
            TypeName = "[dbo].[TabIntType]",
            Direction = ParameterDirection.Input,
        ;

【讨论】:

以上是关于EF Core 使用许多用户定义的表类型执行过程的主要内容,如果未能解决你的问题,请参考以下文章

MsSQL 未使用 sp_executesql 传递用户定义的表类型

在 SQL Server Management Studio 中使用执行过程 - 如何格式化用户定义的表类型的值?

EF Core从TPH迁移到TPT

如何使用EF Core Code-First桥接自己的表

如何使用 EF Core 5 执行存储过程 ORACLE?

EF Core 执行sql语句