最近看到很多人谈多层开发的架构,提到分
    presentation
    business facade (可选)
    business logic
    data access + entities
    persistence framework(可选)按照这样的层次来看,作为business logic与data access之间的交互, 应该说有一个
DAO(Data Access Object)来负责将Database中的资料抓取出来,返回成所预先定义好
的Entity类型,这里可以允许Entity进行粗粒度的OO定义。而presentation与business logic之间的交互,不应该再看到Data Access层面,所以
这个时候,就需要一些OO定义比较细粒度的Object, 援用DTO(Data Transfer Object)
来解决。从这样看来, UI与business间的交互使用DTO对象,而business与data access的交互
则使用Entity。现在问题来了,在.Net中,aspx页面上面很多的控件,如果需要数据绑定,都是使用的
DataTable/DataView,或是Collection类型来的。而一般来说DAO对象的方法操作的就是
DataTable之类的对象,本应该转换为某个Entity的类型,现在应为要绑定,就只好一路
将DataTable对象扔到上一层,从整个Project来看,我必须每个层面都要针对DataTable
对象进行考虑,这样,层与层间的交互就会应为这个没有很好的隔离性。举例如下:

解决方案 »

  1.   

    一个折中的做法就是做一个DataWrapper对象,比如说:有一个Entity的定义,来包装一个DataTable://DataWrapper for Employee Entity, Employee Entities cellections
    //in the domain model.public class EmployeeData : IDisposable
    {
    public const string MAPPING_TABLE = "Employee";

    public const string EmployeeNumber = "empno";
    public const string EmployeeName = "emp_name";
    public const string OrgId = "OrgId"; //here is the real data, which filled from DAO object
    private DataTable dataTable = null; public EmployeeData(DataTable dataTable)
    {
    this.dataTable = dataTable;
    } public DataRow this[int index]
    {
    get
    {
    return this.dataTable.Rows[index];
    }
    }

    public DataView DefaultView
    {
    get
    {
    return this.dataTable.DefaultView;
    }
    } public int Count
    {
    get
    {
    return this.dataTable.Rows.Count;
    }
    } #region IDisposable 成員 public void Dispose()
    {
    this.dataTable.Clear();
    this.dataTable.Dispose();
    } #endregion
    }我有一个DAO对象,EmployeeDAO:public class EmployeeDAO
    {
    public EmployeeDAO()
    {
    } public EmployeeData GetEmployeeByOrgId(string orgId)
    {
    string strSql = "SELECT * FROM emp_data WHERE org_id=@orgId"; IDataParameter[] arySqlParams = new IDataParameter[1];  arySqlParams[0] = new SqlParameter("@orgId", SqlDbType.Char);
    arySqlParams[0].Value = orgId; DataSet ds = DBHelper.manager.RetrieveData(new SqlDataAdapter(), strSql, arySqlParams); EmployeeData employeeData = new EmployeeData(ds.Tables[0]); return employeeData;
    }
    }于是在我的Business Logic中,我就可以这样写EmployeeSystem:public class EmployeeSystem
    {
    public EmployeeSystem()
    {
    } public EmployeeData GetEmployeesByOrgId(string orgId)
    {
    EmployeeDAO employeeDAO = new EmployeeDAO();
    return employeeDAO.GetEmployeeByOrgId(orgId);
    }
    }在我的UI中就可以如此来调用:EmplyeeSystem employeeManager = new EmployeeSystem();
    EmployeeData employees = employeeManager.GetEmployeesByOrgId(ddlOrgList.SelectedValue);dgdEmployees.DataSource = employees.DefaultView;
    dgdEmployees.DataBind();或是:for(int i=0; i<employees.Count; i++)
    {
        lblEmployees.Text += employees[i][EmployeeData.EmployeeName].ToString();
    }
      

  2.   

    这样一来,虽然在business logic中,用DataWrapper让UI层面不用关心到DataTable之类的东西了,但是总是觉得有些怪怪!难道说微软的多层应用的设计就需要按照Data Driven的方式来进行吗?还是说有其他方法,请大家来指点,谢谢!
      

  3.   

    等待高人指点...
    我也是老用dataset或datatable,这样绑定方便一点
    或许层与层之间也可用xml吧,没试过
      

  4.   

    我觉得没必要死抠概念,怎么健壮高效就怎么用。
    比如presentation一个DataGrid它就是简单的重现一下数据库里某个表,为什么不能直接将DataTable传过去呢?当然对于一些复杂的prensentation,肯定得有DTO来管理了。
      

  5.   

    怎么方便怎么用,不要为设计模式所累。
    个人觉得如果使用设计模式的思路, UI与business间的交互使用DTO对象,而business与data access的交互则使用Entity。转换的是不是得不偿失就用DataTable一直往上抛吧。^_^
      

  6.   

    偶一般就是返回一个DATASET之类就可以了
      

  7.   

    看情况的需要,我基本是要Entity的,
    在。NET的在数据集处理DATASET比较方便,想不出为什么放弃它。
    就是现在我用nhibernate也特意地加上了返回DATASET查询的方法。
      

  8.   

    我的观点是如果不需要进行分布式布署,有的东西不需要搞得很复杂.
    我试过写了个utility类,可以自由的在DataSet,Entity Collection与XML之间转换,但是效果不是很好.
    entity的问题是在于处理relationship时比较麻烦,在这里要求有一个比较好的架构来完成数据的persistence.
    另外,dto对象直接进行数据绑定也可以的,因为数据绑定是通过reflection来实际的,带来的问题可能是效率不高.同时,在dto与entity之间的转换也要损失一些效率.
    另一个问题是这样使事务的处理会集中的businessrule层,而在数据库进行事务处理的效率远远高于(如果可能话)在这一层进行处理。我的意见:
    如果不是很大的系统,直接使用DataSet在UI,BR,DA层传输数据就可以了.至于facade层,没有什么必要.
      

  9.   

    仔细想想,其实层和层之间用DataSet或DataTable比较好,因为每层都有自定义的类,来表示实现不同的逻辑,如果直接传DTO,层和层之间耦合度太大,划分不清晰。用DataSet,就好比定义了一个协议,层层之间只要遵守这个协议就OK了,耦合度小,并且开销可能也会小一些,但是就是这个协议无可避免的不是OO的。这个思路是从网络分层结构来的,请大家批。
      

  10.   

    同意DataSet或者DataTable
    我们现在的做法就是将DataTable往上抛,只有需要的时候才定义entity
      

  11.   

    用.net做过两个项目,感觉分层和OO定义确实很重要。特别是当项目进入扩展或需求变化阶段,这些结构的优点也就更加明显。
    我的一点经验是:核心对象一定要在业务层定义好,便于系统的扩展与维护,对于数据层该不该对表现层开放,我觉得应该可以,有时一些简单的业务,直接用DataTable/DataSet实现来的更快,也快捷编码任务。
      

  12.   

    DataTable 说白了是一个放在内存中的Table结构,如果以DataTable来看,很多的编程都会变成Table structure & data oriented, 我没有想到如何进行封装...
      

  13.   

    偶一般不喜欢用 entity  ,偶一般 DA层 返回DataSet
    很多时候 加多一层 entity  不必要
      

  14.   

    微軟的官方意見說是用DataSet作為DTO, 如果更進一步的話, 就是使用Typed DataSet來做為DTO...這樣一來, 我就不知道,在.Net開發中, 還需要定義實體類型嗎?
      

  15.   

    页面的数据显示和绑定很多当然需要提供数据源,建议返回DATASET数据操作当然是用entity
      

  16.   

    樓上的網友, 請解釋一下, entity是在什麼時候使用? 你說的數據操作是指什麼? 謝謝!
      

  17.   

    关于楼主说的邦定问题可以在定义Entity的同时定义EntityCollection 直接继承CollectionBase,这样绑定的数据源就是EntityCollection,现在的项目中,我们也是定义了这些层次,不论是dropdownlist还是datagrid都用EntityCollection来绑定,没什么问题
      

  18.   

    我感觉这两种方法都是可行的,取决于项目的量级,庞大而复杂的项目用DataTable,DataSet,而轻量级的用Entity楼上 wolve讲过了,Entity在处理Relation的时候比较麻烦,处理比较复杂的数据关系是难胜任的,我们现在的项目里用Entity,处理简单的数据关联通常使用Lazyloading,相对能提高Entity一些灵活性至于页面绑定,用包含的Entity的Collection绑定数据控件
      

  19.   

    嗯...这个主意不错,可是从ADO.Net取回来的肯定是一个个的DataSet,我是不是要把DataSet中需要的DataTable转换成自己定义的EntityCollection呢?楼上的网友能给些关键部分的例子吗?谢谢!
      

  20.   

    呵呵, beibeilong(whylove) 的方法和我们使用的是一样的
      

  21.   

    在DAL取回Datareader或者Datatable,然后Add到Collection中,把Collection返回到logic layer
      

  22.   

    举例,我们是这么做的,在DAL取回Datareader,然后Collection.add(new Entity(dr))到中,把Collection返回到logic layer
      

  23.   

    这样有没有performance方面的问题???
      

  24.   

    有影响,要看你的项目对Performance要求多高了
      

  25.   

    初步有了一个概念了,谢谢beibeilong(whylove)和 windancer(^_^) ,继续等待更多网友的讨论...
      

  26.   

    在DAL取回Datareader或者Datatable,然后Add到Collection中,把Collection返回到logic layer
    我就是这么做的
      

  27.   

    直接用DataSet了,为什么要给自己找那么多的麻烦呢?越简单的东西是越好维护的,一个问题能用3行解决就不要用更多的行了,有必要吗?一个DataSet救解决了,为什么还要在封装一下呢?
      

  28.   

    樓上朋友的系統是自己一直在做維護呢? 還是很多人在一起開發啊?如果規模大了, 各個部份的編碼都是圍繞DataTable, 不說開發的時候, 需要大家都了解DataTable中所包含的columns, 以後維護起來, 也需要查照DataTable中的columns list, 應為對於DataTable來說, 不能讓開發/維護人員通過其屬性來了解這個對象的內涵. 而如果用Entity對象封裝後, 就可以望文知意,這其實就是用程序來注釋程序的一種思想...
      

  29.   

    微软的一些源代码程序,例如那个论坛 Asp.Net Foumns就是返回DataReader 然后用ArrayList来Add(Entity),然后返回ArrayList
      

  30.   

    "越简单的东西是越好维护的", 我非常同意, 但是要看從什麼方面進行簡化了...嘿嘿...樓上朋友的簡化, 我自己認為是一種過度簡化了, 並不是從根本上來解決問題. 其實, 我現在的疑問就是在簡化的過程中遇到的.怎麼說呢? 如果在架構和代碼級上做些複雜的工作, 往往會對維護帶來意想不到的簡化...依靠framework和template讓大家書同文,車同軌,這才是真正的簡化.這個問題我昨天晚上參照beibeilong(whylove)和 windancer(^_^)的提示, 已經實現出來了.很方便, 我在UI與Business交互的時候, 根本不用擔心什麼DataTable了. 甚至, 我在想, 有此種還可以衍生出來一個ORM的framework... (^^!想太多了)
      

  31.   

    绑定的时候 <%#((Entity)Container.DataItem).property%>
      

  32.   

    这个贴子一定要回,
    现在的项目多出现返回dataSet和DataTable的用法,这种方法写程序
    对开发人员来说前期是很方便的,但是,在客户需求变化超出设计预想时,
    在原有系统面对多客户时表现出来的问题就很多,开发人员在维护项目时为了提供新功能,在原系统上升级包、打补丁,系统就失去了最初设计时的健壮性、完整性、安全性,系统有它的生命周期,到一定时期了,你的系统已经不能适应客户的大部分需求了,而由于设计时采用了过多的数据表结构定义在各层中出现,升级已经是十分大的工作量了,如果采用实体,应该是一个解决方法,xport(豁然开朗...) 提出的思路很好,我现正在研究Nhibernate希望能解决问题。
      

  33.   

    NHibernate是一個persistence framework, 其前身是Java陣營的Hibernate. 其實她提倡的是Pure Entity Object (Java叫做POJO, 除了屬性的setter/getter外, 沒有別的methods)的持久性管理...我不太喜歡這樣!我認為, Entity Object應該有自己的屬性和方法...
      

  34.   

    我想用DataSet或DataTable比较好的,一个原因就是“ShaftWhy(归去来兮)”说的,保持层与层之间接口简单;第二个原因是,DataTable可以很方便地与DataGrid()集成,如果用对象集合,就不容易实现了;第三个原因是,DataTable可以很方便地作二次查询(用Select()),如果用对象集合,就难以实现了;第四个原因,总是把 DataTable 变成对象集合,有点浪费资源,我的想法是,需要时才转换为对象。
      

  35.   

    回答FJGoodGood(_FJ_强中强):1. 請參考 fengxin107(追逐彩虹) 的回答, DataTable不能讓事情簡單.
    2. 請參考 beibeilong(whylove), windancer(^_^) 和CreaTive1911(草草了之) 的回答, 對象集合也可以綁定到DataGird.
    3. 不太明白, 是說用DataView做Filter嗎?
    4. 這個同意, 但是我們的機器總是越來越好的. :-p
      

  36.   

    使用类型化DataSet,具有DataSet和Entity两种特性
      

  37.   

    我的看法是:
    简单的用DataSet就行了
    复杂的尽量转换成简单的
    实在不行了再用Entity
      

  38.   

    Typed DataSet聽說是個好東東, 短期內覺得有點複雜...關係到XML Schema的東東...等我花些時間看看...
      

  39.   

    我写程序的思路是UI + 通道 + 数据库 通道: 通用的数据层、通用的翻页控件、级联菜单就是通用性很强的,写起来比较麻烦的东东。业务逻辑分为两种情况:简单的话就放在UI层和存储过程里面复杂的话就再写一个类,变成 UI + 业务逻辑 + 通道 + 数据库 这样呢通道是通用的,一般不需要修改,有变化的时候,改改存储过程了什么的就行了。在不用改数据结构的时候,一个人改改UI层、存储过程就可以了。
    如果需要修改数据结构的时候,那就是大的改动了,很可能是当初设计的不太合理,要麻烦一点了。
    但是改动的地方几乎没有增加,无论架构怎么设计,数据库都是要改的嘛。
      

  40.   

    to:jyk(喜欢编程。和气生财。共同提高。共同进步)
    看来你还不知道分层的好处,一来中间件可以在各种环境下使用web,client,offiice中通通没有问题,二来尽量减少对其他层的影响,隔离错误。
      

  41.   

    DataTable 的 Select() 方法可以在 DataTable 上作查询,比较好用。用对象还有一个麻烦的地方,表达主表、子表数据不方便,不够灵活。一般我们的表很多字段都是放ID,名称都在另外一个表,这样可能会作许多连接查询才可以获得数据,用对象比较麻烦。
      

  42.   

    传递单个实体时,我更喜欢用entity. 如果一个实体也用dataset传,未免太冗余了。
    传递集合时我用dataset 和datatabkl。
      

  43.   

    to  FJGoodGood(_FJ_强中强):"用对象还有一个麻烦的地方,表达主表、子表数据不方便,不够灵活" 这个应该是数据库设计方面的问题,不论Table间的关系如何,我们在使用的时候,总是需要通过SQL将Data抓回来,放到某一个容器中,这个时候,在使用Data的时候,就看不到与Database中相关连的东东了。应该说,除了数据访问层外,我们在系统中应该关心Domain Model中的对象.
      

  44.   

    回复人: FJGoodGood(_FJ_强中强) ( ) 信誉:100  2005-02-04 10:32:00  得分: 0  
     
     
       DataTable 的 Select() 方法可以在 DataTable 上作查询,比较好用。用对象还有一个麻烦的地方,表达主表、子表数据不方便,不够灵活。一般我们的表很多字段都是放ID,名称都在另外一个表,这样可能会作许多连接查询才可以获得数据,用对象比较麻烦。
      
    ===============================================================================
    主子表的话,通常使用外键(FK),那么在实体里面其实也是可以表达的,在Entity里面用一个只读的属性(Property)通过ID读取关联表相关内容(比如Name)
    这样做的好处是,数据表可以尽量的简化,无需为了编码方便而使用太多的冗余,而在UI层可以非常直观的取到关联表内容
    另有一个好处,在数据载入时无需把关联数据一次性载入,在用到的时候再动态读取(Lazyloading)
    ==========
    以上是我的浅见另 祝大家新年快乐 :)
      

  45.   

    >> 有一个好处,在数据载入时无需把关联数据一次性载入,在用到的时候再动态读取那要显示一个实体的界面,要读取多少次数据库啊?这对于C/S程序来说(特别是通过WebService连接数据库的程序),是很大的性能问题。
      

  46.   

    这就是Petshop模式和duwamish模式的区别了,ORM并不是万能的,根据不同的项目需求选择合适的模式也很必要,对C/S来说,可能Dataset更合适,这方面我经验不多,以后有用到的话再找 FJGoodGood(_FJ_强中强)兄弟请教了 :)
      

  47.   

    to:xiaolang88(没有米,所以想要米) 看来你还不知道分层的好处,一来中间件可以在各种环境下使用web,client,offiice中通通没有问题,二来尽量减少对其他层的影响,隔离错误。你说的中间件是什么呀?我确实没有体会到分层的好处,我也没有写过分层的程序。这方面的经验很少,还请多多帮忙。
      

  48.   

    分工不是重点,重点是便于维护和可扩展性...如果只是为了分工,按照传统的面向过程的开发模式,以function的分类就可以实现了.
      

  49.   

    DataSet (1) --> (0..n) DataTable, 这样的DT0就微软开发的体系来看,从DataAccess一直贯穿到Presentation Layer, 看来应该不需要Entity Layer了, 请问Sunmast,这样有什么好处吗?有没有一些类似Duwamish的示例的工程可以参考?
      

  50.   

    同意 xport(豁然开朗...)  的意见。
      

  51.   

    好贴.以前看过一些所谓的三层结构,用了reflection,性能不理想.希望能找到性能高的三层或多层结构解决方案.
      

  52.   

    在DAL取回Datareader或者Datatable,然后Add到Collection中,把Collection返回到logic layer
    我就是这么做的
    =====================================================================================
    我也是这么做的,但是我更赞同jyk(喜欢编程。和气生财。共同提高。共同进步) ( ) 信誉:100  2005-2-4 9:25:06  得分: 0  
     
     
       
    我的看法是:
    简单的用DataSet就行了
    复杂的尽量转换成简单的
    实在不行了再用Entity
    ======================================================================================不要为模式所约束  
     
      

  53.   

    我在一个WEB项目中采用了NHibernate作为数据访问层.所有对数库的处理都是通过NHibernater来操作.
    对于数据绑定都通过返回一个ArrayList的数组实现.比返回一个DataSet 要快(我认为)。数据的传递以Entity的为主。
    但对于一些大型的项目,如有几百个客户端的系统NHibernater不知道合不合适使用,主要是因为NHibernater对数据库的操作,好象太过于频繁。
      

  54.   

    to chsfly(一蓑烟雨任平生) ;
    采用nhibernate是个好提议,如果数据访问很频繁,建议不要使用对于楼主,我给人认为:如果系统不是很庞大,参考duwamish就可以,层与层之间就传dataset
    方便的很!但是如果业务规则改变很频繁,可以考虑传递entity
      

  55.   

    收到...思考中...就好比财务系统,注重data,所以较多采用Data Driven, 而HR系统业务规则变化平凡,所以多采用Domain Drivern。