using iWareCommon.Common.Dao;
using iWareCommon.Properties;
using iWareCommon.Utils;
using iWareModel;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
namespace iWareCommon.Common.Service
{
    /// 
    /// 公用方法的抽象类
    /// 张展
    /// 
    /// 自定义的实体类
    /// ORM中的实体类
    public abstract class CommonService:IService where T : class, ICommonEntity  where S : class where D: DbContext,IDisposable
    {
        #region 需要在子类中实现的抽象方法
        
        private CommonDao CommonDao;
        public CommonService(CommonDao commonDao) 
        {
            this.CommonDao = commonDao;
        }
        #endregion
        #region 根据条件查询
        /// 
        /// 根据条件查询自定义实体T的列表
        /// 
        /// 查询条件
        /// 错误信息
        /// 自定义实体T的记录列表
        public virtual List QueryByParam(QueryParam param, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.QueryByParam(param, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "QueryByParam", msg);
                    return new List();
                }
                catch (Exception ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "QueryByParam", ex.Message);
                    return new List();
                }
            }
        }
        #endregion
        #region 根据条件分页查询
        /// 
        /// 根据条件分页查询自定义实体T的列表,同时返回记录的总条数及当前所在的页数
        /// 
        /// 查询条件
        /// 异常错误消息
        /// 记录的总条数
        /// 当前页面数
        /// 自定义实体T的记录列表
        public virtual List QueryByParam(QueryParam param, out string msg, out int totalNum, out int currentPage)
        {
            msg = "";
            totalNum = 0;
            currentPage = 1;
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.QueryByParam(param, dbModel, out totalNum, out currentPage);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "QueryByParam", msg);
                    return new List();
                }
                catch (Exception ex)
                {
                    msg = ex.Message;
                    totalNum = 0;
                    currentPage = 1;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "QueryByParam", ex.Message);
                    return new List();
                }
            }
        }
        #endregion
        #region 插入新的对象
        
        /// 
        /// 将自定义的实体T的实例列表批量保存到数据库
        /// 
        /// 自定义类型T的实例列表
        /// 异常错误消息
        /// 保存的数量
        public virtual int Save(List ts, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.Save(ts, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Save", msg);
                    return 0;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex) 
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Save", ex.Message);
                    return 0;
                }
                catch (Exception ex)
                {
                    msg = ex.HResult == (int)EDbError.记录已存在 ? EDbError.记录已存在.ToString() : ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Save", msg);
                    return 0;
                }       
            }
        }
        /// 
        /// 将自定义的实体T的实例保存到数据库
        /// 
        /// 自定义类型T的实例
        /// 异常错误消息
        /// 新添加T对象的id
        public virtual int Save(T t, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.Save(t, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Save", msg);
                    return -1;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Save", ex.Message);
                    return -1;
                }
                catch (Exception ex)
                {
                    msg = ex.HResult == (int)EDbError.记录已存在 ? EDbError.记录已存在.ToString() : ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Save", msg);
                    return -1;
                }
            }
        }
        #endregion
        #region 修改对象
        /// 
        /// 修改自定义类型T的实体并保存到数据库
        /// 
        /// 自定义类型T的实例
        /// 异常错误消息
        /// 需改实体的id
        public virtual int Update(T t, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.Update(t, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Update", msg);
                    return -1;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "SaveUpdate", ex.Message);
                    return -1;
                }
                catch (Exception ex)
                {
                    msg = ex.HResult == (int)EDbError.记录已存在 ? EDbError.记录已存在.ToString() : ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Update", msg);
                    return -1;
                }
            }
        }
        /// 
        /// 修改自定义类型T的实体并保存到数据库
        /// 
        /// 自定义类型T的实例
        /// 异常错误消息
        /// 需改实体的id
        public virtual int Update(List ts, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    CommonDao.Update(ts, dbModel);
                    return ts.Count;
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Update", msg);
                    return -1;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "SaveUpdate", ex.Message);
                    return -1;
                }
                catch (Exception ex)
                {
                    msg = ex.HResult == (int)EDbError.记录已存在 ? EDbError.记录已存在.ToString() : ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Update", msg);
                    return -1;
                }
            }
        }
        #endregion
        #region 删除对象 
        
        /// 
        /// 从数据库中删除主键为id的记录
        /// 
        /// 需要删除对象的id
        /// 异常错误信息
        /// 被删除对象的主键
        public virtual int Delete(int id, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.Delete(id, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Delete", msg);
                    return -1;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Delete", ex.Message);
                    return -1;
                }
                catch (Exception ex)
                {
                    msg = "记录已被其他对象引用,不能删除";
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Delete", ex.Message);
                    return -1;
                }
            }
        }
        /// 
        /// 从数据库中批量删除主键列表为ids的记录
        /// 
        /// 需要删除对象的id列表
        /// 异常错误信息
        /// 被删除对象的数量
        public virtual int Delete(List ids, out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.Delete(ids, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "Delete", msg);
                    return 0;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Delete", ex.Message);
                    return 0;
                }
                catch (Exception ex)
                {
                    msg = "记录已被其他对象引用,不能删除";
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Delete", ex.Message);
                    return 0;
                }
            }
        }
        #endregion
        #region 拼装字典
        /// 
        /// 将满足条件的T类型拼装成以id为键,类型本身为值的字典
        /// 
        /// 查询条件
        /// 异常错误消息
        /// 以id为键,类型本身为值的字典
        public virtual Dictionary ToDictionary(QueryParam param,out string msg)
        {
            msg = "";
            var type = typeof(D);
            using (var dbModel = type.Assembly.CreateInstance(type.FullName) as DbContext)
            {
                try
                {
                    return CommonDao.ToDictionary(param, dbModel);
                }
                catch (DbEntityValidationException ex)
                {
                    var errs = ex.EntityValidationErrors.SelectMany(validationResult => validationResult.ValidationErrors).Select(m => m.ErrorMessage);
                    msg = string.Join(", ", errs);
                    LogTextHelper.WriteLog(Resources.LogDir,  this.ToString(), "ToDictionary", msg);
                    return new Dictionary();
                }
                catch (Exception ex)
                {
                    msg = ex.Message;
                    LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "ToDictionary", ex.Message);
                    return new Dictionary();
                }
            }
        }
        #endregion
    }
}