Entity Framework 第八篇 结构优化

时间:2024-04-14 20:14:17

在之前的文章里,业务层直接调用一个包装的仓储类入口,忽略了DAL层,在业务层绕过DAL直接调用仓储类似乎也没什么大的问题,但是这样做有一个很大的弊端,就是无法做到DAL层的原子操作的复用。假如多个业务对象调用一个原子操作,每次都要通过仓储类重写,造成了代码的冗余,因此DAL层还是需要的,另外就是业务层可以采用UnitOfWork的思想去扩展,这样业务层可以共用一个数据上下文,从而保证了事务。

所以大致优化了架构。

仓储类改成泛型的结构

 public class BaseRepository<TEntity> : IRepository, IDisposable where TEntity : class
{
private MyDbContext dbContext; public MyDbContext DbContext
{
get
{
return dbContext;
}
set
{
dbContext = value;
}
} private bool disposed; public BaseRepository()
{
dbContext = DbContextFactory.GetCurrentDbContext<QDbContext>();
} public BaseRepository(DbSource db)
{
dbContext = DbContextFactory.GetCurrentDbContext(db);
} public BaseRepository(MyDbContext _dbContext)
{
this.dbContext = _dbContext; } #region 增删改查 /// <summary>
/// 新增实体对象
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public int Insert(TEntity model)
{
return this.ChangeObjectState(model, EntityState.Added);
} /// <summary>
/// 新增实体对象集合
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="models"></param>
/// <returns></returns>
public int Insert(IEnumerable<TEntity> models)
{
return this.ChangeObjectState(models, EntityState.Added);
} /// <summary>
/// 持久化对象更改
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public int Update(TEntity model)
{
return this.ChangeObjectState(model, EntityState.Modified);
} /// <summary>
/// 更新对象集合
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="models"></param>
/// <returns></returns>
public int Update(IEnumerable<TEntity> models)
{
return this.ChangeObjectState(models, EntityState.Modified);
} /// <summary>
/// 更新对象部分属性
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="predicate"></param>
/// <param name="updateAction"></param>
/// <returns></returns>
public int Update(Expression<Func<TEntity, bool>> predicate, Action<TEntity> updateAction)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
if (updateAction == null)
throw new ArgumentNullException("updateAction"); //dbContext.Configuration.AutoDetectChangesEnabled = true;
var _model = dbContext.Set<TEntity>().Where(predicate).ToList();
if (_model == null) return ;
_model.ForEach(p =>
{
updateAction(p);
dbContext.Entry<TEntity>(p).State = EntityState.Modified;
});
return Save();
} /// <summary>
/// 删除实体对象
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public int Delete(TEntity model)
{
return this.ChangeObjectState(model, EntityState.Deleted);
} /// <summary>
/// 删除实体对象集合
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="models"></param>
/// <returns></returns>
public int Delete(IEnumerable<TEntity> models)
{
return this.ChangeObjectState(models, EntityState.Deleted);
} /// <summary>
/// 删除实体对象集合(符合部分条件的)
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="predicate"></param>
/// <returns></returns>
public int Delete(Expression<Func<TEntity, bool>> predicate)
{
List<TEntity> _list = null; _list = dbContext.Set<TEntity>().Where(predicate).ToList();
foreach (var item in _list)
{
dbContext.Entry<TEntity>(item).State = EntityState.Deleted;
}
return Save();
} /// <summary>
/// 查询单个记录
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="predicate"></param>
/// <returns></returns>
public TEntity GetFirstOrDefault(Expression<Func<TEntity, bool>> predicate = null)
{
if (predicate == null)
{
return dbContext.Set<TEntity>().FirstOrDefault();
}
else
{
return dbContext.Set<TEntity>().Where(predicate).FirstOrDefault();
} } /// <summary>
/// 查询多笔记录
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="predicate"></param>
/// <returns></returns>
public IList<TEntity> GetList(Expression<Func<TEntity, bool>> predicate = null)
{ if (predicate == null)
{
return dbContext.Set<TEntity>().ToList();
}
else
{
return dbContext.Set<TEntity>().Where(predicate).ToList();
}
} public IList<TEntity> GetPaged(out int total, Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, int index = , int size = )
{
int skipCount = (index - ) * size;
var query = Get(filter, orderBy);
total = query.Count();
query = skipCount > ? query.Skip(skipCount).Take(size) : query.Take(size);
return query.ToList();
} public IList<TEntity> GetPaged(out int total, Expression<Func<TEntity, bool>> filter = null, string orderBy = null, int index = , int size = )
{
int skipCount = (index - ) * size;
var query = Get(filter, orderBy);
total = query.Count();
query = skipCount > ? query.Skip(skipCount).Take(size) : query.Take(size);
return query.ToList();
} /// <summary>
/// 用作条件查询使用
/// </summary>
/// <returns></returns>
public IQueryable<TEntity> GetQueryable()
{
IQueryable<TEntity> query = dbContext.Set<TEntity>();
return query;
} /// <summary>
/// 执行带参数的sql语句,返回List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="strsql"></param>
/// <param name="paras"></param>
/// <returns></returns>
public IEnumerable<TEntity> GetList(string strsql, SqlParameter[] paras)
{
return dbContext.Database.SqlQuery<TEntity>(strsql, paras).ToList();
} /// <summary>
/// 执行不带参数的sql语句,返回list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="strsql"></param>
/// <returns></returns>
public IEnumerable<TEntity> GetList(string strsql)
{
return dbContext.Database.SqlQuery<TEntity>(strsql).ToList();
} /// <summary>
/// 执行带参数的sql语句,返回一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="strsql"></param>
/// <param name="paras"></param>
/// <returns></returns>
public TEntity GetOneEntity(string strsql, SqlParameter[] paras)
{
return dbContext.Database.SqlQuery<TEntity>(strsql, paras).Cast<TEntity>().First();
} /// <summary>
/// 执行不带参数的sql语句,返回一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="strsql"></param>
/// <returns></returns>
public TEntity GetOneEntity(string strsql)
{
return dbContext.Database.SqlQuery<TEntity>(strsql).Cast<TEntity>().First();
} /// <summary>
/// 执行带参数的sql语句,返回List
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="strsql"></param>
/// <param name="paras"></param>
/// <returns></returns>
public IEnumerable<TView> GetList<TView>(string strsql, SqlParameter[] paras)
{
return dbContext.Database.SqlQuery<TView>(strsql, paras).ToList();
} /// <summary>
/// 执行不带参数的sql语句,返回list
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="strsql"></param>
/// <returns></returns>
public IEnumerable<TView> GetList<TView>(string strsql)
{
return dbContext.Database.SqlQuery<TView>(strsql).ToList();
} /// <summary>
/// 执行带参数的sql语句,返回一个对象
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="strsql"></param>
/// <param name="paras"></param>
/// <returns></returns>
public TView GetOneEntity<TView>(string strsql, SqlParameter[] paras)
{
return dbContext.Database.SqlQuery<TView>(strsql, paras).Cast<TView>().First();
} /// <summary>
/// 执行不带参数的sql语句,返回一个对象
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="strsql"></param>
/// <returns></returns>
public TView GetOneEntity<TView>(string strsql)
{
return dbContext.Database.SqlQuery<TView>(strsql).Cast<TView>().First();
} /// <summary>
/// 获取查询数量
/// </summary>
/// <param name="sql"></param>
/// <param name="paras"></param>
/// <returns></returns>
public int GetCount(string sql, SqlParameter[] paras)
{
return dbContext.Database.SqlQuery(typeof(int), sql, paras).Cast<int>().First();
} #endregion #region 私有方法 private int Save()
{
int effect = ;
if (!this.dbContext.IsTransaction)
{
effect = this.dbContext.SaveChanges();
}
return effect;
} /// <summary>
/// 变更上下文管理器(对象)
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="model"></param>
/// <param name="state"></param>
private int ChangeObjectState(TEntity model, EntityState state)
{
//_context.Configuration.ValidateOnSaveEnabled = false;
dbContext.Entry<TEntity>(model).State = state;
return Save(); } /// <summary>
/// 变更上下文管理器(对象集合)
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="model"></param>
/// <param name="state"></param>
private int ChangeObjectState(IEnumerable<TEntity> model, EntityState state)
{
if (model == null) return ; //_context.Configuration.AutoDetectChangesEnabled = false;
model.ToList().ForEach(p => dbContext.Entry<TEntity>(p).State = state);
return Save(); } private IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, string orderBy = null)
{
IQueryable<TEntity> query = dbContext.Set<TEntity>();
if (filter != null)
{
query = query.Where(filter);
}
if (!string.IsNullOrEmpty(orderBy))
{
query = query.OrderBy(orderBy);
}
return query.AsQueryable();
} private IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
{
IQueryable<TEntity> query = dbContext.Set<TEntity>();
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
orderBy(query).AsQueryable();
}
return query.AsQueryable();
} #endregion public int ExecuteSqlCommand(string sql, params SqlParameter[] paras)
{
if (this.dbContext.IsTransaction)
{
if (dbContext.Database.CurrentTransaction == null)
{
dbContext.Database.BeginTransaction();
}
}
return dbContext.Database.ExecuteSqlCommand(sql, paras);
} public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
} public virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.dbContext.Dispose();
}
}
this.disposed = true;
}
}

单元仓储

 public class UserRepository : BaseRepository<S_Users>
{
public UserRepository():base()
{
}
public UserRepository(DbSource dbSource)
: base(dbSource)
{
}

业务层 继承基类 保证可以共用一个数据上下文

 public class BaseBiz
{
protected Lazy<MyDbContext> _QDbContext = null; protected MyDbContext QDbContext
{
get
{
return _QDbContext.Value;
}
} protected Lazy<MyDbContext> _XFDbContext = null; protected MyDbContext XFDbContext
{
get
{
return _XFDbContext.Value;
}
}
public BaseBiz()
{
_QDbContext = new Lazy<MyDbContext>(() => DbContextFactory.GetCurrentDbContext<QDbContext>());
_XFDbContext = new Lazy<MyDbContext>(() => DbContextFactory.GetCurrentDbContext<XFDbContext>());
}
 public class DbContextFactory
{ public static T GetCurrentDbContext<T>() where T : DbContext, new()
{
string name = typeof(T).Name;
T dbContext = CallContext.GetData(name) as T;
if (dbContext == null)
{
dbContext = new T();
CallContext.SetData(name, dbContext);
}
return dbContext;
}

具体的业务类

 public class S_Users_Cls : BaseBiz
{
protected UserRepository UserRepository = null; public S_Users_Cls()
{
//UserRepository = RepositoryFactory.CreateRepository<UserRepository>(this.QDbContext);
UserRepository = new UserRepository();
}

将事务包装在DbContext里

  public class MyDbContext : DbContext, ITransaction
{ public MyDbContext(string connectionString)
: base(connectionString)
{
// 是否启动延迟加载
Configuration.LazyLoadingEnabled = false;
// 是否启动代理
Configuration.ProxyCreationEnabled = false;
Configuration.AutoDetectChangesEnabled = false;
Configuration.ValidateOnSaveEnabled = false; } public void BeginTransaction()
{
if (this.Database.CurrentTransaction == null)
{
this.Database.BeginTransaction();
}
this.IsTransaction = true;
} public int Commit()
{
int reault = this.SaveChanges();
this.IsTransaction = false;
DbContextTransaction transaction = this.Database.CurrentTransaction;
if (transaction != null)
{
transaction.Commit();
transaction.Dispose();
reault += ;
}
return reault;
} public void Rollback()
{
this.IsTransaction = false;
DbContextTransaction transaction = this.Database.CurrentTransaction;
if (transaction != null)
{
transaction.Rollback();
transaction.Dispose();
}
} private bool isTransaction = false; public bool IsTransaction
{
get { return isTransaction; }
set { this.isTransaction = value; }
} }
public class XFDbContext : MyDbContext
{
public XFDbContext()
: base("XFJD")
{
// 防止Entity变更导致数据库自动更新
Database.SetInitializer<XFDbContext>(null);
}

最后看看业务层如何事务调用

   public bool Add(S_Users model)
{ bool result = false;
this.DbContext.BeginTransaction();
try
{
this.UserRepository.Insert(model); int effect = this.DbContext.Commit();
result = effect > ;
}
catch (Exception ex)
{
this.DbContext.Rollback();
}
return result;
}

非事务性操作

  public bool EditPwd(S_Users model)
{
return UserRepository.EditPwd(model);
}

最后,结构优化用了时间比较短,不敢保证代码是否会存在一些问题。

可以根据是否需要单元仓储类来灵活搭配