首页 新闻 会员 周边

接口是否有间接实现接口的定义?(实现方并不直接实现接口)

0
悬赏园豆:10 [已解决问题] 解决于 2014-04-16 10:42
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 接口。
薛凯凯圆滚滚的主页 薛凯凯圆滚滚 | 初学一级 | 园豆:36
提问于:2014-03-05 16:05
< >
分享
最佳答案
-1

CS_AccountProvider 还继承了 ICS_AccountProvider,而后者继承了 IBaseProvider<CS_Account>。

收获园豆:10
Launcher | 高人七级 |园豆:45045 | 2014-03-05 16:12

没懂?CS_AccountProvider 实现 ICS_AccountProvider 而后者继承了 IBaseProvider

但为什么跟 CS_AccountProvider 继承 BaseProvider 有关系捏?

按道理应该是  BaseProvider 去实现  IBaseProvider 才对嘛。

薛凯凯圆滚滚 | 园豆:36 (初学一级) | 2014-03-05 16:19

@薛凯凯凯凯凯: 你要按“道理”让 BaseProvider 实现 IBaseProvider 也没有问题。但这不影响不按“道理”写的代码运行的正确性。

Launcher | 园豆:45045 (高人七级) | 2014-03-05 16:28

@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();
        }
    }

 

薛凯凯圆滚滚 | 园豆:36 (初学一级) | 2014-03-05 16:34

@薛凯凯凯凯凯: BaseProvider 的所有方法都是不是 virtual 的,因此子类没有任何可以 override 父类方法的可能。也就是说作者的意图可能就是将 BaseProvider 仅仅定义为可复用的方法,那么,如果子类需要自己特有的方法,那么可以在子类接口中去定义,而不影响其它子类。如果该方法可以提升到所有子类,那么就可以把该方法的定义放到 IBaseProvider 中去,这时候有两种情况,一、此方法的实现,各子类不一样;二、此方法的实现,各子类一样,先看后者,很简单,为 BaseProvider 添加相同方法名的实现;对于后者而言,BaseProvider 不做任何修改,而是在各子类中去实现,这样当使用 IBaseProvider 接口时,仍然能够正确访问到此方法。对于第一种情况而言,假设 BaseProvider 先继承 IBaseProvider,那么问题就来了,BaseProvider 必须去实现 IBaseProvider 上新添加的方法,又因为此方法各子类实现不一样,那么各子类又要自己实现,事实上在这个过程,BaseProvider 是否要实现这个方法并不重要,因此这种不按“道理”的设计方式,恰好绕过了这个障碍,尽可能避免修改 BaseProvider 类。

Launcher | 园豆:45045 (高人七级) | 2014-03-05 16:47

@Launcher: 有段话我不太明白!先看后者,很简单,为 BaseProvider 添加相同方法名的实现;对于后者而言,BaseProvider 不做任何修改,而是在各子类中去实现,这样当使用 IBaseProvider 接口时,仍然能够正确访问到此方法。这段第一句我理解(后者BASE实现接口的方式)直接添加相同方法名,第二句你还是说后者?我就糊涂?应该前者的设计方式吧? 还有就是最后那句话你说 : 又因为此方法各子类实现不一样,那么各子类又要自己实现。OK 这个我承认。说的是后者的设计方式先继承的。那么前者你没说?前者如何实现各子类不一样而不用子类都再去写一次自己的实现? 我只看到就节省了一步,就是不在父类中写虚方法,直接让子类去实现父接口的方法。对不对?

薛凯凯圆滚滚 | 园豆:36 (初学一级) | 2014-03-05 17:59

@薛凯凯凯凯凯: 对。

Launcher | 园豆:45045 (高人七级) | 2014-03-05 18:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册