道歉,如果这是一个基本问题...... .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%>
执行此操作,我是否更正或是否需要执行其他步骤?
如果我在这里遗漏了任何重要信息,请告诉我。
答案 0 :(得分:3)
使用数据适配器填充数据表并返回该数据表。如果存储过程仅返回所需的数据。我没有看到任何理由迭代每一列并明确定义它们。 SqlDataAdapter
将为您填充DataTable
,无需硬编码并添加行值。
HERE是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();
}
}
答案 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;
}