本人以前写程序都是瞎写,根本没有啥模式也没有啥方法。
近一年来学习了传智的一些课程,感觉马伦老师很有才,很强大,所以学来了一个模式(应当叫模式吧,该我也不知道叫啥哈)。
就是在DAL层封装一个DbSession来为BLL提供访问统一入口:
public partial interface IDbSession { ObjectContext DbContext { get; } //上下文对象 int ExcuteSql(string sql, params ObjectParameter[] parameters); //可以直接执行SQL语句 int SaveChanges(); //统一提交更改 }
这样来实现:
public partial class DbSession:IDbSession { public System.Data.Objects.ObjectContext DbContext { //这里用了一个工厂来取得DbContext,当时为了方便注入 get { return DbContextFactory.GetCurrentDbContext(); } } public int ExcuteSql(string sql, params System.Data.Objects.ObjectParameter[] parameters) { return DbContext.ExecuteFunction(sql, parameters); } public int SaveChanges() { return DbContext.SaveChanges(); } }
使用时DAL层全部返回true,是否有问题交给BLL来处理
public class BaseRepository<T> : IBaseRepository<T> where T : class,new() { private readonly ObjectContext _db = DbContextFactory.GetCurrentDbContext(); public bool AddEntities(ICollection<T> entities) { foreach (var entity in entities) { AddEntity(entity); } return true; } }
public class BaseService<T> : IBaseService<T> where T : class,new() { ..... public bool AddEntities(ICollection<T> entities) { CurrentRepository.AddEntities(entities); return TryToSave(); } private bool TryToSave() { try { CurrentDbSession.SaveChanges(); return true; } catch (Exception) { return false; } } }
这样,可以多次提交,只有在需要的时候,统一发送到数据库,可以算上Unit Of Work了。
但今天又发现一个好东西,可以再加一个事务进去,其实本身EF就会做事务处理了,但为了好扩展,自己加一个更好些,改造下接口:
记得添加System.Transactions引用并Using
public partial interface IDbSession { ObjectContext DbContext { get; } int ExcuteSql(string sql, params ObjectParameter[] parameters); //执行事务 TransactionScope CreateTransaction(IsolationLevel isolationLevel, int timeoutInSeconds); int SaveChanges(); }
实现它:
public partial class DbSession:IDbSession { public System.Data.Objects.ObjectContext DbContext { get { return DbContextFactory.GetCurrentDbContext(); } } public int ExcuteSql(string sql, params System.Data.Objects.ObjectParameter[] parameters) { return DbContext.ExecuteFunction(sql, parameters); } public int SaveChanges() { return DbContext.SaveChanges(); } //执行事务(级别,超时时间) public TransactionScope CreateTransaction(IsolationLevel isolationLevel, int timeoutInSeconds) { var option = TransactionScopeOption.Required; var options = new TransactionOptions { IsolationLevel = isolationLevel, Timeout = new TimeSpan(0, 0, timeoutInSeconds) }; return new TransactionScope(option, options); } }
这回可以这样调用了:
if (isAddNew) { using (var scope = dbSession.CreateTransaction(System.Transactions.IsolationLevel.ReadCommitted, 600)) { .... dbSession.SaveChanges(); ..... dbSession.SaveChanges(); scope.Complete(); } }
说的语无伦次,仅作笔记 ^^