菜鳥級三層框架(EF+MVC)項目實戰之 系列二 對數據訪問層的抽象下


概述:1、對數據訪問層進行封裝

         2、對業務層提供統一入口

         3、線程內實例唯一

一、數據訪問層封裝抽象

    1.1、在程序集Cnblogs.Rdst.IDAO中創建IDBSession接口,其主要目的是將所有實體類封裝為屬性。

           

    1.2、IDBSession接口中定義SaveChange()方法,定義該方法的意義會在業務邏輯中介紹。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8     public partial interface IDBSession
 9     {
10         int SaveChange();//用於在業務邏輯層對提交進行管理
11     }
12 }

     1.3、創建名為IDBSessionExt的T4模版,實現自動生成IDBSession的部分接口,其中將所有實體類定義為接口屬性,以實現對數據訪問層的封裝。
 

<#@ 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.IDAO
{
  public partial interface IDBSession
  {
    <#foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
    {#>    
        I<#=entity.Name#>Dao <#=entity.Name#>Dao { get; set; }
    <#};#>
 }
}

    1.4、T4模版編輯完成后,運行后生成的代碼如下:

        

 

二、數據訪問層統一入口抽象

      在程序集Cnblogs.Rdst.IDAO中創建IDbSessionFactory接口,為業務邏輯層提供統一訪問入口。

      該接口中定義GetCurrentDBSession()方法,其作用是通過該接口方法獲取需要的實體對象。       

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8     public interface IDBSessionFactory
 9     {
10         IDBSession GetCurrentDBSession();
11     }
12 }

三、實現IDBSession

   3.1、在Cnblogs.Rdst.Dao程序集中創建DBSession 部分類

          

   3.2、在Cnblogs.Rdst.Dao程序集中創建名為DBSessionExt的T4模版,將所有實體類自動封裝為屬性,以下是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.IDAO;

namespace Cnblogs.Rdst.Dao
{
  public partial class DBSession : IDBSession
  {
    <#foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
    {#>    
        private I<#=entity.Name#>Dao _<#=entity.Name#>Dao;
        public I<#=entity.Name#>Dao <#=entity.Name#>Dao
        {
            get
            {
                if (_<#=entity.Name#>Dao == null)
                {
                    _<#=entity.Name#>Dao = new <#=entity.Name#>Dao();
                }
                return _<#=entity.Name#>Dao;
            }
            set { _<#=entity.Name#>Dao = value; }
        }
    <#}#>
 }
}

    3.3保存模版並運行,T4模版會自動將所有實體對象封裝為屬性。如下代碼所示:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using Cnblogs.Rdst.IDAO;
 6 
 7 namespace Cnblogs.Rdst.Dao
 8 {
 9   public partial class DBSession : IDBSession
10   {
11         
12         private INoteInfoDao _NoteInfoDao;
13         public INoteInfoDao NoteInfoDao
14         {
15             get
16             {
17                 if (_NoteInfoDao == null)
18                 {
19                     _NoteInfoDao = new NoteInfoDao();
20                 }
21                 return _NoteInfoDao;
22             }
23             set { _NoteInfoDao = value; }
24         }
25         
26         private IUserInfoDao _UserInfoDao;
27         public IUserInfoDao UserInfoDao
28         {
29             get
30             {
31                 if (_UserInfoDao == null)
32                 {
33                     _UserInfoDao = new UserInfoDao();
34                 }
35                 return _UserInfoDao;
36             }
37             set { _UserInfoDao = value; }
38         }
39      }
40 }

     3.4、打開剛創建的DBSession類,實現IDBSession接口。並重新SaveChanges()方法,SaveChange()方法中調用了EF上下文中的SaveChange(),

            其用途會在業務邏輯層進行詳細說明。

            以下是DBSession類中的實現代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IDAO;
using System.Data.Objects;

namespace Cnblogs.Rdst.Dao
{
    public partial class DBSession : IDBSession
    {
        private ObjectContext _efContext;

        //EF上下文
        public ObjectContext EfContext
        {
            get
            {
                if (_efContext == null)
                {
                  _efContext= ObjectContextFactory.GetCurrentObjectContext();
                }
                return _efContext;
            }
            set { _efContext = value; }
        }

        public int SaveChange()
        {
            return EfContext.SaveChanges();//調用SaveChanges()方法提交操作
        }


    }
}

四、實現數據訪問層統一入口
      接下來現在我們需要在Cnblogs.Rdst.Dao程序集中實現IDbSessionFactory接口

      創建DBSessionFactory類並實現IDbSessionFactory接口,為了避免資源浪費,也用到了CallContex實現了線程內實例唯一。

      以下是DBsessionFactory類中的實現代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IDAO;
using System.Runtime.Remoting.Messaging;

namespace Cnblogs.Rdst.Dao
{
   public class DBSessionFactory:IDBSessionFactory
    {
        public IDBSession GetCurrentDBSession()
        {
            IDBSession dbSession = CallContext.GetData(typeof(DBSessionFactory).FullName) as DBSession;
            if (dbSession == null)
            { 
               dbSession=new DBSession();
               CallContext.SetData(typeof(DBSessionFactory).FullName, dbSession);
            }
            return dbSession;
        }
    }
}


至此,我們就已經完成了對數據訪問層的封裝。

總結:1、方便了對數據庫的替換數據庫,只需要在ObjectContextFactory中進行替換相應的FE上下文。

         2、當數據庫中的表或字段有更新時,我們只需要重新運行一下相應T4模版,就可以實現與數據庫保存一致。

接下來的系列三中會介紹業務邏輯層是如何調用數據訪問層,稍后會進行更新。  

 

 

   

 

 

       

 

 

 

 

        


免責聲明!

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



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