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);
    }
  }