/// <summary>
 /// 创建参数集合
 /// </summary>
 /// <param name="propertys"></param>
 /// <returns></returns>
 private IEnumerable <KeyValuePair <string, object> > BuildDataParameter(IEnumerable <KeyValuePair <string, PropertyInfo> > propertys)
 {
     return(propertys.Select(item =>
     {
         ModelPropertyAttribute mpa = item.Value.GetCustomAttribute <ModelPropertyAttribute>(false);
         if (mpa != null)
         {
             if (mpa.Identity)
             {
                 return new KeyValuePair <string, object>(item.Key, item.Value.GetValue(this) ?? -1);//自增列给与默认值-1
             }
             else if (mpa.Guid)
             {
                 return new KeyValuePair <string, object>(item.Key, item.Value.GetValue(this) ?? Guid.NewGuid().ToString("N"));//Guid给与默认值
             }
             else
             {
                 return new KeyValuePair <string, object>(item.Key, item.Value.GetValue(this));
             }
         }
         else
         {
             return new KeyValuePair <string, object>(item.Key, item.Value.GetValue(this));
         }
     }));
 }
        /// <summary>
        /// 根据非主键信息创建赋值字符串
        /// </summary>
        /// <param name="generals">非主键集合</param>
        /// <returns></returns>
        private int Update(IEnumerable <KeyValuePair <string, PropertyInfo> > keys, IEnumerable <KeyValuePair <string, PropertyInfo> > generals)
        {
            if (keys.Count() == 0)
            {
                throw new KeyNotFoundException("无主键信息");
            }
            if (generals.Count() == 0)
            {
                throw new KeyNotFoundException("无字段信息");
            }


            string update = string.Empty;

            foreach (KeyValuePair <string, PropertyInfo> item in generals)
            {
                ModelPropertyAttribute mpa = item.Value.GetCustomAttribute <ModelPropertyAttribute>(false);
                if (mpa != null && (mpa.Identity || mpa.OnlyInsert))
                {
                    continue;
                }
                update += $", {item.Key}=@{item.Key}";
            }
            update = $"UPDATE {GetTableName()} SET {update.TrimStart(',')} WHERE 1=1 {BuildCondition(keys)}";

            //拼接主键和普通属性,并移除非Key的Identity属性
            IEnumerable <KeyValuePair <string, PropertyInfo> > allKeys = keys.Union(generals).Where(item =>
            {
                ModelPropertyAttribute mpa = item.Value.GetCustomAttribute <ModelPropertyAttribute>(false);
                if (mpa == null)
                {
                    return(true);
                }
                else
                {
                    if (mpa.Identity && !mpa.Key)
                    {
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }
            });

            return(TwinkleContext.GetRequiredService <DatabaseManager>().ExecuteNonQuery(update, BuildDataParameter(allKeys)));
        }
        /// <summary>
        /// 执行插入操作
        /// </summary>
        /// <param name="keys">主键集合</param>
        /// <param name="generals">非主键集合</param>
        /// <returns></returns>
        private int Insert(IEnumerable <KeyValuePair <string, PropertyInfo> > keys, IEnumerable <KeyValuePair <string, PropertyInfo> > generals)
        {
            PropertyInfo identityKey = null;
            //拼接主键和普通属性,并移除Identity属性
            IEnumerable <KeyValuePair <string, PropertyInfo> > allKey = keys.Union(generals).Where(item =>
            {
                ModelPropertyAttribute mpa = item.Value.GetCustomAttribute <ModelPropertyAttribute>(false);
                if (mpa == null)
                {
                    return(true);
                }
                else if (mpa.Identity)
                {
                    identityKey = item.Value;
                    return(false);
                }
                else
                {
                    return(true);
                }
            });

            if (allKey.Count() == 0)
            {
                throw new KeyNotFoundException("无字段信息");
            }

            string insert       = string.Empty;
            string insertValues = string.Empty;

            foreach (KeyValuePair <string, PropertyInfo> item in allKey)
            {
                insert       += $",{item.Key}";
                insertValues += $",@{item.Key}";
            }

            insert  = $"INSERT INTO {GetTableName()}({insert.TrimStart(',')}) VALUES({insertValues.TrimStart(',')});";
            insert += "SELECT @@Identity";//获取自增长列的值
            int result = TwinkleContext.GetRequiredService <DatabaseManager>().ExecuteInteger(insert, BuildDataParameter(allKey));

            if (identityKey != null)
            {
                identityKey.SetValue(this, Convert.ChangeType(result.ToString(), (Nullable.GetUnderlyingType(identityKey.PropertyType) == null ? identityKey.PropertyType : Nullable.GetUnderlyingType(identityKey.PropertyType))));
            }
            return(result);
        }
        /// <summary>
        /// 获取属性集合
        /// </summary>
        /// <param name="isKey"></param>
        /// <returns></returns>
        private IEnumerable <KeyValuePair <string, PropertyInfo> > Propertys(bool isKey)
        {
            PropertyInfo[] Properties = this.GetType().GetProperties();

            Dictionary <string, PropertyInfo> dict = new Dictionary <string, PropertyInfo>();

            foreach (PropertyInfo prop in Properties)
            {
                ModelPropertyAttribute mpa = prop.GetCustomAttribute <ModelPropertyAttribute>(false);
                if (mpa != null)
                {
                    if (mpa.Virtual)
                    {
                        continue;//虚拟列不做处理
                    }

                    if (mpa.Identity && mpa.Guid)
                    {
                        throw new CustomAttributeFormatException($"属性{GetTableName()}.{prop.Name}不能既是Identity又是Guid");
                    }

                    if (mpa.Key == isKey)
                    {
                        dict.Add(prop.Name, prop);
                    }
                }
                else
                {
                    if (!isKey)//未添加ModelPropertyAttribute特性的属性都按照普通属性处理
                    {
                        dict.Add(prop.Name, prop);
                    }
                }
            }
            return(dict);
        }