public class BaseProvider<T> where T : class { //创建EF框架的上下文 //EF上下文的实例保证线程内唯一 //private DataModelContainer db = new DataModelContainer(); /// <summary> /// 获取的是当前线程内部的上下文实例,而且保证了线程内上下文唯一 /// </summary> private readonly DbContext _db = EFContextFactory.GetCurrentDbContext(); /// <summary> /// 实现对数据库的添加功能,添加实现EF框架的引用 /// </summary> /// <param name="entity">实体类</param> /// <returns>最后返回对象的实体类型</returns> public T AddEntity(T entity) { //EF4.0的写法 添加实体 //db.CreateObjectSet<T>().AddObject(entity); //EF5.0的写法 _db.Entry<T>(entity).State = EntityState.Added; //下面的写法统一 //db.SaveChanges(); return entity; } /// <summary> /// 实现对数据库的修改功能 /// </summary> /// <param name="entity">实体类</param> /// <returns>返回是否执行成功,如果执行成功,返回true,负责返回false</returns> public bool UpdateEntity(T entity) { //EF4.0的写法 //db.CreateObjectSet<T>().Addach(entity); //db.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); //EF5.0的写法 //db.Set<T>().Attach(entity); _db.Entry<T>(entity).State = EntityState.Modified; //return db.SaveChanges() > 0; return true; } /// <summary> /// 实现对数据库的删除功能 /// </summary> /// <param name="entity">实体类</param> /// <returns>返回是否执行成功,如果执行成功,返回true,负责返回false</returns> public bool DeleteEntity(T entity) { //EF4.0的写法 //db.CreateObjectSet<T>().Addach(entity); //db.ObjectStateManager.ChangeObjectState(entity, EntityState.Deleted); //EF5.0的写法 _db.Set<T>().Attach(entity); _db.Entry<T>(entity).State = EntityState.Deleted; // return db.SaveChanges() > 0; return true; } /// <summary> /// 实现对数据库的查询 --简单查询 /// </summary> /// <param name="whereLambda">查询的简单条件</param> /// <returns>返回一个实体类的IQueryable集合</returns> public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda) { //EF4.0的写法 //return db.CreateObjectSet<T>().Where<T>(whereLambda).AsQueryable(); //EF5.0的写法 return _db.Set<T>().Where<T>(whereLambda).AsQueryable(); } /// <summary> /// 实现对数据的分页查询 /// </summary> /// <typeparam name="S">按照某个类进行排序</typeparam> /// <param name="pageIndex">当前第几页</param> /// <param name="pageSize">一页显示多少条数据</param> /// <param name="total">总条数</param> /// <param name="whereLambda">取得排序的条件</param> /// <param name="isAsc">如何排序,根据倒叙还是升序</param> /// <param name="orderByLambda">根据那个字段进行排序</param> /// <returns>返回一个实体类型的IQueryable集合</returns> public IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> whereLambda, bool isAsc, Expression<Func<T, S>> orderByLambda) { //EF4.0和上面的查询一样 //EF5.0 var temp = _db.Set<T>().Where<T>(whereLambda); total = temp.Count(); //得到总的条数 //排序,获取当前页的数据 if (isAsc) { temp = temp.OrderBy<T, S>(orderByLambda) .Skip<T>(pageSize * (pageIndex - 1)) //越过多少条 .Take<T>(pageSize).AsQueryable(); //取出多少条 } else { temp = temp.OrderByDescending<T, S>(orderByLambda) .Skip<T>(pageSize * (pageIndex - 1)) //越过多少条 .Take<T>(pageSize).AsQueryable(); //取出多少条 } return temp.AsQueryable(); } }
public interface IBaseProvider<T> where T : class, new() { /// <summary> /// 实现对数据库的添加功能,添加实现EF框架的引用 /// </summary> /// <param name="entity"></param> /// <returns></returns> T AddEntity(T entity); /// <summary> /// 实现对数据库的修改功能 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool UpdateEntity(T entity); /// <summary> /// 实现对数据库的删除功能 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool DeleteEntity(T entity); /// <summary> /// 实现对数据库的查询 --简单查询 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda); /// <summary> /// 实现对数据的分页查询 /// </summary> /// <typeparam name="S">按照某个类进行排序</typeparam> /// <param name="pageIndex">当前第几页</param> /// <param name="pageSize">一页显示多少条数据</param> /// <param name="total">总条数</param> /// <param name="whereLambda">取得排序的条件</param> /// <param name="isAsc">如何排序,根据倒叙还是升序</param> /// <param name="orderByLambda">根据那个字段进行排序</param> /// <returns></returns> IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> whereLambda, bool isAsc, Expression<Func<T, S>> orderByLambda); }
public interface ICS_AccountProvider : IBaseProvider<CS_Account> { }
public class CS_AccountProvider : BaseProvider<CS_Account>,ICS_AccountProvider { }
问个问题,就是为什么 BaseProvider 并有没有 实现 IBaseProvider 为在
CS_AccountProvider 类中继承BaseProvider也算 实现IBaseProvider 接口。
CS_AccountProvider 还继承了 ICS_AccountProvider,而后者继承了 IBaseProvider<CS_Account>。
没懂?CS_AccountProvider 实现 ICS_AccountProvider 而后者继承了 IBaseProvider
但为什么跟 CS_AccountProvider 继承 BaseProvider 有关系捏?
按道理应该是 BaseProvider 去实现 IBaseProvider 才对嘛。
@薛凯凯凯凯凯: 你要按“道理”让 BaseProvider 实现 IBaseProvider 也没有问题。但这不影响不按“道理”写的代码运行的正确性。
@Launcher: 大牛,我想问下 这样的设计好,还是说 让Base抽象去实现IBase好?
比如我这样
public interface IRepository<T> { void Add(T entity); void Del(T entity); void Update(T entity); T Find(Guid entityId); IList<T> Find(ICriteria criteria); IList<T> FindAll(); IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr); int Count(ICriteria criteria); void SaveChanges(); }
public abstract class BaseRepositoryBase<T> : IRepository<T> where T : class { protected CsDbContext dbContext; protected DbSet<T> dbSet; public BaseRepositoryBase(CsDbContext dataContext) { this.dbContext = dataContext; this.dbSet = dataContext.Set<T>(); } #region IRepository<T> 成员 public virtual void Add(T entity) { dbSet.Add(entity); } private string EntitySetName { get { return typeof(T).Name; } } public virtual void Del(T entity) { if (dbContext.Entry(entity).State == EntityState.Detached) { dbSet.Attach(entity); } dbContext.Set<T>().Remove(entity); } public virtual void Update(T entity) { dbSet.Attach(entity); dbContext.Entry(entity).State = EntityState.Modified; } protected ObjectQuery<T> EntitySet { get { IObjectContextAdapter adapter = this.dbContext; return adapter.ObjectContext.CreateQuery<T>("[" + EntitySetName + "]"); } } public IList<T> Find(ICriteria criteria) { if (criteria == null) throw new ArgumentNullException("criteria"); var query = EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray()); return ToList(query); } public IList<T> FindAll() { return ToList(EntitySet); } public IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr) { if (criteria == null || orderExpr == null) throw new ArgumentNullException("criteria"); var query = EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray()); return ToList(orderExpr.OrderFrom<T>(query).Skip((page - 1) * pageSize).Take(pageSize)); } public int Count(ICriteria criteria) { if (criteria == null) throw new ArgumentNullException("criteria"); return EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray()).Count(); } public void SaveChanges() { dbContext.SaveChanges(); } public virtual T Find(Guid entityId) { return Find(new EqualParameterCriteria(EntitySetName + "Id", entityId)).FirstOrDefault(); } protected virtual IList<T> ToList(IQueryable<T> query) { return query.AsEnumerable().Select(x => CreateSqlEntity(x)).Cast<T>().ToList(); } #endregion protected abstract T CreateSqlEntity(T x); public int GetAccounts(ICriteria criteria, int page, int pageSize, Order orderExpr) { if (criteria == null || orderExpr == null) throw new ArgumentNullException("criteria"); var query = EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray()); return ToList(orderExpr.OrderFrom<T>(query).Skip((page - 1) * pageSize).Take(pageSize)).Count; } }
public interface IReservedRepository : IRepository<Cs_Reserved> { IEnumerable<Cs_Reserved> Reserveds { get; } IList<Cs_Reserved> GetAllReserveds(); }
public class ReservedRepository : BaseRepositoryBase<Cs_Reserved>, IReservedRepository { public ReservedRepository(CsDbContext dbContext) : base(dbContext) { } public IEnumerable<Cs_Reserved> Reserveds { get { return dbContext.ReservedCollection; } } public IList<Cs_Reserved> GetAllReserveds() { return FindAll(); } protected override Cs_Reserved CreateSqlEntity(Cs_Reserved x) { throw new NotImplementedException(); } }
@薛凯凯凯凯凯: BaseProvider 的所有方法都是不是 virtual 的,因此子类没有任何可以 override 父类方法的可能。也就是说作者的意图可能就是将 BaseProvider 仅仅定义为可复用的方法,那么,如果子类需要自己特有的方法,那么可以在子类接口中去定义,而不影响其它子类。如果该方法可以提升到所有子类,那么就可以把该方法的定义放到 IBaseProvider 中去,这时候有两种情况,一、此方法的实现,各子类不一样;二、此方法的实现,各子类一样,先看后者,很简单,为 BaseProvider 添加相同方法名的实现;对于后者而言,BaseProvider 不做任何修改,而是在各子类中去实现,这样当使用 IBaseProvider 接口时,仍然能够正确访问到此方法。对于第一种情况而言,假设 BaseProvider 先继承 IBaseProvider,那么问题就来了,BaseProvider 必须去实现 IBaseProvider 上新添加的方法,又因为此方法各子类实现不一样,那么各子类又要自己实现,事实上在这个过程,BaseProvider 是否要实现这个方法并不重要,因此这种不按“道理”的设计方式,恰好绕过了这个障碍,尽可能避免修改 BaseProvider 类。
@Launcher: 有段话我不太明白!先看后者,很简单,为 BaseProvider 添加相同方法名的实现;对于后者而言,BaseProvider 不做任何修改,而是在各子类中去实现,这样当使用 IBaseProvider 接口时,仍然能够正确访问到此方法。这段第一句我理解(后者BASE实现接口的方式)直接添加相同方法名,第二句你还是说后者?我就糊涂?应该前者的设计方式吧? 还有就是最后那句话你说 : 又因为此方法各子类实现不一样,那么各子类又要自己实现。OK 这个我承认。说的是后者的设计方式先继承的。那么前者你没说?前者如何实现各子类不一样而不用子类都再去写一次自己的实现? 我只看到就节省了一步,就是不在父类中写虚方法,直接让子类去实现父接口的方法。对不对?
@薛凯凯凯凯凯: 对。