數據訪問層負責管理數據庫與業務邏輯層之間的通訊。
下面我們以SysException單表的增刪改為例,進行介紹
-
創建數據庫Sys,數據庫名稱為"Sys",執行如下腳本

CREATE TABLE [SysException]( [Id] [nvarchar](36) NOT NULL, [LeiXing] [nvarchar](200) NULL, [Message] [nvarchar](4000) NULL, [Result] [nvarchar](200) NULL, [Remark] [nvarchar](4000) NULL, [State] [nvarchar](200) NULL, [CreateTime] [datetime] NULL, [CreatePerson] [nvarchar](200) NULL, CONSTRAINT [PK_SYSEXCEPTION] PRIMARY KEY NONCLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
-
創建一個DAL的項目
在項目上添加->新建項
選擇"ADO.NET 實體數據模型"
從數據庫生成,新建連接
填寫連接需要的數據庫信息后,點擊下一步
注意:只選擇"在模型中加入外鍵列"
可以看到新生成了兩個文件"App.Config"和"Model1.edmx":
"App.Config"里面是數據庫連接字符串,"Model1.edmx" 里面是數據實體類和訪問數據庫的上下文
-
以下為代碼部分:
- BaseRepository是數據訪問操作的基類

using System.Linq; using System.Data; namespace Langben.DAL { public abstract class BaseRepository<T> where T : class { ///<summary> /// 獲取所有 ///</summary> ///<returns>集合</returns> public virtual IQueryable<T> GetAll() { using (SysEntities db = new SysEntities()) { return GetAll(db); } } ///<summary> /// 獲取所有 ///</summary> ///<returns>集合</returns> public virtual IQueryable<T> GetAll(SysEntities db) { return db.CreateObjectSet<T>().AsQueryable(); } ///<summary> /// 創建 ///</summary> ///<param name="db">實體數據</param> ///<param name="entity">將要創建的對象</param> public virtual void Create(SysEntities db, T entity) { if (entity != null) { db.CreateObjectSet<T>().AddObject(entity); } } ///<summary> /// 創建 ///</summary> ///<param name="entity">一個對象</param> ///<returns></returns> public virtual int Create(T entity) { using (SysEntities db = new SysEntities()) { Create(db, entity); return this.Save(db); } } ///<summary> /// 創建對象集合 ///</summary> ///<param name="db">實體數據</param> ///<param name="entitys">對象集合</param> public virtual void Create(SysEntities db, IQueryable<T> entitys) { foreach (var entity in entitys) { this.Create(db, entity); } } ///<summary> /// 編輯一個對象 ///</summary> ///<param name="db">實體數據</param> ///<param name="entity">將要編輯的一個對象</param> public virtual T Edit(SysEntities db, T entity) { db.CreateObjectSet<T>().Attach(entity); db.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); return entity; } ///<summary> /// 編輯對象集合 ///</summary> ///<param name="db">實體數據</param> ///<param name="entitys">對象集合</param> public virtual void Edit(SysEntities db, IQueryable<T> entitys) { foreach (T entity in entitys) { this.Edit(db, entity); } } ///<summary> /// 提交保存,持久化到數據庫 ///</summary> ///<param name="db">實體數據</param> ///<returns>受影響行數</returns> public int Save(SysEntities db) { return db.SaveChanges(); } } }
- 所有數據實體都繼承自IBaseEntity接口

namespace Langben.DAL { public interface IBaseEntity { } } 業務實體(SysException)的定義和驗證元數據(SysExceptionMetadata) using System; using System.ComponentModel.DataAnnotations; namespace Langben.DAL { [MetadataType(typeof(SysExceptionMetadata))]// public partial class SysException : IBaseEntity { #region 自定義屬性,即由數據實體擴展的業務實體 #endregion } public class SysExceptionMetadata { [ScaffoldColumn(false)] [Display(Name = "主鍵", Order = 1)] public object Id { get; set; } [ScaffoldColumn(true)] [Display(Name = "類型", Order = 2)] [StringLength(200, ErrorMessage = "長度不可超過200")] public object LeiXing { get; set; } [ScaffoldColumn(true)] [Display(Name = "內容", Order = 3)] [StringLength(4000, ErrorMessage = "長度不可超過4000")] public object Message { get; set; } [ScaffoldColumn(true)] [Display(Name = "結果", Order = 4)] [StringLength(200, ErrorMessage = "長度不可超過200")] public object Result { get; set; } [ScaffoldColumn(true)] [Display(Name = "備注", Order = 5)] [StringLength(4000, ErrorMessage = "長度不可超過4000")] public object Remark { get; set; } [ScaffoldColumn(true)] [Display(Name = "狀態", Order = 6)] [StringLength(200, ErrorMessage = "長度不可超過200")] public object State { get; set; } [ScaffoldColumn(true)] [Display(Name = "創建時間", Order = 7)] [DataType(DataType.DateTime,ErrorMessage="時間格式不正確")] public DateTime? CreateTime { get; set; } [ScaffoldColumn(true)] [Display(Name = "創建人", Order = 8)] [StringLength(200, ErrorMessage = "長度不可超過200")] public object CreatePerson { get; set; } } }
- 數據訪問層執行數據庫中的增刪改操作

using System; using System.Collections.Generic; using System.Linq; using System.Data; namespace Langben.DAL { ///<summary> /// 異常處理 ///</summary> public class SysExceptionRepository : BaseRepository<SysException>,IDisposable { ///<summary> /// 通過主鍵id,獲取異常處理---查看詳細,首次編輯 ///</summary> ///<param name="id">主鍵</param> ///<returns>異常處理</returns> public SysException GetById(string id) { using (SysEntities db = new SysEntities()) { return GetById(db, id); } } ///<summary> /// 通過主鍵id,獲取異常處理---查看詳細,首次編輯 ///</summary> ///<param name="id">主鍵</param> ///<returns>異常處理</returns> public SysException GetById(SysEntities db, string id) { return db.SysException.SingleOrDefault(s => s.Id == id); } ///<summary> /// 確定刪除一個對象,調用Save方法 ///</summary> ///<param name="id">一條數據的主鍵</param> ///<returns></returns> public int Delete(string id) { using (SysEntities db = new SysEntities()) { this.Delete(db, id); return Save(db); } } ///<summary> /// 刪除一個異常處理 ///</summary> ///<param name="db">實體數據</param> ///<param name="id">一條異常處理的主鍵</param> public void Delete(SysEntities db, string id) { SysException deleteItem = GetById(db, id); if (deleteItem != null) { db.SysException.DeleteObject(deleteItem); } } ///<summary> /// 刪除對象集合 ///</summary> ///<param name="db">實體數據</param> ///<param name="deleteCollection">主鍵的集合</param> public void Delete(SysEntities db, string[] deleteCollection) { //數據庫設置級聯關系,自動刪除子表的內容 IQueryable<SysException> collection = from f in db.SysException where deleteCollection.Contains(f.Id) select f; foreach (var deleteItem in collection) { db.SysException.DeleteObject(deleteItem); } } public void Dispose() { } } }
-
我們約定:
- 將系統需要的基礎類放在"Framework"文件夾中
- 所有的實體數據都需要繼承IBaseEntity接口
- 所有的數據庫操作都需要繼承BaseRepository抽象類
- 所有的試圖都需要繼承BaseViewRepository抽象類
- 在數據實體上實現驗證規則,對用戶將來保存到數據庫中的數據進行校驗,保護數據的完整性
- Model1.edmx文件是Entity Framework自動生成的,不做修改,因為每次更新會覆蓋。
這里使用了分部類(partial class)對實體數據SysException進行擴展,加入自定義的屬性,使用SysExceptionMetadata對SysException進行數據驗證。
以上我們完成了數據訪問層的設計,下一章我們實現業務邏輯層的代碼