using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;

namespace DAL
{

//new():实例化对象,对泛型的约束
public class EFHelper<TDataBase> where TDataBase : DbContext,new()
{
    static EFHelper<TDataBase> instance = null;
    //私有化构造函数 EF(Entity FrameWork):DatabaseFirst,ModelFirst,CodeFirst
    private EFHelper()
    {  
    
    }

    /// <summary>
    /// 返回当前对象实例
    /// </summary>
    /// <returns></returns>
    public static EFHelper<TDataBase> GetInstance()
    {
        if (instance == null)
        {
            instance = new EFHelper<TDataBase>();
        }
        return instance;
    }

    TDataBase db = null;
    public TDataBase GetDataContext()
    {
        if (db == null)
        {
            db = new TDataBase();
        }
        return db;
    }

    /// <summary>
    /// 返回所有数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> GetList<T>() where T : class
    {
        //单例,创建者,观察者(发布订阅),适配器,门面,职责链,模板,工厂,抽象工厂
        var db = GetDataContext();
        return db.Set<T>().ToList();
    }

    /// <summary>
    /// 根据条件查询
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="predicate"></param>
    /// <returns>集合对象</returns>
    public List<T> GetList<T>(Expression<Func<T,bool>> predicate) where T:class
    {
        var db = GetDataContext();
        return db.Set<T>().Where(predicate).ToList();
    }

    /// <summary>
    /// 根据条件查询
    /// 使用EF时必须每张表都有主键ID
    /// EF:修改删除时必须先获取要修改的数据对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="predicate"></param>
    /// <returns>一个对象</returns>
    public T GetSingle<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        var db = GetDataContext();
        return db.Set<T>().FirstOrDefault(predicate);
    }

    /// <summary>
    /// 插入一个实体
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Entity"></param>
    /// <returns></returns>
    public T InsertEntity<T>(T Entity) where T : class
    {
        var db = GetDataContext();
        try
        {
            T result = db.Set<T>().Add(Entity);
            db.SaveChanges();
            return result;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    /// <summary>
    /// 修改
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Entity"></param>
    /// <returns></returns>
    public bool Update<T>(T Entity) where T : class
    {
        var db = GetDataContext();
        var entry = db.Entry(Entity);
        //System.Data.Entity
        entry.State = System.Data.EntityState.Modified;
        return db.SaveChanges() > 0 ? true : false;
    }

    /// <summary>
    /// 传入实体删除
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Entity"></param>
    /// <returns></returns>
    public bool Delete<T>(T Entity) where T : class
    {
        var db = GetDataContext();
        db.Set<T>().Remove(Entity);
        return db.SaveChanges() > 0 ? true : false;
    }

    /// <summary>
    /// 分布查询
    /// </summary>
    /// <typeparam name="T">查询的对象</typeparam>
    /// <typeparam name="TKey">排序字段类型</typeparam>
    /// <param name="predicate">查询条件</param>
    /// <param name="keySelector">排序字段</param>
    /// <param name="pageIndex">当前页数</param>
    /// <param name="pageNum">每页条数</param>
    /// <param name="orderType">排序类型,1:升序,2:降序</param>
    /// <returns>数据列表</returns>
    public List<T> GetListByPager<T , TKey>(Expression<Func<T, bool>> predicate, Expression<Func<T, TKey>> keySelector, int pageIndex, int pageNum , int orderType) where T : class
    {
        var db = GetDataContext();
        if (orderType == 1)
        {
            return db.Set<T>().Where(predicate).OrderBy(keySelector).Skip((pageIndex - 1) * pageNum).Take(pageNum).ToList();
        }
        else
        {
            return db.Set<T>().Where(predicate).OrderByDescending(keySelector).Skip((pageIndex - 1) * pageNum).Take(pageNum).ToList();
        }
    }

    /// <summary>
    /// 使用SQL增删改
    /// </summary>
    /// <param name="sqlstr"></param>
    /// <param name="pars"></param>
    public int GetPro(string sqlstr, SqlParameter[] pars)
    {
        var db = GetDataContext();
        return db.Database.ExecuteSqlCommand(sqlstr, pars);
    }

    /// <summary>
    /// 使用SQL查询数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sqlstr"></param>
    /// <param name="pars"></param>
    /// <returns></returns>
    public List<T> GetSqlStr<T>(string sqlstr, SqlParameter[] pars)
    {
        var db = GetDataContext();
        return db.Database.SqlQuery<T>(sqlstr, pars).ToList();
    }
}

}