【问题标题】:Refactoring code for datatype数据类型的重构代码
【发布时间】:2014-01-07 16:35:59
【问题描述】:

我有一个通用的数据访问方法,如下所示。它工作正常。但是,基于数据类型(在ExecuteNonQueryWithTextCommandType方法中)有多个if blocks。另外,InsertLogSeverity 方法中用于准备List<CommandParameter> 的冗余代码太多。

如何重构这段代码?

参考文献

  1. How can I easily convert DataReader to List<T>?
  2. Use of Generic Delegates
  3. Fastest method for SQL Server inserts, updates, selects
  4. Writing a Portable Data Access Layer
  5. DAL: Retrieve a DataTable using a Stored Procedure
  6. How to improve data access layer select method Pattern
  7. Return DataReader from DataLayer in Using statement

通用 DAL

public class MyCommonDAL
{
    public void ExecuteNonQueryWithTextCommandType(string commandText, List<CommandParameter> commandParameters)
    {
        string connectionString = @"Server=XXXX;Database=CostPage_Dev;User Id=hhhh;Password=xxxx";
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            using (SqlCommand command = new SqlCommand())
            {
                command.Connection = connection;
                command.CommandType = CommandType.Text;
                command.CommandText = commandText;
                command.CommandTimeout = 0;

                foreach (CommandParameter parameterDetail in commandParameters)
                {
                    if (String.Equals(parameterDetail.ParameterType, "Int"))
                    {
                        command.Parameters.AddWithValue(parameterDetail.ParameterName, Convert.ToInt32(parameterDetail.ParameterValue));
                    }
                    if (String.Equals(parameterDetail.ParameterType, "String"))
                    {
                        command.Parameters.AddWithValue(parameterDetail.ParameterName, Convert.ToString(parameterDetail.ParameterValue));
                    }
                    if (String.Equals(parameterDetail.ParameterType, "DateTime"))
                    {
                        command.Parameters.AddWithValue(parameterDetail.ParameterName, Convert.ToDateTime(parameterDetail.ParameterValue));
                    }

                }

                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }

}

特定于操作的 DAL

public class MyLogDAL
{

    public void InsertLogSeverity(LogSeverityTypePOCO logSeverityType)
    {
        string commandText = @"INSERT INTO dbo.LogSeverityType (LogSeverityTypeID,Name,Description,CreatedDateTime) 
                              VALUES (@LogSeverityTypeID,@Name,@Description,@CreatedDateTime)";


        List<CommandParameter> commandParameters = new List<CommandParameter>();


        CommandParameter parameter1 = new CommandParameter();
        parameter1.ParameterName = "@LogSeverityTypeID";
        parameter1.ParameterValue = logSeverityType.LogSeverityTypeID;
        parameter1.ParameterType = "Int";

        CommandParameter parameter2 = new CommandParameter();
        parameter2.ParameterName = "@Name";
        parameter2.ParameterValue = logSeverityType.Name;
        parameter2.ParameterType = "String";

        CommandParameter parameter3 = new CommandParameter();
        parameter3.ParameterName = "@Description";
        parameter3.ParameterValue = logSeverityType.Description;
        parameter3.ParameterType = "String";

        CommandParameter parameter4 = new CommandParameter();
        parameter4.ParameterName = "@CreatedDateTime";
        parameter4.ParameterValue = logSeverityType.CreatedDateTime;
        parameter4.ParameterType = "DateTime";

        commandParameters.Add(parameter1);
        commandParameters.Add(parameter2);
        commandParameters.Add(parameter3);
        commandParameters.Add(parameter4);

        MyCommonDAL dal = new MyCommonDAL();
        dal.ExecuteNonQueryWithTextCommandType(commandText, commandParameters);
    }

}

客户

class Program
{
    static void Main(string[] args)
    {
        MyLogDAL logDAL = new MyLogDAL();

        LogSeverityTypePOCO logSeverityType = new LogSeverityTypePOCO();
        logSeverityType.LogSeverityTypeID = 107;
        logSeverityType.Name = "N";
        logSeverityType.Description = "D";
        logSeverityType.CreatedDateTime = DateTime.Now;

        logDAL.InsertLogSeverity(logSeverityType);
    }

}

DTO

public class LogSeverityTypePOCO
{
    public int LogSeverityTypeID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime  CreatedDateTime { get; set; }
}

public class CommandParameter
{
    public string ParameterName { get; set; }
    public object ParameterValue { get; set; }
    public string ParameterType { get; set; }
}

【问题讨论】:

标签: c# ado.net


【解决方案1】:

@Lijo,根据我的评论和您的要求,我宁愿使用SqlParamter

类似

public void ExecuteNonQueryWithTextCommandType(string commandText, List<SqlParameter> commandParameters)
{
    string connectionString = @"Server=XXXX;Database=CostPage_Dev;User Id=devtopco;Password=xxxx";
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        using (SqlCommand command = new SqlCommand())
        {
            command.Connection = connection;
            command.CommandType = CommandType.Text;
            command.CommandText = commandText;
            command.CommandTimeout = 0;
            command.Parameters.AddRange(commandParameters.ToArray());

            connection.Open();
            command.ExecuteNonQuery();
        }
    }
}

你的用法会是这样的

string commandText = @"INSERT INTO dbo.LogSeverityType (LogSeverityTypeID,Name,Description,CreatedDateTime) 
                  VALUES (@LogSeverityTypeID,@Name,@Description,@CreatedDateTime)";
ExecuteNonQueryWithTextCommandType(commandText, new List<SqlParameter>
{
    new SqlParameter {ParameterName = "@LogSeverityTypeID", Value = logSeverityType.LogSeverityTypeID, SqlDbType = SqlDbType.Int},
    new SqlParameter {ParameterName = "@Name", Value = logSeverityType.Name, SqlDbType = SqlDbType.VarChar},
    new SqlParameter {ParameterName = "@Description", Value = logSeverityType.Description, SqlDbType = SqlDbType.VarChar},
    new SqlParameter {ParameterName = "@CreatedDateTime", Value = logSeverityType.CreatedDateTime, SqlDbType = SqlDbType.DateTime},
});

【讨论】:

  • 这绝对是一个改进......你认为它是一个生产可用的代码吗?它是一种广泛使用的数据访问模式吗?还是这里还需要更多重构?
  • 您应该考虑从 app.config 中检索连接字符串,而不是对其进行硬编码。也可能进行一些错误处理或至少记录错误。
  • 是的....除此之外,我实际上指的是InsertLogSeverity。那里有重构的余地吗?
  • @Lijo,见上面我的使用规范。
【解决方案2】:

我认为您可以使用类型约束,例如:

    public abstract class CommandParameter
    {
        public string ParameterName { get; set; }
        public virtual object ParameterValue { get; }
        public virtual string ParameterType { get; }
    }

    public class CommandParameter<T>:CommandParameter
    {
        public T Value { get; set; }

        public override object ParameterValue
        {
            get
            {
                return Value;
            }
        }

        public override string ParameterType
        {
            get
            {
                return typeof(T).Name;
            }
        }
    }

用法:

            var param = new CommandParameter<string>();
            param.ParameterName = "@blahblah";
            param.Value = "stringVal";

            var param2 = new CommandParameter<int>();
            param2.ParameterName = "@blahInt";
            param2.Value = 123;

当您需要在更高级别引用 ParameterValue 时,只需引用 Object 类型的 ParameterValue,无需转换它。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多