概述: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模版,就可以實現與數據庫保存一致。
接下來的系列三中會介紹業務邏輯層是如何調用數據訪問層,稍后會進行更新。
