EF之结构进一步优化
针对之前的使用,做了进一步优化
1.将DAL对象缓存起来
2.仓储类不依赖固定构造的DbContext,执行操作的时候,从线程中动态读取DbContext,这一步也是为了方便将DAL对象缓存起来,解决缓存对象的DbContext的释放问题,没有依赖固定构造的DbContext就不存在释放问题了。(如果依赖固定构造的DbContext,假如webapi情景,解决方案是在ActionFilter中调用API之前声明线程标识,读取缓存的时候根据该线程标识来决定是否替换以及释放DbContext,不难做到)
3.预留IDbContextFactory,方便动态创建自定义的DbContext
4.BIZ层声明静态方法,方便调用
5.更快捷的事务调用方式
6.IRepository中添加GetDbContext();供DAL对象重写实现,从而可以支持多库,默认的情况下由继承自IDbContextFactory来实现DbContext
所以接下来是一个最新的版本,同时修复了一些bug,譬如解决的事务嵌套的问题、ExecuteSqlCommand执行被上下文更新覆盖的问题、扩展了查询直接获取匿名对象,扩展了连接查询(不依赖linq)、扩展了查询单一或多个字段、修复了排序的bug问题、修复了附加实体出现主键重复的问题、将仓储类非泛型基类与泛型基类分离从而方便非泛型方法的直接调用。
目前接下来代码是一个最新的版本,不排除依旧有bug
/// <summary>
/// 数据仓储基类
/// </summary>
public class BaseRepository : IRepository, IDisposable
{ /// <summary>
/// 数据库上下文字段
/// </summary>
protected MyDbContext _dbContext; /// <summary>
/// 数据库上下文属性
/// </summary>
public MyDbContext DbContext
{
get
{
return _dbContext;
}
set
{
_dbContext = value;
}
} private bool disposed; /// <summary>
/// 默认构造函数
/// </summary>
public BaseRepository()
{
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="db"></param>
public BaseRepository(DbSource db)
{
//dbContext = DbContextFactory.GetCurrentDbContext(db);
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="_dbContext"></param>
public BaseRepository(MyDbContext _dbContext)
{
//this.dbContext = _dbContext; } #region 查 /// <summary>
/// 获取查询数量
/// </summary>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public int GetCount(string sqlText, params DbParameter[] parms)
{
//return dbContext.Database.SqlQuery(typeof(int), sql, paras).Cast<int>().First();
return GetScalar<int>(sqlText, parms);
} /// <summary>
/// 返回字段
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public T GetScalar<T>(string sqlText, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
string connectionString = dbContext.Database.Connection.ConnectionString;
using (var conn = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(sqlText);
command.Connection = conn;
//command.Parameters.Clear();
command.Parameters.AddRange(parms);
conn.Open();
object obj = null;
obj = command.ExecuteScalar();
command.Parameters.Clear();
command.Dispose();
conn.Close(); if (obj == null
|| obj == System.DBNull.Value)
return default(T); if (typeof(T) == typeof(int))
obj = Convert.ToInt32(obj); return (T)obj;
}
} /// <summary>
/// 执行不带参数的sql语句,返回一个对象
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="sqlText"></param>
/// <returns></returns>
public TView GetSingle<TView>(string sqlText)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TView>(sqlText).Cast<TView>().First();
}
catch
{
return default(TView);
}
} /// <summary>
/// 执行带参数的sql语句,返回一个对象
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public TView GetSingle<TView>(string sqlText, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TView>(sqlText, parms).Cast<TView>().First();
}
catch
{
return default(TView);
}
} /// <summary>
/// 执行不带参数的sql语句,返回list
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="sqlText"></param>
/// <returns></returns>
public List<TView> GetList<TView>(string sqlText)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TView>(sqlText).ToList();
}
catch
{
return null;
}
} /// <summary>
/// 执行带参数的sql语句,返回List
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public List<TView> GetList<TView>(string sqlText, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TView>(sqlText, parms).ToList();
}
catch (Exception e)
{
return null;
}
} /// <summary>
/// 多表连查分页查询
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="sqlText"></param>
/// <param name="orderText"></param>
/// <param name="page"></param>
/// <param name="parms"></param>
/// <returns></returns>
public PageSource<TView> GetPaged<TView>(string sqlText, string orderText, PageFilter page, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
PageSource<TView> pageSource = new PageSource<TView>();
int pageIndexPara = page.PageIndex;
// 计算分页大小,和分页数
string sqlTextCount = String.Format("SELECT COUNT(1) AS CT FROM ({0}) t", sqlText);
string cst = dbContext.Database.Connection.ConnectionString;
pageSource.TotalCount = GetScalar<int>(sqlTextCount, parms);
int pageCount = ;
if (page.PageSize <= )
{
page.PageSize = ;
}
if (pageSource.TotalCount % page.PageSize == )
{
pageCount = pageSource.TotalCount / page.PageSize;
}
else
{
pageCount = pageSource.TotalCount / page.PageSize + ;
} // 得到当前页面索引
if (page.PageIndex < )
page.PageIndex = ;
int currentPageIndex = page.PageIndex;
if (currentPageIndex > pageCount)
{
currentPageIndex = pageCount;
page.PageIndex = currentPageIndex;
}
pageSource.PageCount = pageCount;
pageSource.PageIndex = page.PageIndex;
pageSource.PageSize = page.PageSize;
// 得到用于分页的SQL语句
int startIndex = (currentPageIndex - ) * page.PageSize;
int endIndex = currentPageIndex * page.PageSize; if (pageIndexPara <= || pageIndexPara > pageSource.PageCount)
{
pageSource.PageIndex = pageIndexPara;
pageSource.DataSource = null;
return pageSource;
} string rowNumber = String.Format(" (ROW_NUMBER() OVER(ORDER BY {0})) AS RowNumber, ", orderText);
sqlText = sqlText.Trim().Insert(, rowNumber);
string sqlTextRecord = String.Format("SELECT * FROM ({0}) TT1 WHERE RowNumber>{1} and RowNumber<={2}",
sqlText,
startIndex,
endIndex
); pageSource.DataSource = GetList<TView>(sqlTextRecord, parms); return pageSource; } #endregion /// <summary>
/// 执行SQL命令
/// </summary>
/// <param name="sqlText"></param>
/// <returns></returns>
public int ExecuteSqlCommand(string sqlText)
{
MyDbContext dbContext = this.GetDbContext();
if (dbContext.IsTransaction)
{
if (dbContext.Database.CurrentTransaction == null)
{
dbContext.Database.BeginTransaction();
}
} int effect= dbContext.Database.ExecuteSqlCommand(sqlText);
return effect;
} /// <summary>
/// 执行带参数SQL命令
/// </summary>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public int ExecuteSqlCommand(string sqlText, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
if (dbContext.IsTransaction)
{
if (dbContext.Database.CurrentTransaction == null)
{
dbContext.Database.BeginTransaction();
}
} return dbContext.Database.ExecuteSqlCommand(sqlText, parms);
} ///// <summary>
///// 通过Out参数返回要获取的值
///// </summary>
///// <param name="storedProcName"></param>
///// <param name="Parameters"></param>
///// <returns></returns>
//public object[] ExecuteProc(string storedProcName, params SqlParameter[] Parameters)
//{
// using (var conn = new SqlConnection(dbContext.Database.Connection.ConnectionString))
// {
// List<SqlParameter> outParms = Parameters.Where(p => p.Direction == System.Data.ParameterDirection.Output).ToList();
// SqlCommand command = new SqlCommand(storedProcName);
// command.Connection = conn;
// command.CommandType = CommandType.StoredProcedure; // command.Parameters.AddRange(Parameters);
// conn.Open();
// command.ExecuteNonQuery(); // command.Parameters.Clear();
// command.Dispose();
// conn.Close();
// object[] values = outParms.Select(r => r.Value).ToArray();
// return values;
// }
//} /// <summary>
/// 通过Out参数返回要获取的值
/// </summary>
/// <param name="procName"></param>
/// <param name="parms"></param>
/// <returns></returns>
public object[] ExecuteProc(string procName, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
List<DbParameter> outParms = parms.Where(p => p.Direction == System.Data.ParameterDirection.Output || p.Direction == System.Data.ParameterDirection.ReturnValue).ToList();
DbParameter returnParm = parms.FirstOrDefault(p => p.Direction == System.Data.ParameterDirection.ReturnValue);
StringBuilder procBuilder = new StringBuilder(procName);
foreach (DbParameter parm in parms)
{
if (parm.Direction == System.Data.ParameterDirection.Input)
{
procBuilder.AppendFormat(" {0}{1}", parm.ParameterName, ",");
}
else if (parm.Direction == System.Data.ParameterDirection.Output)
{
procBuilder.AppendFormat(" {0} {1}{2}", parm.ParameterName, "OUT", ",");
}
}
string proc = procBuilder.ToString().TrimEnd(',');
if (returnParm != null)
{
proc = "EXEC " + returnParm.ParameterName + "=" + proc;
}
else
{
proc = "EXEC " + proc;
}
if (dbContext.IsTransaction)
{
if (dbContext.Database.CurrentTransaction == null)
{
dbContext.Database.BeginTransaction();
}
}
var results = dbContext.Database.ExecuteSqlCommand(proc, parms);
object[] values = outParms.Select(r => r.Value).ToArray();
return values; } /// <summary>
/// 返回结果集的存储过程
/// </summary>
/// <typeparam name="TView"></typeparam>
/// <param name="procName"></param>
/// <param name="parms"></param>
/// <returns></returns>
public List<TView> ExecuteProc<TView>(string procName, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
StringBuilder procBuilder = new StringBuilder(procName);
foreach (DbParameter parm in parms)
{
if (parm.Direction == System.Data.ParameterDirection.Input)
{
procBuilder.AppendFormat(" {0}{1}", parm.ParameterName, ",");
}
else if (parm.Direction == System.Data.ParameterDirection.Output)
{
procBuilder.AppendFormat(" {0} {1}{2}", parm.ParameterName, "OUT", ",");
}
}
string proc = procBuilder.ToString().TrimEnd(',');
return dbContext.Database.SqlQuery<TView>(proc, parms).ToList();
} /// <summary>
/// 创建参数
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public SqlParameter GetParameter(string name, object value)
{
return new SqlParameter("@" + name, value);
} /// <summary>
/// 创建参数
/// </summary>
/// <param name="name"></param>
/// <param name="type"></param>
/// <param name="size"></param>
/// <returns></returns>
public SqlParameter GetParameterOut(string name, DbType type, int size)
{
return new SqlParameter
{
ParameterName = "@" + name,
Direction = ParameterDirection.Output,
DbType = type,
Size = size };
} /// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// Dispose
/// </summary>
/// <param name="disposing"></param>
public virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this._dbContext.Dispose();
}
}
this.disposed = true;
} /// <summary>
/// 默认支持单库
/// 如果多库的操作请在DAL子类中实现此方法
/// </summary>
/// <returns></returns>
public virtual MyDbContext GetDbContext()
{
return Transaction.DbContextFactory.GetDbContext();
} }
/// <summary>
/// 数据仓储泛型基类
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class BaseRepository<TEntity> : BaseRepository where TEntity : class
{ #region 增删改查 /// <summary>
/// 新增实体对象
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public TResult Insert(TEntity entity)
{
return this.ChangeObjectState(entity, EntityState.Added);
} /// <summary>
/// 新增实体对象集合
/// </summary>
/// <param name="entities"></param>
/// <returns></returns>
public TResult Insert(IEnumerable<TEntity> entities)
{
return this.ChangeObjectState(entities, EntityState.Added);
} /// <summary>
/// 实体对象更改
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public TResult Update(TEntity entity)
{
return this.ChangeObjectState(entity, EntityState.Modified);
} /// <summary>
/// 更新s实体对象集合
/// </summary>
/// <param name="entities"></param>
/// <returns></returns>
public TResult Update(IEnumerable<TEntity> entities)
{
return this.ChangeObjectState(entities, EntityState.Modified);
} /// <summary>
/// 更新实体对象部分属性
/// </summary>
/// <param name="predicate"></param>
/// <param name="updateAction"></param>
/// <returns></returns>
public TResult Update(Expression<Func<TEntity, bool>> predicate, Action<TEntity> updateAction)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
if (updateAction == null)
throw new ArgumentNullException("updateAction");
MyDbContext dbContext = this.GetDbContext();
//dbContext.Configuration.AutoDetectChangesEnabled = true;
var _model = dbContext.Set<TEntity>().AsNoTracking().Where(predicate).ToList();
if (_model == null) return new TResult(false, "参数为NULL");
_model.ForEach(p =>
{
updateAction(p);
DetachExistsEntity(p);
dbContext.Entry<TEntity>(p).State = EntityState.Modified;
});
return Save(EntityState.Modified);
} /// <summary>
/// 删除实体对象
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public TResult Delete(TEntity entity)
{
return this.ChangeObjectState(entity, EntityState.Deleted);
} /// <summary>
/// 删除实体对象集合
/// </summary>
/// <param name="entities"></param>
/// <returns></returns>
public TResult Delete(IEnumerable<TEntity> entities)
{
return this.ChangeObjectState(entities, EntityState.Deleted);
} /// <summary>
/// 根据条件删除实体对象集合
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public TResult Delete(Expression<Func<TEntity, bool>> predicate)
{
MyDbContext dbContext = this.GetDbContext();
List<TEntity> _list = null; _list = dbContext.Set<TEntity>().AsNoTracking().Where(predicate).ToList();
foreach (var item in _list)
{
dbContext.Entry<TEntity>(item).State = EntityState.Deleted;
}
return Save(EntityState.Deleted);
} /// <summary>
/// 用作单表条件查询使用
/// </summary>
/// <returns></returns>
public IQueryable<TEntity> GetQueryable()
{
MyDbContext dbContext = this.GetDbContext();
DbSet<TEntity> query = dbContext.Set<TEntity>();
return query;
} /// <summary>
/// 直接获取特定一个或者多个字段的值
/// 多个字段需要声明Model或者采用dynamic
/// var dmic= GetScalar《dynamic》(m=>m.ID== "1",m=>new { m.ID,m.Name });var v = dmic.Name;
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="predicate"></param>
/// <param name="select"></param>
/// <returns></returns>
public T GetScalar<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> select)
{
MyDbContext dbContext = this.GetDbContext();
if (predicate == null)
{
return dbContext.Set<TEntity>().AsNoTracking().Select(select).FirstOrDefault();
}
else
{
return dbContext.Set<TEntity>().AsNoTracking().Where(predicate).Select(select).FirstOrDefault();
} } /// <summary>
/// 获取单个数据
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public TEntity GetSingle(Expression<Func<TEntity, bool>> predicate = null)
{
MyDbContext dbContext = this.GetDbContext();
if (predicate == null)
{
return dbContext.Set<TEntity>().AsNoTracking().FirstOrDefault();
}
else
{
return dbContext.Set<TEntity>().AsNoTracking().Where(predicate).FirstOrDefault();
} } /// <summary>
/// 执行带参数的sql语句,获取单一数据
/// </summary>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public TEntity GetSingle(string sqlText, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TEntity>(sqlText, parms).Cast<TEntity>().First();
}
catch
{
return null;
}
} /// <summary>
/// 执行不带参数的sql语句,获取单一数据
/// </summary>
/// <param name="sqlText"></param>
/// <returns></returns>
public TEntity GetSingle(string sqlText)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TEntity>(sqlText).Cast<TEntity>().First();
}
catch
{
return null;
}
} /// <summary>
/// 获取多条记录
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public List<TEntity> GetList(Expression<Func<TEntity, bool>> predicate = null)
{
MyDbContext dbContext = this.GetDbContext();
if (predicate == null)
{
return dbContext.Set<TEntity>().AsNoTracking().ToList();
}
else
{
return dbContext.Set<TEntity>().AsNoTracking().Where(predicate).ToList();
}
} /// <summary>
/// 获取多条记录,根据特定字段返回自定义model或者匿名类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="predicate"></param>
/// <param name="select"></param>
/// <returns></returns>
public List<T> GetList<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> select)
{
MyDbContext dbContext = this.GetDbContext();
if (predicate == null)
{
return dbContext.Set<TEntity>().AsNoTracking().Select(select).ToList();
}
else
{
return dbContext.Set<TEntity>().AsNoTracking().Where(predicate).Select(select).ToList();
}
} /// <summary>
/// 带有lambda表达式排序的获取
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// <returns></returns>
public List<TEntity> GetList(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
{
return Get(predicate, orderBy).ToList();
} /// <summary>
/// 带有文本排序的获取
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// <returns></returns>
public List<TEntity> GetList(Expression<Func<TEntity, bool>> predicate, string orderBy)
{
return Get(predicate, orderBy).ToList();
} /// <summary>
/// 执行不带参数的sql语句,获取多条记录
/// </summary>
/// <param name="sqlText"></param>
/// <returns></returns>
public List<TEntity> GetList(string sqlText)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TEntity>(sqlText).ToList();
}
catch
{
return null;
}
} /// <summary>
/// 执行带参数的sql语句,获取多条记录
/// </summary>
/// <param name="sqlText"></param>
/// <param name="parms"></param>
/// <returns></returns>
public List<TEntity> GetList(string sqlText, params DbParameter[] parms)
{
MyDbContext dbContext = this.GetDbContext();
try
{
return dbContext.Database.SqlQuery<TEntity>(sqlText, parms).ToList();
}
catch
{
return null;
}
} /// <summary>
/// 分页
/// </summary>
/// <param name="total"></param>
/// <param name="filter"></param>
/// <param name="orderBy"></param>
/// <param name="index"></param>
/// <param name="size"></param>
/// <returns></returns>
public List<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();
} /// <summary>
/// 分页
/// </summary>
/// <param name="total"></param>
/// <param name="filter"></param>
/// <param name="orderBy"></param>
/// <param name="index"></param>
/// <param name="size"></param>
/// <returns></returns>
public List<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>
/// <param name="query"></param>
/// <param name="page"></param>
/// <returns></returns>
public PageSource<TEntity> GetPaged(IQueryable<TEntity> query, PageFilter page)
{
PageSource<TEntity> pageSource = new PageSource<TEntity>();
int pageIndexPara = page.PageIndex;
int total = query.Count();
pageSource.TotalCount = total;
int pageCount = ;
if (page.PageSize <= )
{
page.PageSize = ;
}
if (pageSource.TotalCount % page.PageSize == )
{
pageCount = pageSource.TotalCount / page.PageSize;
}
else
{
pageCount = pageSource.TotalCount / page.PageSize + ;
}
// 得到当前页面索引
if (page.PageIndex < )
page.PageIndex = ; if (page.PageIndex > pageCount)
{
page.PageIndex = pageCount;
}
pageSource.PageCount = pageCount;
pageSource.PageIndex = page.PageIndex;
pageSource.PageSize = page.PageSize;
int skipCount = (page.PageIndex - ) * page.PageSize; if (pageIndexPara <= || pageIndexPara > pageSource.PageCount)
{
pageSource.PageIndex = pageIndexPara;
pageSource.DataSource = null;
return pageSource;
} query = skipCount > ? query.Skip(skipCount).Take(page.PageSize) : query.Take(page.PageSize);
pageSource.DataSource = query.ToList();
return pageSource;
} /// <summary>
/// 内连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <returns></returns>
public List<TModel> GetInnerJoin<TInner, TModel>(
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, TInner, TModel>> resultSelector) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().Join(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector);
return query.ToList();
} /// <summary>
/// 内连接查询,查询条件在主表中,支持返回匿名类
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="predicate">主表查询条件</param>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <returns></returns>
public List<TModel> GetInnerJoin<TInner, TModel>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, TInner, TModel>> resultSelector) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().Where(predicate).Join(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector);
return query.ToList();
} /// <summary>
/// 内连接查询,查询条件在主从表中,不支持返回匿名类
/// </summary>
/// <typeparam name="TInner">关联表</typeparam>
/// <typeparam name="TModel">返回类型</typeparam>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <param name="predicate">主从表查询条件</param>
/// <returns></returns>
public List<TModel> GetInnerJoin<TInner, TModel>(
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, TInner, TModel>> resultSelector,
Expression<Func<TModel, bool>> predicate) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().Join(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector).Where(predicate);
return query.ToList();
} /// <summary>
/// 左连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <returns></returns>
public List<TModel> GetLeftJoin<TInner, TModel>(
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, TInner, TModel>> resultSelector) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().LeftOuterJoin(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector);
return query.ToList();
} /// <summary>
/// 左连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="predicate"></param>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <returns></returns>
public List<TModel> GetLeftJoin<TInner, TModel>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, TInner, TModel>> resultSelector) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().Where(predicate).LeftOuterJoin(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector);
return query.ToList();
} /// <summary>
/// 左连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <param name="predicate"></param>
/// <returns></returns>
public List<TModel> GetLeftJoin<TInner, TModel>(
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, TInner, TModel>> resultSelector,
Expression<Func<TModel, bool>> predicate) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().LeftOuterJoin(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector).Where(predicate);
return query.ToList();
} /// <summary>
/// 一对多连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <returns></returns>
public List<TModel> GetGroupJoin<TInner, TModel>(
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, IEnumerable<TInner>, TModel>> resultSelector) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().GroupJoin(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector);
return query.ToList();
} /// <summary>
/// 一对多连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="predicate"></param>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <returns></returns>
public List<TModel> GetGroupJoin<TInner, TModel>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, IEnumerable<TInner>, TModel>> resultSelector) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().Where(predicate).GroupJoin(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector);
return query.ToList();
} /// <summary>
/// 一对多连接查询
/// </summary>
/// <typeparam name="TInner"></typeparam>
/// <typeparam name="TModel"></typeparam>
/// <param name="outerKeySelector"></param>
/// <param name="innerKeySelector"></param>
/// <param name="resultSelector"></param>
/// <param name="predicate"></param>
/// <returns></returns>
public List<TModel> GetGroupJoin<TInner, TModel>(
Expression<Func<TEntity, dynamic>> outerKeySelector,
Expression<Func<TInner, dynamic>> innerKeySelector,
Expression<Func<TEntity, IEnumerable<TInner>, TModel>> resultSelector,
Expression<Func<TModel, bool>> predicate) where TInner : class
{
MyDbContext dbContext = this.GetDbContext();
var query = dbContext.Set<TEntity>().GroupJoin(dbContext.Set<TInner>(), outerKeySelector, innerKeySelector, resultSelector).Where(predicate);
return query.ToList();
} #endregion #region 私有方法 /// <summary>
/// 分离依存的实体对象
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
private Boolean DetachExistsEntity(TEntity entity)
{
var objContext = ((IObjectContextAdapter)this.GetDbContext()).ObjectContext;
var objSet = objContext.CreateObjectSet<TEntity>();
var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity); Object foundEntity;
var exists = objContext.TryGetObjectByKey(entityKey, out foundEntity); if (exists)
{
objContext.Detach(foundEntity);
} return (exists);
} private TResult Save()
{
MyDbContext dbContext = this.GetDbContext();
TResult result = new TResult();
int effect = ; try
{
effect = dbContext.SaveChanges();
if (effect > )
{
result.Flag = true;
}
else
{
result.Flag = false;
result.Message = "无受影响行";
result.Code = "None Effect";
}
}
catch (Exception ex)
{
result.Flag = false;
result.Message = ex.Message;
result.Code = "Exception";
if (dbContext.IsTransaction)
{
throw ex;
}
} return result;
} private TResult Save(EntityState state)
{
MyDbContext dbContext = this.GetDbContext();
TResult result = new TResult();
int effect = ; try
{
effect = dbContext.SaveChanges();
if (effect > )
{
result.Flag = true;
switch (state)
{
case EntityState.Added:
result.Message = "添加成功";
result.Code = "Insert Success";
break;
case EntityState.Modified:
result.Message = "更新成功";
result.Code = "Update Success";
break;
case EntityState.Deleted:
result.Message = "删除成功";
result.Code = "Delete Success";
break;
default:
break;
}
}
else
{
result.Flag = false;
result.Message = "无受影响行";
result.Code = "None Effect";
}
}
catch (Exception ex)
{
result.Flag = false;
result.Message = ex.Message;
result.Code = "Exception";
if (dbContext.IsTransaction)
{
throw ex;
}
} return result;
} /// <summary>
/// 变更上下文管理器(对象)
/// </summary>
/// <param name="entity"></param>
/// <param name="state"></param>
/// <returns></returns>
private TResult ChangeObjectState(TEntity entity, EntityState state)
{
MyDbContext dbContext = this.GetDbContext();
if (entity == null)
{
return new TResult(false, "参数为NULL");
}
//_context.Configuration.ValidateOnSaveEnabled = false;
DetachExistsEntity(entity);
dbContext.Entry<TEntity>(entity).State = state;
return Save(state); } /// <summary>
/// 变更上下文管理器(对象集合)
/// </summary>
/// <param name="entities"></param>
/// <param name="state"></param>
/// <returns></returns>
private TResult ChangeObjectState(IEnumerable<TEntity> entities, EntityState state)
{
if (entities == null) return new TResult(false, "参数为NULL");
MyDbContext dbContext = this.GetDbContext();
//_context.Configuration.AutoDetectChangesEnabled = false;
entities.ToList().ForEach(p =>
{
DetachExistsEntity(p);
dbContext.Entry<TEntity>(p).State = state;
});
return Save(state); } private IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, string orderBy = null)
{
MyDbContext dbContext = this.GetDbContext();
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)
{
MyDbContext dbContext = this.GetDbContext();
IQueryable<TEntity> query = dbContext.Set<TEntity>();
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
orderBy(query).AsQueryable();
}
return query.AsQueryable();
} #endregion }
/// <summary>
/// DAL简单工厂
/// </summary>
public class DALFactory
{ private static object _lock = new object(); private static DALCache _DALCaches = new DALCache(); /// <summary>
/// DAL缓存容器
/// </summary>
public static DALCache DALCaches
{
get
{
if (_DALCaches == null)
{
lock (_lock)
{
if (_DALCaches == null)
{
_DALCaches = new DALCache();
}
}
}
return _DALCaches;
}
} /// <summary>
/// 创建DAL简单工厂
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T CreateDAL<T>() where T : class, IRepository, new()
{
Type key = typeof(T);
if (DALCaches.Get(key.FullName) != null)
{
return (T)DALCaches.Get(key.FullName);
}
T dao = new T();
DALCaches.Insert(key.FullName, dao);
return dao;
} /// <summary>
/// 创建DAL简单工厂
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="myDbContext"></param>
/// <returns></returns>
public static T CreateDAL<T>(MyDbContext myDbContext) where T : class, IRepository, new()
{
Type key = typeof(T);
T dao = default(T);
if (DALCaches.Get(key.FullName) != null)
{
dao = (T)DALCaches.Get(key.FullName);
if (dao.DbContext != null)
{
dao.DbContext.Dispose();
}
dao.DbContext = myDbContext;
}
dao = new T();
dao.DbContext = myDbContext;
DALCaches.Insert(key.FullName, dao);
return dao;
} }
/// <summary>
/// 创建DbContext简单工厂
/// </summary>
public abstract class DbContextFactory
{
/// <summary>
/// 创建DbContext简单工厂
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
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;
} }
/// <summary>
/// DbContext工厂方法接口,由DAL层实现继承并在配置文件里配置
/// </summary>
public interface IDbContextFactory
{
/// <summary>
/// 获取数据上下文
/// </summary>
/// <returns></returns>
MyDbContext GetDbContext();
}
/// <summary>
/// 数据仓储接口
/// </summary>
public interface IRepository
{
/// <summary>
/// 数据上下文
/// </summary>
MyDbContext DbContext { get; set; } /// <summary>
/// 从线程中获取DbContext
/// </summary>
/// <returns></returns>
MyDbContext GetDbContext();
}
/// <summary>
/// 事务接口
/// </summary>
public interface ITransaction
{
/// <summary>
/// 事务标识
/// </summary>
bool IsTransaction { get; } /// <summary>
/// 开启事务
/// </summary>
void BeginTransaction(); /// <summary>
/// 提交事务
/// </summary>
/// <returns></returns>
int Commit(); /// <summary>
/// 回滚事务
/// </summary>
void Rollback();
}
/// <summary>
/// 数据上下文
/// </summary>
public class MyDbContext : DbContext, ITransaction
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="connectionString"></param>
public MyDbContext(string connectionString)
: base(connectionString)
{
// 是否启动延迟加载
Configuration.LazyLoadingEnabled = false;
// 是否启动代理
Configuration.ProxyCreationEnabled = false;
Configuration.AutoDetectChangesEnabled = false;
Configuration.ValidateOnSaveEnabled = false; } /// <summary>
///开启一个事务
/// </summary>
public void BeginTransaction()
{
if (this.Database.CurrentTransaction == null)
{
this.Database.BeginTransaction();
}
this.BeginCounter++;
this.IsTransaction = true; } /// <summary>
/// 提交一个事务
/// </summary>
/// <returns></returns>
public int Commit()
{
this.BeginCounter--;
int result = ;
if (this.BeginCounter == )
{
result += this.SaveChanges();
this.IsTransaction = false;
DbContextTransaction transaction = this.Database.CurrentTransaction;
if (transaction != null)
{
transaction.Commit();
transaction.Dispose();
result += ;
} }
return result;
} /// <summary>
/// 回滚一个事务
/// </summary>
public void Rollback()
{
this.BeginCounter--;
if (this.BeginCounter == )
{
this.IsTransaction = false;
DbContextTransaction transaction = this.Database.CurrentTransaction;
if (transaction != null)
{
transaction.Rollback();
transaction.Dispose();
}
}
else
{
//this.BeginCounter = 1;
throw new Exception("嵌套内部事务异常");
}
} private bool isTransaction = false; /// <summary>
/// 事务性操作
/// </summary>
public bool IsTransaction
{
get { return isTransaction; }
set { this.isTransaction = value; }
} private int beginCounter = ; /// <summary>
/// 事务计数器
/// </summary>
public int BeginCounter
{
get { return beginCounter; }
set { this.beginCounter = value; }
}
}
/// <summary>
/// 事务辅助类
/// </summary>
public class Transaction
{
private static object _lock = new object(); private static IDbContextFactory dbContextFactory = null; /// <summary>
/// DbContextFactory
/// </summary>
public static IDbContextFactory DbContextFactory
{
get
{
if (dbContextFactory == null)
{
lock (_lock)
{
if (dbContextFactory == null)
{
dbContextFactory = LoadDbContextFactory();
}
}
}
return dbContextFactory;
}
} /// <summary>
/// 开始事务
/// </summary>
public static void BeginTransaction()
{
MyDbContext dbContext = DbContextFactory.GetDbContext();
dbContext.BeginTransaction();
} /// <summary>
/// 提交一个事务
/// </summary>
/// <returns></returns>
public static int Commit()
{
MyDbContext dbContext = DbContextFactory.GetDbContext();
return dbContext.Commit();
} /// <summary>
/// 回滚一个事务
/// </summary>
public static void Rollback()
{
MyDbContext dbContext = DbContextFactory.GetDbContext();
dbContext.Rollback();
} private static IDbContextFactory LoadDbContextFactory()
{
string factoryPath = ConfigurationManager.AppSettings["IDbcontextFactory"].ToString();
string[] arr = factoryPath.Split(',');
string assemblyName = arr[];
string className = arr[];
return (IDbContextFactory)Assembly.Load(assemblyName).CreateInstance(className);
} }
接下来看看DAL层
public class TestDAL: BaseRepository<Test>
{
} public class CustomerDbContext:MyDbContext
{
public CustomerDbContext()
: base("XFW")
{
// 防止Entity变更导致数据库自动更新
Database.SetInitializer<CustomerDbContext>(null);
} public CustomerDbContext(string connectionString)
: base(connectionString)
{
// 防止Entity变更导致数据库自动更新
Database.SetInitializer<CustomerDbContext>(null);
} public DbSet<Test> Test { get; set; }
} public class CustomerDbContextFactory : IDbContextFactory
{
/// <summary>
/// 创建自定义DbContext
/// </summary>
/// <returns></returns>
public MyDbContext GetDbContext()
{
return DbContextFactory.GetCurrentDbContext<CustomerDbContext>();
}
}
BIZ层
public class TestBiz
{
public static TResult AddTest()
{
TestDAL testdal = DALFactory.CreateDAL<TestDAL>();
TResult t;
Transaction.BeginTransaction();
try
{
testdal.Insert(new Test { ID= });
testdal.ExecuteSqlCommand("update test set name='111' where id=1");
//Test test = testdal.GetSingle(m => m.ID == 1);
//test.Name1 = "asdafaff";
testdal.Update(m => m.ID == , m => { m.Name1 = "asdafaff"; });
Transaction.Commit();
}
catch(Exception ex)
{
Transaction.Rollback();
}
finally
{
t= new TResult();
}
return t;
} }
EF之结构进一步优化的更多相关文章
- 进一步优化SPA的首屏打开速度(模块化与懒载入) by 嗡
前言 单页应用的优点在于一次载入全部页面资源,利用本地计算能力渲染页面.提高页面切换速度与用户体验.但缺点在于全部页面资源将被一次性下载完,此时封装出来的静态资源包体积较大,使得第一次打开SPA页面时 ...
- MySQL 性能优化--优化数据库结构之优化数据类型
MySQL性能优化--优化数据库结构之优化数据类型 By:授客 QQ:1033553122 优化数字数据(Numeric Data) l 对于唯一ID或其它可用字符串或数字表示的值,选择 ...
- MySQL 性能优化--优化数据库结构之优化数据大小
MySQL性能优化--优化数据库结构之优化数据大小 By:授客 QQ:1033553122 尽量减少表占用的磁盘空间.通常,执行查询期间处理表数据时,小表占用更少的内存. 表列 l 尽可能使 ...
- 采用DTO和DAO对JDBC程序进行进一步优化
采用DTO和DAO对JDBC程序进行进一步优化 DTO:数据传输对象,主要用于远程调用等需要远程调用对象的地方DAO:数据访问对象,主要实现封装数据库的访问,通过它可以把数据库中的表转换成DTO类 引 ...
- html5--switch选择结构的优化
html5--switch选择结构的优化 问题: 使用循环语句判断月份是31天还是30天 两点提示: 使用switch多条件判断语句 合理的省略break优化代码 <!DOCTYPE html& ...
- SSE图像算法优化系列二十一:基于DCT变换图像去噪算法的进一步优化(100W像素30ms)。
在优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码) 一文中,我们曾经优化过基于DCT变换的图像去噪算法,在那文所提供的Demo中,处理一副1000*1000左右的灰度噪音图像耗时 ...
- DOM结构及优化
1.DOM树中三种常见的DOM节点: 1>元素节点:上图中<a>,<h1>等都是元素节点,即标签 2>文本节点:向用户展示的内容,如...中的"文档标题& ...
- EF查询之性能优化技巧
上一篇:EF使用CodeFirst方式生成数据库&技巧经验 前言 EF相信大部分同学都已经经常使用了,可是你的查询高效吗? 今天我就以个人使用经验来讲讲在使用EF做查询的时候大家都容易忽略的性 ...
- JavaScript中国象棋程序(8) - 进一步优化
在这最后一节,我们的主要工作是使用开局库.对根节点的搜索分离出来.以及引入PVS(Principal Variation Search,)主要变例搜索. 8.1.开局库 这一节我们引入book.js文 ...
随机推荐
- CXF调用webservice超时设置
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(Service1Soap.cl ...
- 升级到macOS 10.12 mysqlb报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
系统升级到macOS 10.12后启动mysql后,在终端输入mysql 报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' ...
- SQL Server 常用日期查询语句
--本月月初select dateadd(mm,datediff(mm,0,getdate()),0) --本月月末select DATEADD(DD,-1,DATEADD(MONTH,1+DAT ...
- 各种同步方法性能比较(synchronized,ReentrantLock,Atomic)
synchronized: 在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的.原因在于,编译程序通常会尽可能的进行优化synchronize,另外可读性非常好,不 ...
- 系统右键自定义功能-右键备份【C#】
平时在某些公司发布网站的时候,都是手动备份文件,以免发布错误,做回滚使用.频繁的发布,在做备份的时候也会稍稍浪费点时间.当然在一些大的公司都会有一些自动发布系统,就不会出现这种问题了,对这种问题,我做 ...
- java实现删除文件以及文件夹
首先,需要明确的是File类中的delete()方法适用于删除空目录,或者单个文件. 然后,对于二级目录以上的文件夹的删除,需要分两步进行删除. 1.删除最底层目录下面的文件,或者空目录 当有多个文件 ...
- Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...
- iOS,多媒体,地图相关
1.本地音频播放 2.本地视频播放 3.使用UIImagePickerController摄像头拍照,录像,照片库浏览 4.使用AVFunction,AVCaptureVideoDataOutput实 ...
- 使用MapReduce实现join操作
在关系型数据库中,要实现join操作是非常方便的,通过sql定义的join原语就可以实现.在hdfs存储的海量数据中,要实现join操作,可以通过HiveQL很方便地实现.不过HiveQL也是转化成 ...
- 数据结构看书笔记(二)--算法(Algorithm)简介
算法:是解决问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作. 算法的特性:算法具有五个特性:输入.输出.有穷性.确定性.可行性 输入输出:算法具有零个或多个输入:至 ...