输出存储过程结果

时间:2014-12-10 14:25:11

标签: c# .net visual-studio-express

道歉,如果这是一个基本问题...... .net newb在这里投入了深层次。

我创建了一个存储过程来返回我正在执行的记录,如下所示。当我在Visual Studio Express中使用断点检查“r”时,我的数据会正确返回。

MyPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{

    var dd = dealerDetails();
}

protected DataTable dealerDetails()
{
    SqlConnection cn;
    SqlCommand cmd;

    using (cn = new SqlConnection(Settings.Server.ConnectionString))
    {
        cn.Open();
        cmd = new SqlCommand("spMyStoredProcedure", cn);
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add("@strslug", SqlDbType.NVarChar, -1).Value = Page.Request.QueryString["_slug"];
        JJ.Diagnostics.Tracer.Trace(cmd);
        try
        {
            IDataReader r = cmd.ExecuteReader();
            while (r.Read())
            {
                ??????
            }

            r.Close();
            return ?????;

        }
        catch (SqlException exSql)
        {
            // Make an event log entry of the exception
            EventLogController.LogException(exSql);
            throw;
        }
        catch (Exception ex)
        {
            // Make an event log entry of the exception
            EventLogController.LogException(ex);
            throw;
        }

    }


}

当我只是尝试返回r时,我收到一个错误:

  

无法将类型'System.Data.IDataReader'明确地转换为'System.Data.DataTable'。   存在明确的转换(您是否错过了演员?)

我希望能够在MyPage.aspx中访问此存储过程的结果。我假设我可以使用<%=dd.propname%>执行此操作,我是否更正或是否需要执行其他步骤?

如果我在这里遗漏了任何重要信息,请告诉我。

2 个答案:

答案 0 :(得分:3)

使用数据适配器填充数据表并返回该数据表。如果存储过程仅返回所需的数据。我没有看到任何理由迭代每一列并明确定义它们。 SqlDataAdapter将为您填充DataTable,无需硬编码并添加行值。

HERESqlDataAdapters的一些阅读和示例。

using (SqlDataAdapter da = new SqlDataAdapter(cmd, cn)
{
    DataTable dt = new DataTable("TableName");
    da.Fill(dt);
    return dt;
}

整个代码:

// Utilize the using directive on any disposable objects so you aren't 
// left with garbage.
using (SqlConnection cn = new SqlConnection(Settings.Server.ConnectionString))
using (SqlCommand cmd = new SqlCommand("spMyStoredProcedure", cn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    // define your parameter here, just personal preference, but makes debugging 
    //easier in my opinion.
    string slug = Page.Request.QueryString["_slug"];
    // Use the newer .AddWithValue command.
    cmd.Parameters.AddWithValue("@strslug", slug);
    JJ.Diagnostics.Tracer.Trace(cmd);

    try
    {
        // SqlDataAdapter will automatically open/close your connection for you, 
        // however, for future reference, try to open your connection only when 
        // it is required to be opened. This will reduce your connection time/
        // server strain.
        // cn.Open();
        using (SqlDataAdapter da = new SqlDataAdapter(cmd, cn)
        {
            // Data adapter will automatically fill your returned data table.
            DataTable dt = new DataTable("TableName");
            da.Fill(dt);
            return dt;
        }
    }
    catch (SqlException exSql)
    {
        // Make an event log entry of the exception
        EventLogController.LogException(exSql);
        throw;
    }
    catch (Exception ex)
    {
        // Make an event log entry of the exception
        EventLogController.LogException(ex);
        throw;
    }
}

从这一点开始,您可以像这样访问您的数据:

protected void Page_Load(object sender, EventArgs e)
{
    DataTable dd = dealerDetails();
    // if more than one row is expected you can use the for loop
    // if not, just access them directly.
    for (int i = 0; i < d.Rows.Count - 1; i++)
    {
        // Jump straight to here if you are positive you will only 
        // return 1 row of data.
        string ColumnName1 = dd.Rows[i]["ColumnName1"].ToString();
        string ColumnName2 = dd.Rows[i]["ColumnName2"].ToString();
    }
}

答案 1 :(得分:2)

根据您的dealerDetails方法签名 - 返回值为DataTable。因此,您无法返回DataReader,因为它不是从DataTable派生的。

您需要创建DataTable及其列,并在从dataReader读取时填充表。

像这样的东西

using(var r = cmd.ExecuteReader())
{
    var dt = new DataTable();
    dt.Columns.Add("Column1_Name", typeof(column1_Type));
    dt.Columns.Add("Column2_Name", typeof(column2_Type));

    while (r.Read())
    {
        var dro = dt.NewRow();
        dro["Column1_Name"] = somevalue_from_reader;
        dro["Column2_Name"] = somevalue_from_reader;
        dt.Rows.Add(dro);
    }

    r.Close();
    return dt;
}