2013-12-19 69 views
1

我有一個常見的數據訪問方法,如下所列。它工作正常。但是,基於數據類型有多個if blocks(在ExecuteNonQueryWithTextCommandType方法中)。另外,用於準備List<CommandParameter>的InsertLogSeverity方法中有太多冗餘代碼。數據類型的重構代碼

如何重構這個代碼?

參考文獻

  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; } 
} 
+2

爲什麼使用自己的參數類型而不是SqlParameter? http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter(v=vs.110).aspx –

+0

參考文獻[寫入便攜式數據訪問層(http://msdn.microsoft .com/en-us/library/ms971568.aspx)和[DAL:使用存儲過程檢索DataTable](http://msmvps.com/blogs/deborahk/archive/2009/07/07/dal-retrieve-一個-數據表-使用-A-存儲過程。aspx) – Lijo

+1

您正在編寫專門的DAL,因爲您正在專門使用SqlConnection而不是IDbConnection –

回答

2

@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}, 
}); 
+0

這絕對是一種改進......您認爲這是一個可用於生產的代碼嗎?它是一種廣泛使用的數據訪問模式嗎?還是在這裏需要更多的重構? – Lijo

+0

您應該查看從app.config中檢索連接字符串,而不是對其進行硬編碼。也可能是一些錯誤處理或至少記錄錯誤。 –

+0

是的....除此之外,我實際上是指'InsertLogSeverity'。那裏是否有重構的空間? – Lijo

1

我想你可以使用類型約束,是這樣的:

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在更高層次上

,只是引用的parameterValue,因爲它是Object類型的,並沒有必要將其轉換。

+1

你也可以使用標準的sqlparameter,爲了簡潔和優雅,你可以寫一些通用的方法來做sql查詢,我在vb.net中做了一個例子,在這裏 - http://codereview.stackexchange.com/questions/25792/VB-淨-SQL代碼清理/ 30858#30858 – Rex