Вывод результатов хранимой процедуры

1

Извините, если это несколько элементарный вопрос....net newb здесь бросили в глубокий конец.

Я создал хранимую процедуру для возврата записи, которую я выполняю, как показано ниже. Когда я проверяю "r" с точкой останова в Express Studio Express, мои данные возвращаются правильно.

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%> Я прав в этом или потребует каких-либо дополнительных шагов?

Пожалуйста, дайте мне знать, если я пропустил какую-либо важную информацию здесь.

  • 1
    Честный совет - особенно если вы изучаете .net, так что, надеюсь, вам легче выработать хорошую / плохую привычку. Попробуйте использовать более описательные имена переменных - нет причин минимизировать C #.
Теги:
visual-studio-express

2 ответа

3

Используйте адаптер данных, чтобы заполнить таблицу данных и вернуть их. Если ваша хранимая процедура возвращает только данные, которые необходимы. Я не вижу причин перебирать каждый столбец и явно определять их. SqlDataAdapter заполнит DataTable для вас без жесткого кодирования и добавления значений строк.

Здесь есть некоторые примеры чтения и примеры SqlDataAdapters.

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();
    }
}
  • 0
    что именно это достигнет, кроме как пойти против SOLID?
  • 0
    @decPL Как именно это «пойти ... против SOLID»?
Показать ещё 5 комментариев
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;
}
  • 0
    Поскольку OP является новинкой в .NET, было бы полезно пойти дальше и показать ему директиву using .
  • 1
    @decPL Разумный комментарий, спасибо. Я обновил ответ.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню