PetShop 4.0 数据访问层之我所见

个人感觉数据访问层,设计上应该可以更精简。

现有的框架是一个DAL,对应一个Helper(我们可以理解其实就是真正的数据引擎)。这种方式实现上确实很简单,但是有重复的地方。对于每种DAL,不同的只是Helper,其它实现基本相同。

一个可行的重构,实现一个真正的Helper类,把不同的数据引擎,封装为一个DALEngine, 一些简单的代码实现,可以参见如下:
public interface IDALEngine
{
    int ExecuteNonQuery(CommandType cmdType, String cmdText, IList<IParameter> parameters);
    object ExecuteNonScalar(CommandType cmdType, String cmdText, IList<IParameter> parameters);
    IDataReader ExecuteReader(CommandType cmdType, String cmdText, IList<IParameter> parameters);
}

public abstract class DALHelper
{
    public static int ExecuteNonQuery(IDALEngine engine, CommandType cmdType, String cmdText, IList<IParameter> parameters)
    {
        return engine.ExecuteNonQuery(cmdType, cmdText, parameters);
    }

    public static object ExecuteNonScalar(IDALEngine engine, CommandType cmdType, String cmdText, IList<IParameter> parameters)
    {
        return engine.ExecuteNonScalar(cmdType, cmdText, parameters);
    }

    public static IDataReader ExecuteReader(IDALEngine engine, CommandType cmdType, String cmdText, IList<IParameter> parameters)
    {
        return engine.ExecuteReader(cmdType, cmdText, parameters);
    }
}

public class SqlDALEngine : IDALEngine
{
    private SqlConnection conn;
    public SqlDALEngine(String connString)
    {
        conn = new SqlConnection(connString);
        if (conn.State != ConnectionState.Open)
        {
            conn.Open();
        }
    }
    int ExecuteNonQuery(CommandType cmdType, String cmdText, IList<IParameter> parameters)
    {
        if (conn.State != ConnectionState.Open)
        {
            //throw exception: connection is closed!
        }

        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandType = cmdType;
        cmd.CommandText = cmdText;
        
        if (parameters != NULL)
        {
            foreach (IParameter param in parameters)
            {
                cmd.Parameters.Add(param);  //也许需要进行一些转换,这里只是一个伪代码
            }
        }

        int result = cmd.ExecuteNonQuery();
        
        return result;
    }

    object ExecuteNonScalar(CommandType cmdType, String cmdText, IList<IParameter> parameters)
    {
        //参考实现如ExecuteNonQuery
    }

    IDataReader ExecuteReader(CommandType cmdType, String cmdText, IList<IParameter> parameters)
    {
        //参考实现如ExecuteNonQuery
    }  
}

看起来这只是一个简单的转换,但在大型系统,表格极多的情况下,绝对是一大改善。

另外,原有的数据访问层框架,如果在数据没有准备好的情况下,不便于测试,通过这种改善,我们可以把数据访问及数据访问引擎给进行隔离,各自发展

欢迎大家参与讨论,谢绝人身攻击!

posted @ 2012-11-15 16:39  理查杨哥  阅读(161)  评论(0编辑  收藏  举报