菜鳥級三層框架(EF+MVC)項目實戰之 系列三 業務邏輯層封裝


 

概述:業務邏輯層封裝相對數據訪問層來說較為簡單,我們分為以下幾步:

         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 abstract  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 SetCurrentDao()
       {
           this.CurrentDao = this.DbSession.<#=entity.Name#>Dao;
       }
    }
<#};#>
}

        以下是運行T4模版后自動生成的代碼:

 

這時我們就對業務邏輯層封裝完成,系列四中使用MVC3.0簡單實現增刪改查以及分頁功能。

 

 

 

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM