DAL底层封装了一个上下文的文件源码:
public abstract class EFContext
{
#region 单例模式创建一个上下文对象
private static DbContext dbContext=null;
protected static DbContext CreateInstance(string connectKeyName="DbContext")
{
DbContext db=CallContext.GetData(connectKeyName) as DbContext;
if(db==null)
{
db=Activator.CreateInstance(Type.GetType("AssemblyName."+connectKeyName+",AssemblyName")) as DbContext;
CallContext.SetData(connectKeyName,db);
}
return db;
}
#endregion
public DbContext _db=CreateInstance();
public virtual int SaveChanges()
{
return this._db.SaveChanges();
}
}
然后有一个IBaseRepository基接口定义了一些基础方法
public interface IBaseRepository<T> where T : class
{
T Insert(T entity);
void Delete(T entity);
T Update(T entity);
//......
}
实现接口的一个文件DataAccess
public class DataAccess<T>:EFContext,IBaseRepository<T>,IDisposable where T: class
{
public DataAccess(string connectKeyName)
{
_db.CreateInstance(!string.IsNullOrEmpty(connectKeyName)?connectKeyName:"DbContext");
}
public T Insert(T entity)
{
_db.Set<T>().Add(entity);
return entity;
}
//......
}
上面是DAL的处理
下面开始BLL层的处理
public abstract class BaseRepository<T> : IBLL.IBaseRepository<T> where T : class
{
private static string KeyName="DbContext";
public static string SetConnectorName(string ckeyName="DbContext")
{
KeyName=ckeyName;
return KeyName
}
public int SaveChanges()
{
return _baseRepository.SaveChanges();
}
}
private static IDAL.IBaseRepository<T> _baseRepository=new DAL.DataAccess<T>(KeyName);
public T Update(T entity)
{
return _baseRepository.Update(entity);
}
//...集成IBLL.IBaseRepository接口的方法实现就不一一写了
}
每个表对应的BLL层的类文件
public class TableA : BaseRepository<Model.TableA>,IBLL.ITableA
{
public TableA()
{
SetConnectorName("DbContext");
}
}
后面有一个比较复杂的逻辑,就是有一个表A是作为主表,B,C分别是外键表,A中的字段分别是作为外键约束引用的B,C的主键,这样我在更新A,B,C的数据的时候我的操作就是直接更新A,然后把B,C中的当前数据的列表先执行删除,然后再插入到B,C中,写入如下
public int UpdateEntity(Model.TableA entity)
{
var bList=entity.B==null?new List<Model.TableB>():entity.B.ToList();
var cList=entity.C==null?new List<Model.TableC>():entity.C.ToList();
entity.B=null;
entity.C=null;
IBLL.TableB tb=new BLL.TableB();
IBLL.TableC tc=new BLL.TableC();
tb.DeleteList(t=>t.aId==entity.Id);
tc.DeleteList(t=>t.aId==entity.Id);
base.Update(entity);
if(bList.count!=0)
{
tb.InsertList(bList);
}
if(cList.Count!=0)
{
tc.InsertList(cList);
}
SaveChanges();
tb.SaveChanges();//开始没有如下两句
tc.SaveChanges();//开始没有如下两句
}
最开始的情况就是A表能够保存修改,但是B,C表的修改不能够被保存,后面加入了两句saveChanges就正常了,这个saveChanges方法不是保存的上下文吗,而我底层DAL.DataAccess获取DbContext时不是同一个导致吗,高人能告知下这是为什么吗?
------解决思路----------------------
博客园不是在外面又套了一个,什么IUnitOfWork,也就是他们自己也承认什么IRepository其实还不够,所以在套个IUnitOfWork去补充
------解决思路----------------------
看看开源项目:nopCommerce
你会更加好地运用nopCommerce模式
public class DataAccess<T>:EFContext,IBaseRepository<T>,IDisposable where T: class
{
public DataAccess(string connectKeyName)
{
_db.CreateInstance(!string.IsNullOrEmpty(connectKeyName)?connectKeyName:"DbContext");
}
public T Insert(T entity)
{
_db.Set<T>().Add(entity);// 这里是_db, 你的单例变量是:private static DbContext dbContext=null;构造出来都没有用
return entity;
}
//......
}
所以要分别savechange,另外 EF最好不要用单例
看看我推荐的项目IOC控制EF生命周期的方式
另外IUnitOfWork 还是一个不错的概念的,就看你自己怎么实现