业务逻辑层封装
述:业务逻辑层封装相对数据访问层来说较为简单,我们分为以下几步:
1、抽象基接口定义CRUD方法
2、应用T4模版生成所有实体接口
3、接口实现
一、接口定义
1.1、创建名为Cnblogs.Rdst.IBLL的程序集,主要用于业务逻辑层接口定义
并引用Cnblogs.Rdst.Domain和System.Data.Entity。这里需要注意,只要是用到EF实体,就需要添加System.Data.Entity引用。
1.2、创建IBaseService接口定义CRUD方法
这里可以直接将IBaseDao中定义的方法拷贝过来。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Cnblogs.Rdst.IBLL
7 {
8 public interface IBaseService<T>
9 where T: class ,
10 new ()
11 {
12 // 根据条件获取实体对象集合
13 IQueryable<T> LoadEntites(Func<T, bool > whereLambda);
14
15 // 根据条件获取实体对象集合分页
16 IQueryable<T> LoadEntites(Func<T, bool > whereLambda, int pageIndex, int pageSize, out int totalCount);
17
18 // 增加
19 T AddEntity(T entity);
20
21 // 更新
22 T UpdateEntity(T entity);
23
24 // 删除
25 bool DelEntity(T entity);
26
27 // 根据条件删除
28 bool DelEntityByWhere(Func<T, bool > whereLambda);
29 }
30 }
1.3、创建名为IServiceExt的T4模版,用于自动生成所有实体对象的接口,并继承自IBaseService接口
以下是T4模版中的代码:
<#@ template language= " C# " debug= " false " hostspecific= " true " #>
<#@ include file= " EF.Utility.CS.ttinclude " #>< #@
output extension = " .cs " #>
< #
CodeGenerationTools code = new CodeGenerationTools( this );
MetadataLoader loader = new MetadataLoader( this );
CodeRegion region = new CodeRegion( this , 1 );
MetadataTools ef = new MetadataTools( this );
string inputFile = @" ..\\Cnblogs.Rdst.Domain\\Model.edmx " ;
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create( this );
# >
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;
namespace Cnblogs.Rdst.IBLL
{
< #
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{# >
public interface I<#=entity.Name#>Service : IBaseService<<#=entity.Name#>>
{
}
<#};#>
}
以下是T4模版运行后,自动为我们生成的代码:
至此,业务逻辑层的接口就定义完成了。
二、抽象出业务逻辑层的基类
2.1、创建名为Cnblogs.Rdst.BLL程序集,并添加DAO、Domain、IBLL、IDAO、System.Data.Entity程序集引用,如下图
2.2、接下来是我们的重点,创建名为BaseService基类。该基类中实现了对数据访问层的调用,也实现了CRUD
步骤: 1、先将IDBSessionFactory封装为属性,用于获取IDBSession
2、再将IDBSession封装为属性,用于获取EF上下文对象
3、定义IBaseDao类型的CurrentDao属性,用于属性获取具体的实体对象
4、定义抽象方法 SetCurrentDao(),用于子类设置实现,为CurrentDao属性赋具体的实体对象
以下是这部分代码实现:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using Cnblogs.Rdst.IDAO;
6 using Cnblogs.Rdst.Dao;
7
8
9 namespace Cnblogs.Rdst.BLL
10 {
11 public class BaseService<T>
12 where T : class ,
13 new ()
14 {
15 // 构造函数
16 public BaseService()
17 {
18 // 调用SetCurrentDao()方法,要求子类必须实现
19 SetCurrentDao();
20 }
21
22 // 获取EF实体工厂
23 IDBSessionFactory _dbSessionFactory;
24 IDBSession _dbSession;
25
26 public IDBSessionFactory DbSessionFactory
27 {
28 get
29 {
30 if (_dbSessionFactory == null )
31 {
32 _dbSessionFactory = new DBSessionFactory();
33 }
34 return _dbSessionFactory;
35 }
36 set { _dbSessionFactory = value; }
37 }
38
39
40 public IDBSession DbSession
41 {
42 get
43 {
44 if (_dbSession == null )
45 {
46 _dbSession = DbSessionFactory.GetCurrentDBSession(); // 通过数据访问层提供的工厂获取EF实体对象
47 }
48 return _dbSession;
49 }
50 set { _dbSession = value; }
51 }
52 // 数据访问层基接口类型可以接收数据访问层的所有实体Dao
53 public IBaseDao<T> CurrentDao { get ; set ; }
54
55 // 该方法用于子类实现,其作用是设置相应的实体Dao
56 public abstract void SetCurrentDao();
//以下是CRUD实现
2.3、实现CRUD
有了EF上下文,我们就可以实现CRUD
在实现增加和更新方法是,我们这时调用DBSessin中封装的SaveChanges()方法进行提交,主要目的是实现业务层控制提交。
由于EF具有延迟加载特性,因此我们利用此特性,实现批量操作时,一次提交数据库,已提程序高性能。
因此我们这时需要将BaseDao中的增加和更新方法中的SaveChange()方法注视掉,在此我就不贴出此部分代码了。
以下是CRUD实现代码:
1 // 以下是CRUD实现
2
3 public virtual IQueryable<T> LoadEntites(Func<T, bool > whereLambda)
4 {
5 return this .CurrentDao.LoadEntites(whereLambda);
6 }
7
8
9 public virtual IQueryable<T> LoadEntites(Func<T, bool > whereLambda, int pageIndex, int pageSize, out int totalCount)
10 {
11 return this .CurrentDao.LoadEntites(whereLambda, pageIndex, pageSize, out totalCount);
12 }
13
14
15 public virtual T AddEntity(T entity)
16 {
17 var tmp= this .CurrentDao.AddEntity(entity);
18 this .DbSession.SaveChange();
19 return tmp;
20 }
21
22
23 public virtual T UpdateEntity(T entity)
24 {
25 var tmp= this .CurrentDao.UpdateEntity(entity);
26 this .DbSession.SaveChange();
27 return tmp;
28 }
29
30
31 public virtual bool DelEntity(T entity)
32 {
33 return this .CurrentDao.DelEntity(entity);
34 }
35
36
37 public virtual bool DelEntityByWhere(Func<T, bool > whereLambda)
38 {
39 return this .DelEntityByWhere(whereLambda);
40 }
41 }
42 }
至此,BaseService业务逻辑层基类就封装完成,接下来使用T4模版自动生成所有实体。
2.4、创建名为ServiceExt的T4模版
以下是模版中的代码:
<#@ template language= " C# " debug= " false " hostspecific= " true " #>
<#@ include file= " EF.Utility.CS.ttinclude " #>< #@
output extension = " .cs " #>
< #
CodeGenerationTools code = new CodeGenerationTools( this );
MetadataLoader loader = new MetadataLoader( this );
CodeRegion region = new CodeRegion( this , 1 );
MetadataTools ef = new MetadataTools( this );
string inputFile = @" ..\\Cnblogs.Rdst.Domain\\Model.edmx " ;
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create( this );
# >
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IBLL;
using Cnblogs.Rdst.Domain;
namespace Cnblogs.Rdst.BLL
{
< #
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{# >
public partial class <#=entity.Name#>Service : BaseService<<#=entity.Name#>>, I<#=entity.Name#> Service
{
public override void SetCurrenDao()
{
this .CurrentDao = this .DbSession.<#=entity.Name#> Dao;
}
}
<#};#>
}
以下是运行T4模版后自动生成的代码:
这时我们就对业务逻辑层封装完成,系列四中使用MVC3.0简单实现增删改查以及分页功能。
标签: EF
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息