2009-10-17 65 views
0

我有一堆DAO類爲一個實體做類似的事情。 我想知道是否有人可以幫助我: 1)簡化代碼 2)停止複製每個實體的代碼。重構以下方法來刪除重複的代碼

public IList<IUser> GetAll() 
    { 
     IList<IUser> users = new List<IUser>(); 

     using (var myConnection = new SqlConnection(ApplicationConfig.ConnectionString)) 
     { 
      using (var myCommand = new SqlCommand("sp_GetAllUsers", myConnection)) 
      { 
       myCommand.CommandType = CommandType.StoredProcedure; 
       myConnection.Open(); 
       using (SqlDataReader myReader = myCommand.ExecuteReader()) 
       { 
        if (myReader != null) 
        { 
         while (myReader.Read()) 
          users.Add(FillDataRecord(myReader)); 
         myReader.Close(); 
        } 
       } 
      } 
      myConnection.Close(); 
     } 
     return users; 
    } 

    public IUser GetBy(int id) 
    { 
     IUser user = null; 

     using (var myConnection = new SqlConnection(AppConfiguration.ConnectionString)) 
     { 
      using (var myCommand = new SqlCommand("sp_GetUserById", myConnection)) 
      { 
       myCommand.Parameters.Add("@id", System.Data.SqlDbType.Int).Value = id; 
       myCommand.CommandType = CommandType.StoredProcedure; 
       myConnection.Open(); 
       using (SqlDataReader myReader = myCommand.ExecuteReader()) 
       { 
        if (myReader != null) 
        { 
         while (myReader.Read()) 
          user = FillDataRecord(myReader); 
         myReader.Close(); 
        } 
       } 
      } 
      myConnection.Close(); 
     } 
     return user; 
    } 

    private static IUser FillDataRecord(IDataRecord myDataRecord) 
    { 
     IAddress address = null; 

     if (!myDataRecord.IsDBNull(myDataRecord.GetOrdinal("AddressId"))) 
      address= GetAddress(myDataRecord.GetInt32(myDataRecord.GetOrdinal("AddressId"))); 

     IUser user = new User 
            { 
             Id = myDataRecord.GetInt32(myDataRecord.GetOrdinal("Id")) 
             ,LastName = myDataRecord.IsDBNull(myDataRecord.GetOrdinal("LastName")) ? string.Empty : myDataRecord.GetString(myDataRecord.GetOrdinal("LastName")) 
             ,FirstName = myDataRecord.IsDBNull(myDataRecord.GetOrdinal("FirstName")) ? string.Empty : myDataRecord.GetString(myDataRecord.GetOrdinal("FirstName")) 
             ,MyAddress= address 
            }; 
     return user; 
    } 

在此先感謝

回答

1

使用泛型和基類,所有的數據對象從派生。下面是我所做的:

using System; 
using System.Collections.Generic; 

namespace StreamSubServer 
{ 


    public abstract class DataObjectBase<T> 
    { 
     public List<T> GetAll() 
     { 
      //get the value of the StoredProcedureAttribute attribute 

     } 
     public T GetBy(int id) 
     { 
      ... 
     } 
    } 
    [StoredProcedure("usp_GetUsers")] 
    public class User : DataObjectBase<User> 
    { 
     string userName {get;set;} 

    } 
} 

然後更換與使用反射通過您的數據集/ DataReader的返回的列行走並分配值屬性的實現代碼中的省略號。您可以更好地瞭解如何從ActiveRecord源代碼中完成此操作,我無恥地將其拆分爲自己的數據訪問層。

執行StoredProcedure屬性並使用反射來檢查其值,並將其傳遞到填充方法和cha-ching中!

祝你好運!

1

我認爲最簡單的重構是:

public IList<IUser> GetAll() 
    { 

     using (var myConnection = new SqlConnection(ApplicationConfig.ConnectionString)) 
     { 
      using (var myCommand = new SqlCommand("sp_GetAllUsers", myConnection)) 
      { 
       return loadUserList(myConnection, myCommand); 
      } 
      myConnection.Close(); // This should be in a finally if to be used 
     } 
     return null; 
    } 
private IList<IUser> loadUserList(SqlConnection myConnection, SqlCommand myCommand) { 
    IList<IUser> users = new List<IUser>(); 
      myCommand.CommandType = CommandType.StoredProcedure; 
      myConnection.Open(); 
      using (SqlDataReader myReader = myCommand.ExecuteReader()) 
      { 
       if (myReader != null) 
       { 
        while (myReader.Read()) 
         users.Add(FillDataRecord(myReader)); 
        myReader.Close(); 
       } 
      } 
    return users; 
} 

如果你能回到剛纔的第一個記錄,其他函數返回一個自IUSER,如果你的願望。

爲了使這個更通用,傳入一個動作來完成處理,因此每個實體可以負責它自己的解析,並使用泛型,就像已經提到的那樣。