C# 输出存储过程结果
如果这是一个基本的问题,我道歉。这里的网络新手被扔到了深水区 我创建了一个存储过程来返回我正在执行的记录,如下所示。当我在VisualStudioExpress中使用断点检查r时,数据将正确返回 MyPage.aspx.csC# 输出存储过程结果,c#,.net,visual-studio-express,C#,.net,Visual Studio Express,如果这是一个基本的问题,我道歉。这里的网络新手被扔到了深水区 我创建了一个存储过程来返回我正在执行的记录,如下所示。当我在VisualStudioExpress中使用断点检查r时,数据将正确返回 MyPage.aspx.cs protected void Page_Load(object sender, EventArgs e) { var dd = dealerDetails(); } protected DataTable dealerDetails() { SqlCon
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中此存储过程的结果。我假设我可以用我的回答来做这件事,我的回答是正确的还是需要额外的步骤
如果我在这里输入了任何重要信息,请告诉我。根据您的DealDetails方法签名-返回值为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;
}
根据您的DealDetails方法签名-返回值为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;
}
使用数据适配器填充数据表并返回该数据表。如果存储过程仅返回所需的数据。我不认为有任何理由遍历每一列并显式定义它们。SqlDataAdapter将为您填充数据表,而无需硬编码和添加行值 是SqlDataAdapters的一些阅读和示例 完整代码:
// 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();
}
}
使用数据适配器填充数据表并返回该数据表。如果存储过程仅返回所需的数据。我不认为有任何理由遍历每一列并显式定义它们。SqlDataAdapter将为您填充数据表,而无需硬编码和添加行值 是SqlDataAdapters的一些阅读和示例 完整代码:
// 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();
}
}
这是一条真诚的建议——尤其是因为你正在学习.net,所以希望你能更容易地养成好习惯/坏习惯。请尝试使用更具描述性的变量名-没有理由缩小C。这是一条诚实的建议-尤其是因为您正在学习.net,所以希望您更容易养成好习惯/坏习惯。尽量使用更具描述性的变量名-没有理由缩小C。因为OP对.NET来说是新的,所以增加长度并向他显示using指令可能会有用。@AndyKorneyev或只做dt.Loadr;非常感谢。在这种情况下,返回数据表是正确的方法还是有更好的方法?我根本不受限于使用datatable,我遇到了一个示例,并以这种方式实现了它,它从SP返回了数据,所以我坚持使用它。Cheers@Fraser您可以将数据读入自定义类或任何您需要的内容。这取决于您试图完成的任务。@aw04存储过程只从数据库中返回与业务分支相关的一行。我需要将此查询的结果传递到.aspx页面,以便访问这些值。Cheers由于OP是.NET的新成员,所以可能需要额外的长度并向他显示using指令。@AndyKorneyev或只需执行dt.Loadr;非常感谢。在这种情况下,返回数据表是正确的方法还是有更好的方法?我根本不受限于使用datatable,我遇到了一个示例,并以这种方式实现了它,它从SP返回了数据,所以我坚持使用它。Cheers@Fraser您可以将数据读入自定义类或任何您需要的内容。这取决于您试图完成的任务。@aw04存储过程只从数据库中返回与业务分支相关的一行。我需要将此查询的结果传递到.aspx页面,以便访问这些值。欢呼除了反对固体,这到底能实现什么?@decPL这到底是怎么回事。。。反对实体'?一个人应该“依赖抽象。不要依赖具体。”即使你忽略了它作为指导原则,而不是明显正确的规则-你的答案仍然不能解决OP的问题。@aw04问题更新。为什么要在字段名中执行硬编码和添加行的额外步骤。如果您的过程返回正确的值,则只需填写并返回数据表即可:p@Volearix是的,我对DataTable不太熟悉,所以我没有回答。现在看来这比我的建议要好。除了与固体相悖之外,这到底能起到什么作用?@decPL这到底是怎么回事。。。反对实数“?一个人应该”依赖于抽象。不要依赖于c
即使你忽略了它作为指导原则,而不是明显正确的规则,你的答案仍然不能解决OP的问题。@aw04问题更新。为什么要在字段名中执行硬编码和添加行的额外步骤。如果您的过程返回正确的值,则只需填写并返回数据表即可:p@Volearix是的,我对DataTable不太熟悉,所以我没有回答。这看起来比我的建议好。