C#:如何缩短代码以运行存储过程?
我非常喜欢保持代码简单和精简,这样它就可以重用,在我所努力的事情上,就是使用数据阅读器来处理不同类型的对象,我用了一种方法,发现连接关闭或保持打开存在问题。所以我被强迫,同时复制和粘贴代码,这是我讨厌的!!! 我有没有办法缩小它的规模,这样我就可以把它放在一个方法中,使它可以重复使用,而且很好C#:如何缩短代码以运行存储过程?,c#,ado.net,sqldatareader,C#,Ado.net,Sqldatareader,我非常喜欢保持代码简单和精简,这样它就可以重用,在我所努力的事情上,就是使用数据阅读器来处理不同类型的对象,我用了一种方法,发现连接关闭或保持打开存在问题。所以我被强迫,同时复制和粘贴代码,这是我讨厌的!!! 我有没有办法缩小它的规模,这样我就可以把它放在一个方法中,使它可以重复使用,而且很好 ENT_AuctionBid ret = new ENT_AuctionBid(); try { SqlParameter[] Params = ne
ENT_AuctionBid ret = new ENT_AuctionBid();
try
{
SqlParameter[] Params = new SqlParameter[]{
new SqlParameter("@ID", ID )
};
using (SqlConnection conn = new SqlConnection(this.ConnectionString))
{
using (SqlCommand command = new SqlCommand("GetItem", conn))
{
SqlDataReader reader;
command.CommandType = CommandType.StoredProcedure;
conn.Open();
command.Parameters.AddRange(Params);
reader = command.ExecuteReader(CommandBehavior.SingleRow);
while (reader.HasRows)
{
while (reader.Read())
{
//
ret = this.Convert(reader);
}
reader.NextResult();
}
reader.Close();
}
}
}
catch (Exception ex)
{
}
return ret;
您可以开始使用LINQtoSQL,它有自己的数据类系统,您可以在其中拖放数据库表和存储过程。然后,您只需在类的顶部创建一个实例--
private MyCustomDataClass\u db=new MyCustomDataClass()
然后您只需键入\u db.
示例(从将所有存储过程添加到数据类时开始)
这有点小:-
try
{
using (SqlConnection conn = new SqlConnection(this.ConnectionString))
{
using (SqlCommand command = new SqlCommand("GetItem", conn))
{
command.Paramaters.AddWithValue("@ID",ID);
command.CommandType = CommandType.StoredProcedure;
conn.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
//
ret = this.Convert(reader);
}
}
}
}
catch (Exception ex)
{
}
您应该使用SQLDataAdapter。
下面是一个关于如何使用它的好例子:
此外,您可能需要考虑切换到实体框架,它将使您的数据访问变得更容易、更容易,但在现有项目中可能会很复杂。
< P>创建用于创建和返回Sql命令类型的对象的辅助方法。将连接对象以及存储过程名称和参数列表(如果有)传递给此帮助器方法。如果您有从数据读取器创建的不同对象,请将数据读取器传递给构造函数,并让它基于该数据生成对象。至于关闭连接,你应该一直尝试…抓住…最后。在最后一节中,关闭连接。在我的项目中,我通常会创建一个实用程序类来解决这个问题,该实用程序类包含访问数据库的所有方法,并在内部管理与数据库连接和适配器相关的所有内容。 例如,一个名为DBSql的类包含一个连接(SqlConnection connection;)作为私有成员和以下方法:
//execute the query passed to the function
public System.Data.DataSet ExecuteQuery(string query)
//returns if a query returns rows or not
public bool HasRows(string query)
//execute commands like update/insert/etc...
public int ExcuteNonQuery(string sql)
在我的类中,您只需传递一个字符串,然后类初始化各种DataAdapter和命令以执行它并返回一个数据集。显然,您可能会使管理参数/事务和其他一切变得复杂。
通过这种方式,您可以确保连接和对象始终以相同的方式处理,并且希望以正确的方式处理。您可以使用更少的行:
// Skipped creating temp variable
try {
using (SqlConnection conn = new SqlConnection(this.ConnectionString))
using (SqlCommand command = new SqlCommand("GetItem", conn) { CommandType = CommandType.StoredProcedure} ) {
command.Parameters.AddWithValue(@ID, ID);
conn.Open();
// reader is IDisposable, you can use using
using (var reader = command.ExecuteReader(CommandBehavior.SingleRow)) {
// Skipped parsing multiple result sets, you return after the first
// otherwise there's no point using SingleRow
// If nothing is read, return default value
return reader.Read() ? this.Convert(reader) : new ENT_AuctionBid();
}
}
}
catch (Exception ex) {
// Handle your exception here
}
// Return default value for error
return new ENT_AuctionBid();
使用此代码关闭所有连接(因为使用)。不会创建不需要的循环,因为您只需要一行。并且不需要临时变量,因此不创建ABonded对象,只有在使用它时才会创建它。您可以使用实用程序文件,例如来自Microsoft Data Access应用程序块的文件。那么您需要的所有代码如下:
using (SqlDataReader sdr = SqlHelper.ExecuteReader(this.ConnectionString, "GetItem", ID))
{
while (sdr.Read())
{
ret = this .Convert(sdr);
}
}
using将调用dispose以关闭连接。True。只是@Funky说他在某些地方的连接保持开放存在问题。就我个人而言,我使用try..catch..finally而不是使用(),因为我的连接也是由助手方法创建的,因为我通常必须在后台进行某些日志记录。然后有一个close connection helper方法,它在连接关闭之前进行一些检查,并将其放入finally块中。SqlDataAdapter有相当大的开销-这在这里确实不需要。。。所以我会投反对票。EF可能是可选的
using (SqlDataReader sdr = SqlHelper.ExecuteReader(this.ConnectionString, "GetItem", ID))
{
while (sdr.Read())
{
ret = this .Convert(sdr);
}
}