1.1.1 EF thread unique
EF instances are used in the data layer and data session layer, so only one EF instance (the only object in the thread) can be created in a request, and it is encapsulated as a factory class
1.1.2 to prevent cross reference and circular reference, this factory class should be written in the data layer DAL
New class DBContextFactory of DAL
/// <summary> /// Responsible for creation EF The data operation context instance must be unique within the thread /// </summary> public class DBContextFactory { public static DbContext CreateDbContext() { //from CallContext Read from dbContext DbContext dbContext = (DbContext)CallContext.GetData("dbContext"); //If CallContext Medium dbContext yes null Yes, it's the first time if (dbContext==null) { dbContext = new OAEntities();//Create a new EF Context instance CallContext.SetData("dbContext", dbContext);//hold dbContext Deposit in CallContext For next use } return dbContext; } }
1.2.1 change the EF data operation context instance in BaseDal and DBSession to thread unique
Both writing methods are available
public class BaseDal<T> where T : class, new() { //OAEntities Db = new OAEntities(); DbContext Db = DBContextFactory.CreateDbContext(); /// <summary> /// newly added /// </summary> /// <param name="entity"></param> /// <returns></returns> public T AddEntity(T entity) { Db.Set<T>().Add(entity);//DbSet<T> //Db.SaveChanges(); return entity; } /// <summary> /// delete /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool DeleteEntity(T entity) { //Append to ef On, mark the deletion mark, and then save Db.Entry<T>(entity).State = System.Data.Entity.EntityState.Deleted; //return Db.SaveChanges() > 0; return true; } /// <summary> /// to update /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool EditEntity(T entity) { //Append to ef And then save it Db.Entry<T>(entity).State = System.Data.Entity.EntityState.Modified; //return Db.SaveChanges() > 0; return true; } /// <summary> /// Query filtering /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda) { return Db.Set<T>().Where(whereLambda); } /// <summary> /// paging /// </summary> /// <typeparam name="s"></typeparam> /// <param name="pageIndex">Page</param> /// <param name="pageSize">Quantity per page</param> /// <param name="totalCount">Total</param> /// <param name="whereLambda">Filter condition</param> /// <param name="orderbyLambda">sort criteria</param> /// <param name="isAsc"></param> /// <returns></returns> public IQueryable<T> PageLoadEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderbyLambda, bool isAsc) { var temp = Db.Set<T>().Where(whereLambda); totalCount = temp.Count(); if (isAsc)//positive sequence { //Column: pageIndex=3,pageSize=15 //Skip data before page 3 after positive sequence(First 2 pages*15),All that's left is 15 temp = temp.OrderBy<T, s>(orderbyLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize); } else//Reverse order { temp = temp.OrderByDescending<T, s>(orderbyLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize); } return temp; } }
/// <summary> /// 1.Data session layer: it is a factory class that is responsible for the creation of all data operation class instances, and then the business layer obtains the instances of the data classes to be operated through the data session layer, /// So data session layer decouples business layer and data layer. /// 2.A method is provided in the data session layer to save all data. /// </summary> public class DBSession { //OAEntities Db = new OAEntities(); public DbContext Db { get { return DBContextFactory.CreateDbContext(); } } private IUserInfoDal _UserInfoDal; public IUserInfoDal UserInfoDal { get { if(_UserInfoDal==null) { _UserInfoDal=new UserInfoDal(); } return _UserInfoDal; } set { _UserInfoDal = value; } } /// <summary> /// A business often involves the operation of multiple tables. We hope to connect the database once to complete the operation of the table data and improve the performance /// Work unit mode /// </summary> /// <returns></returns> public bool SaveChanges() { return Db.SaveChanges() > 0; } }