【问题标题】:Getting .NET schema for a stored procedure result获取存储过程结果的 .NET 架构
【发布时间】:2011-02-14 05:03:17
【问题描述】:

我在 T-SQL 中有几个存储过程,其中每个存储过程都有一个固定的结果集架构。

我需要将每个过程的结果集映射到 POCO 对象,并且需要结果集中每一列的列名和类型。有没有快速获取信息的方法?

到目前为止,我发现的最好方法是从 .NET 访问每个存储过程,并在 IDataReader/IDataRecord 上编写我自己的扩展方法,以便将信息(列名和类型)转储出去。

例如,执行以下查询的存储过程:

SELECT Id, IntField, NullableIntField, VarcharField, DateField FROM SomeTable

需要我有映射信息:

Id - Guid
IntField - System.Int32
NullableIntField - Nullable<System.Int32>
VarcharField - String
DateField - DateTime

【问题讨论】:

    标签: c# .net sql-server tsql


    【解决方案1】:

    我认为您应该能够使用 SqlDataReader.GetSchemaTable 方法来访问架构。

    更多信息可以在这里找到。

    http://support.microsoft.com/kb/310107

    来自上述来源的示例

    SqlConnection cn = new SqlConnection();
    SqlCommand cmd = new SqlCommand();
    DataTable schemaTable; 
    SqlDataReader myReader; 
    
    //Open a connection to the SQL Server Northwind database.
    cn.ConnectionString = "Data Source=server;User ID=login;
                           Password=password;Initial Catalog=DB";
    cn.Open();
    
    //Retrieve records from the Employees table into a DataReader.
    cmd.Connection = cn;
    cmd.CommandText = "SELECT Id, IntField, NullableIntField, VarcharField, DateField FROM SomeTable";
    
    myReader = cmd.ExecuteReader(CommandBehavior.KeyInfo);
    
    //Retrieve column schema into a DataTable.
    schemaTable = myReader.GetSchemaTable();
    
    //For each field in the table...
    foreach (DataRow myField in schemaTable.Rows){
        //For each property of the field...
        foreach (DataColumn myProperty in schemaTable.Columns) {
        //Display the field name and value.
        Console.WriteLine(myProperty.ColumnName + " = " + myField[myProperty].ToString());
        }
        Console.WriteLine();
    
        //Pause.
        Console.ReadLine();
    }
    
    //Always close the DataReader and connection.
    myReader.Close();
    cn.Close();
    

    【讨论】:

    • 是的,这就是我计划在我的扩展方法中提取信息的方式。感谢您的建议
    【解决方案2】:

    我认为您正在做的可能是最好的方法。真的,没有一个神奇的存储库可以保存所有这些信息。您可以从系统目录视图中找到存储的 proc 参数,但遗憾的是,结果集的形状和字段名称和类型并未存储在 SQL Server 系统视图中的任何位置。

    【讨论】:

    • 感谢您对我理论的肯定。
    【解决方案3】:

    另一种选择(根据您的需要,可能比 GetSchemaTable() 更好或更差)。
    以下代码为您提供了一个列结构与您的结果集相同的 DataTable:

    DataTable table = new DataTable();
    var cmd = new SqlCommand("...");
    using (var reader = cmd.Execute(CommandBehaviour.SchemaOnly))
        table.Load(reader);
    

    【讨论】:

    • 这使用了已弃用的 SET FMTONLY ON(自 2012 年以来??)。见我上面的回答。
    • 我会说,由 MS 来相应地更改 Execute(CommandBehaviour.SchemaOnly) 的实现。
    【解决方案4】:

    如果这是您需要做的一次性事情,而不是每次调用该过程时您将在运行时做的事情,那么只需修改结果集查询以使用 INTO ThrowArayTable 将行转储到新表中:

    SELECT
        Col1, col2, col3, ...
        INTO ThrowArayTable     ----<<<add this line to existing result set query
        FROM ...
        WHERE ...
    

    运行应用程序或手动调用过程以生成 ThrowArayTable。您现在可以使用任何方法、SSMS 或 INFORMATION_SCHEMA.COLUMNS 来查找列 aames 和数据类型

    只需记住将过程改回来(删除INTO ThrowArayTable 值),这样它就会真正返回结果集。

    【讨论】:

    • 是的,很好的建议。我不知道访问类型信息的方法。缺点是我无权编辑存储过程,因为它们不在我的控制之下。此外,我还必须手动将列类型映射到相应的 .NET 类型,包括可为空的类型。
    • 谢谢。有时最简单的方法是最好的。这正是我想要的。我不知道为什么解决方案躲过了我。我猜是因为我在存储过程的上下文中考虑它。
    猜你喜欢
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多