.NET 3.5 SP1 釋出後,EF 吸引大量開發者用於資料存取層。但 Spring.NET 當前版本僅支援原生 ADO.NET 與 NHibernate,不知如何整合 EF 以獲得 Spring 事務管理與 AOP 能力。作者研究後給出完整整合方案。
System.Transactions.TransactionScopeObjectContext 與資料庫互動,提供基類統一管理原始代碼:
[Transaction]
static void DbOperation() {
// 資料存取代碼
}
AOP 作用後:
[Transaction]
static void DbOperation() {
TransactionScope ts = new TransactionScope();
try {
// 資料存取代碼
ts.Complete();
} finally {
ts.Dispose();
}
}
public class EFSupport<TObjectContext> : DaoSupport
where TObjectContext : ObjectContext
{
public TObjectContext Database { get; set; }
protected override void CheckDaoConfig() {
if (this.Database == null) throw new ArgumentException("Database cannot be null.");
}
}
public interface IOrderDao {
void AddOrder(Order order);
void AddOrderItems(IList<OrderItem> orderItems);
}
public class OrderDao : EFSupport<DemoEntities>, IOrderDao {
[Transaction]
public void AddOrder(Order order) {
this.Database.AddToOrderSet(order);
this.Database.SaveChanges();
}
[Transaction]
public void AddOrderItems(IList<OrderItem> orderItems) {
foreach (var item in orderItems)
this.Database.AddToOrderItemSet(item);
this.Database.SaveChanges();
}
}
<objects xmlns="https://www.springframework.net">
<object id="EFTxSampleEntities" type="Demo.EFTxSample.EFTxSampleEntities">
<constructor-arg name="connectionString" value="metadata=res://*;provider=System.Data.SqlClient;provider connection string="Data Source=...;Initial Catalog=Demo;Integrated Security=True;MultipleActiveResultSets=True""/>
</object>
<object id="orderDao" type="Demo.EFTxSample.OrderDao">
<property name="Database" ref="EFTxSampleEntities"/>
</object>
<object id="transactionManager" type="Spring.Data.Core.TxScopeTransactionManager, Spring.Data">
</object>
<object id="autoProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>
<object id="transactionAdvisor" type="Spring.Transaction.Interceptor.TransactionAttributeSourceAdvisor, Spring.Data">
<property name="TransactionInterceptor" ref="transactionInterceptor"/>
</object>
<object id="transactionInterceptor" type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
<property name="TransactionManager" ref="transactionManager"/>
<property name="TransactionAttributeSource" ref="attributeTransactionAttributeSource"/>
</object>
<object id="attributeTransactionAttributeSource" type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
</objects>
TxScopeTransactionManager:整合 TransactionScope 的事務管理器DefaultAdvisorAutoProxyCreator:自動代理建立器,啟用 AOPTransactionAttributeSourceAdvisor + TransactionInterceptor:攔截 [Transaction] 屬性方法AttributesTransactionAttributeSource:從屬性讀取事務定義EFSupport<T>:泛型基類注入 ObjectContext,CheckDaoConfig 確保非空附件提供完整可運行範例。此方案讓 EF 專案無縫享受 Spring.NET 宣告式事務與 AOP 強大能力。