编写更优化的代码并在C#中重用代码

时间:2014-03-31 06:45:17

标签: c# sql .net oop design-patterns

我正在使用C#winforms和MSSQL server 2012编写一个桌面应用程序。此应用程序中有几个类需要连接到数据库和所有uisng ADO.Net。这是我的课程:

  class Prices
{
    private int id = 0;

    public int Id
    {
        get { return id; }
        set { id = value; }
    }
    private string materialName = string.Empty;
    ......
    ......
    ......

     public void updateMaterialPrice()
    {                        
            string conString = ConfigurationManager.ConnectionStrings["secaloFormulaCS"].ToString();
            using (SqlConnection sqlCon = new SqlConnection(conString))
            using (SqlCommand sqlCmd = new SqlCommand("spUpdateMaterialPrice", sqlCon))
            {
                sqlCmd.CommandType = CommandType.StoredProcedure;
                sqlCmd.Parameters.AddWithValue("materialName",MaterialName);
                sqlCmd.Parameters.AddWithValue("unitPrice", Price);
                sqlCmd.Parameters.AddWithValue("carbohydrate", Carbohydrtate);
                sqlCmd.Parameters.AddWithValue("protein", Proterin);
                sqlCmd.Parameters.AddWithValue("fat", Fat);
                sqlCmd.Parameters.AddWithValue("humidity", Humadity);
                sqlCmd.Parameters.AddWithValue("minerlas", Minerlas);
                sqlCon.Open();
                sqlCmd.ExecuteNonQuery();
                sqlCon.Close();
                sqlCon.Dispose();
            }                                                   
    }         
    public void addMaterial()
    {
        string ConString = ConfigurationManager.ConnectionStrings["secaloFormulaCS"].ToString(); 
        using(SqlConnection sqlCon = new SqlConnection(ConString))
        using(SqlCommand sqlCmd = new SqlCommand("spAddMaterial",sqlCon))
        {
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.Parameters.AddWithValue("materialName", MaterialName); 
            sqlCmd.Parameters.AddWithValue("unitPrice",Price);
            sqlCmd.Parameters.AddWithValue("carbohydrate",Carbohydrtate);
            sqlCmd.Parameters.AddWithValue("proterin", Proterin); 
            sqlCmd.Parameters.AddWithValue("fat",Fat); 
            sqlCmd.Parameters.AddWithValue("humidity", Humadity); 
            sqlCmd.Parameters.AddWithValue("minerals",Minerlas);
            sqlCon.Open();
            sqlCmd.ExecuteNonQuery();
            sqlCon.Close();
            sqlCon.Dispose(); 
        }

正如您在addMterial()和updateMaterialPrice()中看到的,我使用相同的代码连接到数据库并调用存储过程,这在我的其他类中重复多次。我该如何防止这种代码重复?是否只需编写连接所需的代码并一次查询数据库并根据需要重复使用几次?

3 个答案:

答案 0 :(得分:1)

好吧,你可以制作一个辅助方法为你准备命令,或者至少填写参数,例如。

void PrepareParameters(SqlCommand cmd)
{
  cmd.Parameters.AddWithValue("materialName",MaterialName);
  cmd.Parameters.AddWithValue("unitPrice", Price);
  cmd.Parameters.AddWithValue("carbohydrate", Carbohydrtate);
  cmd.Parameters.AddWithValue("protein", Proterin);
  cmd.Parameters.AddWithValue("fat", Fat);
  cmd.Parameters.AddWithValue("humidity", Humadity);
  cmd.Parameters.AddWithValue("minerlas", Minerlas);
}

理想情况下,除非您想使用像Entity Framework这样的现成ORM(通常是一个好主意),否则您需要创建一些抽象类来处理这些事情,这样您就可以节省代码重用。

例如,PrepareParameters方法可能是抽象的,并且可能有一个抽象属性返回要更新,创建或删除的SP的名称(或者更好的是,您可以遵循命名方案,以便你只需要一个名字)。然后你可以在抽象基类中编写99%的逻辑,并且只在实际的派生类中准备参数,从而减少代码重复 lot

答案 1 :(得分:1)

有些选项如下:

  1. 编写一个SqlHelper类,它执行执行存储过程的重复grunt工作。 (尤其是ExecuteNonQuery,因此您不必担心返回类型。)
  2. e.g。

    public void ExecuteQuery(string sprocName, SqlParamater[] parameters)
    {
     // initialize connection
     // construct command with sprocName and parameters
     // ExecuteNonQuery
    }
    
    1. 使用Linq2Sql
    2. 这是一款出色的快速ORM工具,可以简化数据访问。

      1. 使用实体框架
      2. 这是一种日益使用的ORM工具。

        以上所有方法都有其优点/缺点。你需要给它们增加重量。选择正确的方法。

答案 2 :(得分:1)

我使用Factory模式进行数据库连接,这意味着我不必打开SqlConnection或在程序周围传递连接字符串。

以下是我用于运行返回多行的查询的方法示例。

我会从“makeObject”方法调用该方法,该方法将此数据表转换为对象。

public static class DB
{
    private static readonly string connectionString   = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    private static readonly DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient");

    /// <summary>
    /// Use when returning data from multiple rows
    /// </summary>
    /// <param name="sql">query</param>
    /// <param name="parameters">declared parameters</param>
    /// <returns>datatable of db rows</returns>
    public static DataTable GetDataTable(string sql, SqlParameter[] parameters)
    {
        try
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = connectionString;

                using (DbCommand command = factory.CreateCommand())
                {
                    command.Connection  = connection;
                    command.CommandType = CommandType.Text;
                    command.CommandText = sql;

                    if (parameters != null)
                    {
                        foreach (var parameter in parameters)
                        {
                            if (parameter != null)
                                command.Parameters.Add(parameter);
                        }
                    }
                    using (DbDataAdapter adapter = factory.CreateDataAdapter())
                    {
                        adapter.SelectCommand = command;

                        DataTable dt = new DataTable();
                        adapter.Fill(dt);

                        return dt;
                    }
                }
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
}