Petshop的架构思路清晰简单,我想很多人都很了解,就想问些简单问题。1.一般DAL层写好或者生成好了常用的SQL语句,但是面对自定义SQL语句怎么办?
2.应该改写DAL层还是写在别的地方?
3.可以在DAL层留一个方法,然后在BLL层写自定义SQL语句和参数传进去执行吗?如DAL层留个方法:/// <summary>
        /// 自定义SQL语句得到一个DataSet(包含自定义的DataTable名)
        /// </summary>
        public DataSet GetData(String tableName, String sql)
        {
            return OracleHelper.Query(tableName, sql);
        }
BLL层写语句调用,虽然这个DAL层的方法显得没有意义了,但是我主要是想在数据库结构没有发生变化的时候,除了UI和BLL层,都不可以做到不去修改。

解决方案 »

  1.   

    数据操作之类的都要放在DAL中
    BLL只是分配调用哪个操作事件
      

  2.   

    额,楼主你的想法是对的撒,这样就利于维护啊,只要修改Ui就是了啊,bll同样可以不用修改啊?
      

  3.   

    DAL层 负责SQL的组成 和 数据库的访问 (用ORM的话另当别论)为什么LZ的DAL层是负责接受SQL的呢? 难道SQL的组成放在业务层去了??
      

  4.   

    自定义的sql不应该在bll中生成,应该在dal中做。
      

  5.   


    Petshop 的 DAL 还清晰简单?烦都烦死了。Linq to SQL 才算清晰简单。DAL层一行代码也不用写,这才叫做清晰简单。
      

  6.   

    DAL中做数据库的操作
    BLL中不应当传入sql语句来处理
    DAL中的方法可以接收一些参数,从BLL层中调用传入以实现灵活的做sql操作
      

  7.   

    实际上正如SP1234老大所说的,很多架构在DAL层不用写一句代码。PETSHOP也只不过给了一个分层的思想,具体怎么分层,还是看需求。
      

  8.   

    所有的与数据库相关的操作一般放在DAL层,便于维护
      

  9.   

    比Petshop 的 DAL 清晰简单还有强类型的DataSet!!
      

  10.   


    感谢回复,那就是说每扩充一个方法,还要写IDAL和DAL,当数据库结构发生变更的时候,CODESMITH就要重新生成DAL和MODEL层,这个时候还要记得那个DAL是从写过的,还要把自定义的复制出来,避免覆盖,是不是太麻烦了?既然BLL有时候都可以传where的字符串作为参数给DAL实现一些灵活操作,为什么不能直接传SQL语句和parameters呢?
      

  11.   

    如果在BLL中构造sql,那么当你切换数据库的时候BLL也得重写?那这个分层就没有什么意义了。
      

  12.   

    我一向认为,,petshop是个失败的案例,,,试问一下,,如果真的要做那些工能出来,,要写的那么烦吗??我的方法就简单的多,,如果是站在PHP的角度来说,,,那就更简单了,,petshop的写法变的更不可思议了
      

  13.   

    当然是改写DAL层 这样方便扩展,petshop已经是微软简化的不能在减的代码了 每一句都有他的含义,自定义的sql指的是什么,复杂的吗,一样传参旧可以了
      

  14.   

    那就是说自定义一个SQL语句,就要在IDAL,DAL,BLL各添加一个方法了?顺便问下谁有比较满意或者网上比较好的框架可以让我看看吗?
    [email protected]
      

  15.   

    bll层 不是不能写sql语句
    更谈不上是错误——你的程序可以正常运行嘛
    不过,如果是新人,最好不要这样写因为sql语句放在bll层是有前提的
    就是你认为sql语句是什么一个方法:string f(int num,string username)
    参数是num和username
    其类型是int和string
    同样,string f(string sqlstr)
    如果你能把sqlstr理解成带有很规范格式的参数的话,你可以用
    如果在你的眼睛,你觉得sql语句是且仅是一个字符串的话,哪就算了
    另外,如果是多人合作开发或维护,哪也就最好不要这样同样xml,你可以看成结构严禁的特殊的txt文件,只要这些东西用活了,这里的界限其实并没有那么多规矩
      

  16.   

    多谢回复,我现在就是比较困扰就是在DAL实现扩展,需要修改的的层太多,而且牵扯到数据库结构发生变化时,肯定是要用CodeSmith等重新生成Model和DAL层的代码,这样就牵扯到覆盖的问题,还要一个一个DAL层的文件进行检查。而不常用的扩展语句写在BLL层就不会有这个问题。因为无论数据如何变化都不会影响BLL层的从新生成。还有,如(慕白兄)大大的回复,的确是更改数据库种类时,会牵扯到BLL的重写,这样无法通过只修改web.config就实现数据库切换。但是我想系统需要在运行时候动态切换数据库种类的项目太有限了。我所提到的数据库切换无非是指在项目开始时客户有不同的选择。而且如果BLL不写代码仅仅是因为数据库切换的问题的话,我想也有其他的对框架改写的方案。
    我在DAL层也写了一些公用的扩展方法,就是为了BLL可以写少量代码就实现自定义语句的扩充,就是想让程序员只专注UI和BLL层。比如BLL层只用这样写就可以获取一个可以绑定且和Model中对应类型的DS:
    /// <summary>
    /// 得到一个扩展的对象实体
    /// </summary>
    public DataSet GetExtendModel(Int64 SET_DEPARTMENTLIST_ROWID)
    {
    //定义一个Hashtable用来存放关联的表名以及关系列(可为多表关联)
    Hashtable Relationship = new Hashtable();

    //用法示例
                //Relationship.Add("表1 a", "列2=a.列1");
                Relationship.Add("SET_DepartmentList a", "ParentRowID=a.SET_DepartmentList_RowID"); //定义一个String数组用来存放需要查询的扩展关联列(扩展出的各列均为只读,需要使用Eval绑定)
    String[] Columns = new String[1];

    //用法示例
                //Columns[0] = "a.列5 as 别名1";
                //Columns[1] = "a.列6 as 别名2";
                Columns[0] = "a.DepartmentName as ParentName";

    return objIDAL.GetExtendModel(SET_DEPARTMENTLIST_ROWID, Relationship, Columns);
    }
    对应的DAL
    /// <summary>
    /// 得到一个扩展的对象实体
    /// </summary>
    public DataSet GetExtendModel(Int64 SET_DEPARTMENTLIST_ROWID, Hashtable Relationship, String[] Columns)
    {
    StringBuilder strSQL = new StringBuilder();

    //查询出该表下的所有列
    strSQL.Append("select SET_DEPARTMENTLIST.SET_DEPARTMENTLIST_ROWID, SET_DEPARTMENTLIST.DEPARTMENTNAME, SET_DEPARTMENTLIST.PARENTROWID, SET_DEPARTMENTLIST.DEPARTMENTEXPLAIN");

    //循环查询扩展关联列(带别名)
    foreach (String str in Columns)
                {
                    if (!String.IsNullOrEmpty(str))
                    {
                        strSQL.Append(", " + str);
                    }
                }            strSQL.Append(" from SET_DEPARTMENTLIST ");

    //循环添加关联表及左连接关系列(带别名)
    foreach (DictionaryEntry de in Relationship)
                {
                    strSQL.Append("left join " + de.Key.ToString() + " ");
                    strSQL.Append("on SET_DEPARTMENTLIST." + de.Value.ToString() + " ");
                }

    strSQL.Append("where SET_DEPARTMENTLIST.SET_DEPARTMENTLIST_ROWID=:SET_DEPARTMENTLIST_ROWID");

    OracleParameter[] parameters = 
    {
    new OracleParameter(":SET_DEPARTMENTLIST_ROWID", OracleType.Number)
    };

    parameters[0].Value = SET_DEPARTMENTLIST_ROWID;

    DataSet objDS = OracleHelper.Query(strSQL.ToString(), parameters);

    if (objDS.Tables[0].Rows.Count > 0)
    {
    //克隆数据结构
    DataSet objDS_Clone = objDS.Clone();

    //将返回的DataSet各列数据类型转化为对应的Model数据类型
    //此行为目的是借用DataSet实现实体类的功能并与实体类保持兼容
    //可将此方法和实体类的操作方法配合使用在同一个ObjectDataSource中
    //需要注意的是:扩展出的各列均为只读,需要使用Eval绑定
    objDS_Clone.Tables[0].Columns["SET_DEPARTMENTLIST_ROWID"].DataType = Type.GetType("System.Int64");
    objDS_Clone.Tables[0].Columns["DEPARTMENTNAME"].DataType = Type.GetType("System.String");
    objDS_Clone.Tables[0].Columns["PARENTROWID"].DataType = Type.GetType("System.Int64");
    objDS_Clone.Tables[0].Columns["DEPARTMENTEXPLAIN"].DataType = Type.GetType("System.String");

    //创建一个新行实现数据类型转化
    objDS_Clone.Tables[0].Rows.Add(objDS_Clone.Tables[0].NewRow()); //循环赋值,令返回的DataSet具有匹配后数据类型的数据
                    for (Int32 intCount = 0; intCount < objDS_Clone.Tables[0].Columns.Count; intCount++)
                    {
                        objDS_Clone.Tables[0].Rows[0][intCount] = objDS.Tables[0].Rows[0][intCount];
                    }                return objDS_Clone;
    }
    else
    {
    return null;
    }
    }请各位朋友关注我的这次回复,给于解答,让我对架构的理解更加深入。同时我也觉得有很多东西值得我们思考。
      

  17.   

    我想类似于petshop的所谓DAL层的这种写法,必定是属于淘汰之列!!
    何以见的呢?看:
    vs2005推出了强类型的DataSet,
    vs2008推出了Linq,
    这些是什么东东?
    数据访问层啊!!
    这些东东你用过后,正像18楼所说:“petshop的写法变的更不可思议了”
      

  18.   

    看了sp1234社区的昵称:(csdn怎么总是显得质量低劣呢,).那我就想不通了,难道你不属于csdn吗?既然属于,你这不是给自己身上泼粪吗?最见不得这种倚老卖老的人!那好,我干脆给你改个名字,"sb1234"。
      楼下的拍砖吧!
      

  19.   

    CSDN是个大家庭啊。。
    各种各样的人都有啊。。
      

  20.   

    SQL语句是应该尽量出现在DAL,当然定义DAL的新方法,就需要对应的修改BLL和IDAL,这是无可避免的。每个框架都不会是完美的,如果强调易用和少修改,那么DataSet操作相对轻松多了,但是DS的效率,安全性等当然不如IList,实体类那些了。