重构以下方法以删除重复的代码

时间:2009-10-17 02:11:53

标签: .net-3.5

我有一堆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;
    }

提前致谢

2 个答案:

答案 0 :(得分: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属性并使用反射检查其值,将其传递到fill方法和chaching中!

祝你好运!

答案 1 :(得分: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以来。

为了使这更通用,传入一个动作来进行处理,因此每个实体都可以负责它自己的解析,并使用已经提到的泛型。

相关问题