數據訪問層及EntityFramework
阿新 • • 發佈:2018-08-02
定義 標識 comm first 工作 ret 延遲 dot obj
數據訪問層(Data Access Layer)負責與數據儲存設備打交道,為業務層提供數據服務(一般指增、刪、改、查)。一個好的數據訪問層可在不影響其他邏輯的情況下,替換數據訪問技術、數據據庫。
數據訪問層的常見模式與原則
- 工作單元(Unit of Work)
維護一系列操作的事務性(Transaction),一系列操作要麽都成功,如果有一個操作失敗,則事務回滾。這裏也主要用於對數據庫的操作。
如果通過sql
腳本直接訪問數據庫,可以直接用sql
調用相應數據庫的事務。
如果采用自己寫的ORM,則可定義一個IUnitOfWork
接口,將增、刪、改的數據保存進集合,在Commit
方法將object數據存儲數據庫,可通過TransactionScope
public interface IUnitOfWork { void RegisterAmended(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository); void RegisterNew(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository); void RegisterRemoved(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository); void Commit(); }
如果利用第三方ORM庫,一般都提供Unit of work
- 標識映射
標識映射即通過唯一標識,將加載的數據存入緩存,方便下次訪問。
- 延遲加載 表示需要時才去加載所需的資源。一般指需要時采取加載外鍵關聯的表。如在學生管理系統,每個學生都有自己的成績,在展示學生列表時不加載成績,只有進入某個學生詳細信息才加載。
數據並發控制
同時修改一份數據造成修改沖突,一般通過為數據添加一個version
屬性表明版本。EntityFramework
EntityFramework是微軟官方提供的ORM類庫,其采用
Repository
模型,功能強大,這裏簡單介紹下其數據訪問層特性的實現。工作單元(Unit of Work)
- 隱式事務
using (var context = new MyStoreContext())
{
customer = new Customer { FirstName = request.FirstName, LastName = request.LastName };
context.Customers.Add(customer);
context.SaveChanges();
return customer;
}
其中context.SaveChanges()
方法事務執行,其內部實現了事務。
- 顯示事務
using (var context = new BloggingContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context.SaveChanges();
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
context.SaveChanges();
var blogs = context.Blogs
.OrderBy(b => b.Url)
.ToList();
transaction.Commit();
}
catch (Exception)
{
// TODO: Handle failure
}
}
}
- Cross-context transaction(跨庫的事務)
using (var context1 = new BloggingContext(connectionstring1))))
{
using (var transaction = context1.Database.BeginTransaction())
{
try
{
context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context1.SaveChanges();
using (var context2 = new BloggingContext(connectionstring2))
{
//context2 用context1的事務
context2.Database.UseTransaction(transaction.GetDbTransaction());
var blogs = context2.Blogs
.OrderBy(b => b.Url)
.ToList();
}
transaction.Commit();
}
catch (Exception)
{
// TODO: Handle failure
}
延遲性加載
EntityFramework 默認為延遲加載,如果希望饑渴加載需要include
數據並發控制
為實體添加version
屬性
[Timestamp]
public byte[] RowVersion { get; set; }
通過異常機制查詢保存的數據是否被修改或刪除,異常為DbUpdateConcurrencyException
數據訪問層及EntityFramework