[原创].NET 业务框架开发实战之六 DAL的重构

简介: 原文:[原创].NET 业务框架开发实战之六 DAL的重构.NET 业务框架开发实战之六 DAL的重构  前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了名字,主要是因为文章的标题带来了不少的歧义:系列文章中本打算开发一个简化业务发的流程的Framework,然后用这个Framework再来实战,开发一个分布式的应用。
原文: [原创].NET 业务框架开发实战之六 DAL的重构

.NET 业务框架开发实战之六 DAL的重构
  前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了名字,主要是因为文章的标题带来了不少的歧义:系列文章中本打算开发一个简化业务发的流程的Framework,然后用这个Framework再来实战,开发一个分布式的应用。改了名字。给大家带来了不便,敬请见谅。

   本篇的议题如下:
   1. 确定DAL的接口的定义。

 

  系列文章链接:

 [原创].NET 分布式架构开发实战之一 故事起源

[原创].NET 分布式架构开发实战之二 草稿设计

[原创].NET 分布式架构开发实战之三 数据访问深入一点的思考

[原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)

[原创].NET 分布式架构开发实战五 Framework改进篇

[原创].NET 业务框架开发实战之六 DAL的重构

[原创].NET 业务框架开发实战之七 业务层初步构想

[原创].NET 业务框架开发实战之八 业务层Mapping的选择策略

[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略

[原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇)

[原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇)

 

 

 

   之前在开发DAL中,提出了一些思想,也设计了一些接口。现在就把DAL的一些设计完善起来。说是“完善”,并不是说把所有的代码都实现,而是把该定义的接口,方法敲定下来。Richard认为,设计一个架构或者Framework的时候,开始是接口的定义,定义好各层之间交互的接口,然后才是具体代码的实现。


   因为在设计Framework的时候,首先要考虑这个Framework的使用者是谁,希望他们怎么样来使用开发出来的这个Framework。在这里,Richard很明白:Framework的使用者就是自己公司里的开发人员。而且还要使得开发的使用尽量的方便,不要到处去配置一些文档,最好就是把Framework引入进来,稍微配一下就使用。

 

  在Richard设计的Framework中,就DAL而言,如果希望DAL返回DataTable,DataReader等给BLL,那么需要配置的仅仅只是指明数据库的连接字符串;如果希望DAL返回的数据实体给BLL,那么就得把一张张的表映射成为实体,然后让这些实体继承IDataEntity接口就行了(生成实体可以用ORM工具,或者自己手写代码)。

 Richard思考了之前对DAL的设计,在此他做了一些改进。


   首先就是对于IDataContext的重新设计和理解:之前的设计是定义了IDataContext,然后用不同的方式实现这个接口,如LinqDataContext.Provider就是用Linq的方法来返回结果(DataResult)。现在Richard认为IDataContext其实就是用来操作数据库的,所以返回的结果就应该是操作数据之后的结果,如Update操作就返回受影响的行数或者是否更新成功。至于是否要把一些额外的信息包装返回给BLL,就不是IDataContext的实现者的事情了。而且Richard还考虑到了需要在一定程度上支持原生的ADO.NET,起码给ADO.NET预留接口。

 

   基于此,Richard就把IDataContext定义为一个接口声明,然后再定义了IDataEntityContext,和IDataTableContext来继承IDataContext,他们的关系图如下:

  

  

   其中IDataEntityContext使用Linq和Entity Framework来实现,而IDataTableContext就是用ADO.NET的方式来实现。

    IDataEntityContext接口的和系列文章中定义的一些方法差不多,但是做了修改。其中有一点要提的就是:ICriteria就是所有条件对象要实现的接口(查询对象也是条件对象的一种)。例如,可以根据相应的条件删除,更新数据。


 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
  ///   <summary>
    
///  所有的数据实体执行者实现这个借口
    
///   </summary>
     public   interface  IDataEntityContext:IDataContext
    {
        TEntity Add < TEntity > (TEntity entity)  where  TEntity : IDataEntity;
        List < TEntity >  Add < TEntity > (List < TEntity >  entityList)  where  TEntity : IDataEntity;

        
bool  Update < TEntity > (TEntity entity)  where  TEntity : IDataEntity;
        
bool  Update < TEntity > (List < TEntity >  entityList)  where  TEntity : IDataEntity;
        
bool  Update(ICriteria condiftion,  object  value);

        
bool  Delete < TEntity > (TEntity entity)  where  TEntity : IDataEntity;
        
bool  Delete < TEntity > (List < TEntity >  entityList)  where  TEntity : IDataEntity;
        
bool  Delete(ICriteria condition);

        
int  GetCount(ICriteria condition);
        List < TEntity >  Query < TEntity > (ICriteria condition);
        List < TEntity >  Query < TEntity > (ICriteria condition,  int  pageIndex,  int  pageSize,  ref   int  entityCount)  where  TEntity : IDataEntity;
        List < object >  Query(ICriteria condiftion);
    }

 

 

   另外就是多了一个 List<object> Query(ICriteria condiftion);方法,之所以有这个方法,Richard考虑到,可能开发人员想要直接自己写SQL语句去执行,如select avg(Count),sum(Name) from Customer...,开发人员可以写任意的语句,所以返回一个实体类不现实,就返回一个List<object>。

 

   还有一点就是关于查询对象的改进:以前仅仅只是定义了查询对象的接口,现在用ICriteria 接口中定义来条件对象,而且还可以在条件对象声明是在对数据操作是否采用事务或者缓存。

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
  ///   <summary>
    
///  所有的条件对象都要从这个接口继承
    
///   </summary>
     public   interface  ICriteria
    {
        
string  Name {  get set ; }
        
bool  IsCache {  get set ; }
        
bool  IsTransaction {  get set ; }
    }

 

   

  之后Richard又定义了一个IDataProvider,接口,声明如下 :

 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
  ///   <summary>
    
///  数据提供者要实现的借口
    
///   </summary>
     public   interface  IDataProvider
    {
        DataResult < TEntity >  Add < TEntity > (TEntity entity)  where  TEntity : IDataEntity;
        DataResult < TEntity >  Add < TEntity > (List < TEntity >  entityList)  where  TEntity : IDataEntity;

        DataResult < TEntity >  Update < TEntity > (TEntity entity)  where  TEntity : IDataEntity;
        DataResult < TEntity >  Update < TEntity > (List < TEntity >  entityList)  where  TEntity : IDataEntity;
        
bool  Update(ICriteria condiftion,  object  value);

        DataResult < TEntity >  Delete < TEntity > (TEntity entity)  where  TEntity : IDataEntity;
        DataResult < TEntity >  Delete < TEntity > (List < TEntity >  entityList)  where  TEntity : IDataEntity;
        
bool  Delete(ICriteria condiftion);

        
int  GetCount(ICriteria condition);

        DataResult < TEntity >  GetOne < TEntity > (ICriteria condition)  where  TEntity : IDataEntity;
        DataResult < TEntity >  GetList < TEntity > (ICriteria condition)  where  TEntity : IDataEntity;
        DataResult < TEntity >  GetPageData < TEntity > (ICriteria condition,  int  pageIndex,  int  pageSize,  ref   int  entityCount)  where  TEntity : IDataEntity;
        List < object >  GetCustomData(ICriteria condiftion);
    }

 

 

   之所以要定义这个接口,其实 Richard就是想让实现了IDataContext的类踏踏实实的去做底层的数据操作,至于数据操作之后的结果以什么形式给BLL,不用IDataContext的实现者来关心,而是用IDataProvider的实现者来关心。


   在IDataProvider的实现者在底层就是调用了IDataContext的实现者的方法,然后在IDataProvider中,对外提供了一些更加友好和方便使用的方法,最后在BLL中直接依赖的就是IDataProvider,而不是IDataContext。


   另外,对于IDataProvider返回的DataResult也做了一些修改:如果返回的是数据实体,即 使用的是IDataEntityContext来提供底层的数据操作,那么DataResult<TEntity>是没有问题的;但是如果使用的是IDataTableContext,那么返回DataResult<TEntity>就不行了,因为IDataTableContext查询方法可能返回的DataTable,或者DataReader.所以,在设计中叶预留了一个接口:让IDataProvider返回的结果实现IDataResult接口,那么ataResult<TEntity>继承这个接口,主要用来返回数据实体,如下:
 

   

  DAL的设计就到这里,下一篇文章就开始讲述对业务层的一些思考。

  版权为小洋和博客园所有,转载请标明出处给作者。

    http://www.cnblogs.com/yanyangtian

   代码下载  

  

目录
相关文章
|
7月前
|
人工智能 芯片
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
|
5月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
181 0
|
8月前
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
318 23
|
9月前
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
146 9
|
9月前
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
120 8
|
9月前
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
122 7
|
9月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
219 5
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
195 7
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
375 0
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
213 0