业务逻辑层封装

述:业务逻辑层封装相对数据访问层来说较为简单,我们分为以下几步:

         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> LoadEntitesFunc<T, bool> whereLambda);
14 
15         //根据条件获取实体对象集合分页
16         IQueryable<T> LoadEntitesFunc<T, bool> whereLambda, int pageIndex, int pageSize, out int totalCount);
17 
18         //增加
19         T AddEntityT entity);
20 
21         //更新
22         T UpdateEntityT entity);
23 
24         //删除
25         bool DelEntityT entity);
26 
27         //根据条件删除
28         bool DelEntityByWhereFunc<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 CodeGenerationToolsthis);
MetadataLoader loader = new MetadataLoaderthis);
CodeRegion region = new CodeRegionthis, 1);
MetadataTools ef = new MetadataToolsthis);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollectioninputFile);
string namespaceName = code.VsNamespaceSuggestion);

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Createthis);
#>
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>).OrderBye => 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> LoadEntitesFunc<T, bool> whereLambda)
 4         {
 5             return this.CurrentDao.LoadEntiteswhereLambda);
 6         }
 7 
 8 
 9         public virtual IQueryable<T> LoadEntitesFunc<T, bool> whereLambda, int pageIndex, int pageSize, out int totalCount)
10         {
11             return this.CurrentDao.LoadEntiteswhereLambda, pageIndex, pageSize, out totalCount);
12         }
13 
14 
15         public virtual T AddEntityT entity)
16         {
17             var tmp= this.CurrentDao.AddEntityentity);
18             this.DbSession.SaveChange);
19             return tmp;
20         }
21 
22 
23         public virtual T UpdateEntityT entity)
24         {
25             var tmp= this.CurrentDao.UpdateEntityentity);
26             this.DbSession.SaveChange);
27             return tmp;
28         }
29 
30 
31         public virtual bool DelEntityT entity)
32         {
33             return this.CurrentDao.DelEntityentity);
34         }
35 
36 
37         public virtual bool DelEntityByWhereFunc<T, bool> whereLambda)
38         {
39             return this.DelEntityByWherewhereLambda);
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 CodeGenerationToolsthis);
MetadataLoader loader = new MetadataLoaderthis);
CodeRegion region = new CodeRegionthis, 1);
MetadataTools ef = new MetadataToolsthis);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollectioninputFile);
string namespaceName = code.VsNamespaceSuggestion);

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Createthis);
#>
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>).OrderBye => 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://www.cnblogs.com/Leo_wl/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注