using System.Collections.Generic;
using System.Data;

namespace Mall.Repository
{
    /// <summary>
    /// Repository接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IDataRepository<T> where T : class
    {
        /// <summary>
        /// 执行SQL
        /// </summary>
        /// <param name="sql">sql命令</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务对象</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="commandType">命令类型</param>
        /// <returns></returns>
        int Execute(string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null);

        /// <summary>
        /// 新增一条数据
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        dynamic Insert(T entity);

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        dynamic Insert(T entity, IDbTransaction transaction = null);

        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <param name="entityList">实体列表对象</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool InsertBatch(IEnumerable<T> entityList, IDbTransaction transaction = null);

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool Update(T entity, IDbTransaction transaction = null);

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="fileds">需要更新的字段</param>
        /// <param name="where">where条件</param>
        /// <param name="transaction">事务</param>
        /// <returns></returns>
        bool Update(IDictionary<string, object> fileds, IList<WhereHelper> where, IDbTransaction transaction = null);

        /// <summary>
        /// 更新数据库字段(单个条件)
        /// </summary>
        /// <param name="fileds">更新字段(字典)</param>
        /// <param name="whereHelper">where条件(单个)</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool Update(IDictionary<string, object> fileds, WhereHelper whereHelper, IDbTransaction transaction = null);

        /// <summary>
        /// 批量更新数据
        /// </summary>
        /// <param name="entityList">实体列表对象</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool UpdateBatch(IEnumerable<T> entityList, IDbTransaction transaction = null);


        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="primaryId">主键编号</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        int Delete(dynamic primaryId, IDbTransaction transaction = null);

        /// <summary>
        /// 根据字典删除数据
        /// </summary>
        /// <param name="where">删除条件</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool Delete(IList<WhereHelper> where, IDbTransaction transaction = null);

        /// <summary>
        /// 根据Where条件删除一条记录
        /// </summary>
        /// <param name="whereHelper">删除条件字典</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool DeleteOne(WhereHelper whereHelper, IDbTransaction transaction = null);

        /// <summary>
        ///根据条件 批量删除数据
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        int DeleteList(object predicate, IDbTransaction transaction = null);

        /// <summary>
        /// 根据主键列表 批量删除数据
        /// </summary>
        /// <param name="ids">编号</param>
        /// <param name="transaction">事务对象</param>
        /// <returns></returns>
        bool DeleteBatch(IEnumerable<dynamic> ids, IDbTransaction transaction = null);

        /// <summary>
        /// 根据主键获得实体对象
        /// </summary>
        /// <param name="primaryId">主键编号</param>
        /// <returns></returns>
        T GetEntity(dynamic primaryId);

        /// <summary>
        /// 根据主键获得实体对象
        /// </summary>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="primaryId">主键编号</param>
        /// <returns></returns>
        TReturn GetEntity<TReturn>(dynamic primaryId) where TReturn : class;

        /// <summary>
        /// 根据主键列表 获得实体对象集合
        /// </summary>
        /// <param name="ids">动态Id</param>
        /// <returns></returns>
        IEnumerable<T> GetList(IList<dynamic> ids);

        /// <summary>
        /// 根据主键列表 获得实体对象集合
        /// </summary>
        /// <param name="ids">动态Id集合</param>
        /// <returns></returns>
        IEnumerable<TReturn> GetList<TReturn>(IList<dynamic> ids) where TReturn : class;

        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        IEnumerable<T> GetList();

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="allRowsCount">条数</param>
        /// <param name="sql">sql命令</param>
        /// <param name="param">参数</param>
        /// <param name="allRowsCountSql">条数sql</param>
        /// <param name="allRowsCountParam">条数sql参数</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="commandType">命令类型</param>
        /// <returns></returns>
        IEnumerable<T> GetPage(int pageIndex, int pageSize, out long allRowsCount, string sql, dynamic param = null, string allRowsCountSql = null, dynamic allRowsCountParam = null, int? commandTimeout = null, CommandType? commandType = null);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="TReturn">约束</typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="allRowsCount">条数</param>
        /// <param name="sql">sql命令</param>
        /// <param name="param">参数</param>
        /// <param name="allRowsCountSql">条数sql</param>
        /// <param name="allRowsCountParam">条数sql参数</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="commandType">命令类型</param>
        /// <returns></returns>
        IEnumerable<TReturn> GetPage<TReturn>(int pageIndex, int pageSize, out long allRowsCount, string sql, dynamic param = null, string allRowsCountSql = null, dynamic allRowsCountParam = null, int? commandTimeout = null, CommandType? commandType = null) where TReturn : class;
    }
}