编写更优化的代码并在 C# 中重用代码
本文关键字:代码 优化 | 更新日期: 2023-09-27 17:55:26
我正在使用C# winforms和MSSQL server 2012编写桌面应用程序。 此应用程序中有几个类退出需要连接到数据库和所有 UINN 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()中看到的那样,我使用相同的代码连接到数据库并调用存储过程,并且在我的其他类中重复了几次。 如何防止此代码重复? 有没有办法只编写连接所需的代码并查询数据库一次,然后根据需要多次重用?
我对数据库连接使用工厂模式,这意味着我永远不必打开 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;
}
}
}
好吧,您可以创建一个辅助方法来为您准备命令,或者至少填充参数,例如。
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);
}
理想情况下,除非你想使用像实体框架这样的现成的ORM(通常是一个好主意),否则你会创建一些抽象类来处理这些事情,这样你就可以节省代码重用。
例如,PrepareParameters
方法可以是抽象的,并且可能有一个抽象属性返回要更新、创建或删除的 SP 的名称(或者更好的是,您可以遵循命名方案,以便只需要一个名称)。然后你可以在抽象基类中编写 99% 的逻辑,并且只在实际的派生类中准备参数,从而大大减少代码重复。
一些选项如下:
- 编写一个 SqlHelper 类,该类执行执行存储过程的重复繁重工作。(尤其是 ExecuteNonQuery 的,这样你就不用担心返回类型了。
例如
public void ExecuteQuery(string sprocName, SqlParamater[] parameters)
{
// initialize connection
// construct command with sprocName and parameters
// ExecuteNonQuery
}
- 使用 Linq2Sql
这是一个出色的快速ORM工具,可以简化大量数据访问。
- 使用实体框架
这是一个越来越多地使用的ORM工具。
上述所有方法都有其优点/缺点。您需要对它们进行称重并选择正确的方法。