前言:
本篇主要讲述如何把DAL和BLL衔接起来。
本篇议题如下:
1).DAL和BLL之前的Mapping
2)。如何Mapping
3)。再次构思
1.DAL和BLL之前的Mapping
首先,业务类和数据实体类不是一 一对应的关系,换句话说,不是一个业务类就一定对应数据库中的一张表。业务类是用只是使用数据实体中的数据而已,所以一个业务类中的数据往往来自多个数据实体。
每个业务类都是有自己的一些属性的,把数据以数据实体或者DataTable的形式从DAL获取之后,BLL类就使用这些数据,BLL不会把这些原生的数据实体暴露给UI。BLL类会把UI中要是用的数据装入到自己的属性中。
所以在这个过程中就有一个赋值的过程,或者称为mapping映射。当Richard提出这个想法后,项目组的同事就问他:为什么要做的这么复杂,还要一 一 的赋值,为什么不直接把数据实体给UI使用,为什么一定要在中间这么转一下呢?
Richard分析了一些原因:
1. 如果直接把数据实体给了UI,那么UI那端就很清楚DAL了,以后数据访问方式从ADO.NET 到了EF,那么UI 就动了,又回到以前了。
2.在BLL中可以对从DAL取出来的数据进行一些处理,如转换格式,计算,组合等。
Richard想到把BLL和DAL彻底的解耦:业务类中不存在数据实体类的引用。这样设计之后灵活性就很大了。最后达到的效果就是:通过配置,配置业务类每个属性的数据的来源。而这个业务类完全不知道这些数据到底来源于哪个或者哪些数据实体。
这样确实很灵活,Richard兴奋不已。
2. 如何Mapping
初步想法通过配置文件。如现在有一个Product的业务类,定义如下:
代码
public class ProductBL public string ProductName { get; set; } public decimal Price { get; set; } public string Description { get; set; } } |
那么如何给这些属性赋值,同时也不引用数据实体。Richard用配置文件来实现的,这里Richard就约定了:配置文件的名字就是“业务类的名字”+“Mapping.xml”。所以Product的配置文件就是ProductBLMapping.xml
代码
<?xml version="1.0" encoding="utf-8" ?> <BusinessModel name="ProductBL" mappingTo="DAL.ProductEntity" > <property name="ProductName" mappingTo="Name" type="System.String"/> <property name="Price" mappingTo="Price" type="System.Decimal"/> <property name="Description" mappingTo="Description" type="System.String"/> </BusinessModel> |
然后再运行的时候就通过反射来赋值。
现在问题又来了:
1).每次都是通过反射来赋值,性能很成问题。
2).如果配置文件出错,调试很不方便。
3).如何处理一个业务类对应对个数据实体的情况,如:
代码
public class ProductBL //来自CustomDAL } |
但是好处很明显:
1).DAL和BLL解耦
2).很便于查询对象的实现。例如:在UI代码写:
ICriteria condition=CriteriaFactory.Create(typeof(ProductBL).Where("ProductName", Operation.Equal,"book");
当然ProductName是业务类ProductBL的属性,在查询对象最后解析为SQL语句的时候就可以利用ProductBLMapping.xml来生成SQL。
(注:小洋请大家想想,上面的思想来自于.NET中哪个开源框架?)
对于性能方面,Richard尝试这样解决:
在第一次Mapping的时候,就把这些mapping的信息保存在静态字典中,下次在mapping的时候,就不用再读配置文件了,而且读内存中的字典。
但是这样,随着业务类的增加,内存使用也加大,而且赋值方式还是反射。
3. 再次构思
Richard接着考虑:如何处理一个业务类对应对个数据实体的情况?于是配置文件就改为了:
代码
<?xml version="1.0" encoding="utf-8" ?> <BusinessModel name="ProductBL" > <property name="ProductName" mappingTo="DAL.ProductEntityName" type="System.String"/> <property name="Price" mappingTo="DAL.ProductEntityPrice" type="System.Decimal"/> <property name="Description" mappingTo="DAL.ProductEntityDescription" type="System.String"/> <property name="CustomerName" mappingTo="DAL.CustomerEntity.Name" type="System.String"/> </BusinessModel> |
基本的问题算是解决了,但是性能的问题依然存在。
Richard又开始考虑更加好的方式。
本篇就写到这里,谢谢各位。