using SqlSugar;
|
using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations.Schema;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_Core.Const;
|
using WIDESEA_Core.Helper;
|
|
namespace WIDESEA_Core.Utilities
|
{
|
public static class EntityProperties
|
{
|
/// <summary>
|
/// 验证数据库字段类型与值是否正确,
|
/// </summary>
|
/// <param name="value">值</param>
|
/// <param name="propertyInfo">要验证的类的属性,若不为null,则会判断字符串的长度是否正确</param>
|
/// <returns>(bool, string, object)bool成否校验成功,string校验失败信息,object,当前校验的值</returns>
|
public static (bool, string, object) ValidationVal(this PropertyInfo propertyInfo, object value)
|
{
|
string dbType = "";
|
SugarColumn sugarColumn = null;
|
if (propertyInfo != null)
|
{
|
sugarColumn = propertyInfo.GetCustomAttribute<SugarColumn>();
|
dbType = propertyInfo.PropertyType != null ? propertyInfo.GetProperWithDbType() : SqlDbTypeName.NVarChar;
|
}
|
dbType = dbType.ToLower();
|
string val = value?.ToString();
|
//验证长度
|
string reslutMsg = string.Empty;
|
if (dbType == SqlDbTypeName.Int)
|
{
|
if (!value.IsInt())
|
reslutMsg = "只能为有效整数";
|
} //2021.10.12增加属性校验long类型的支持
|
else if (dbType == SqlDbTypeName.BigInt)
|
{
|
if (!long.TryParse(val, out _))
|
{
|
reslutMsg = "只能为有效整数";
|
}
|
}
|
else if (dbType == SqlDbTypeName.DateTime
|
|| dbType == SqlDbTypeName.Date
|
|| dbType == SqlDbTypeName.SmallDateTime
|
|| dbType == SqlDbTypeName.SmallDate
|
)
|
{
|
if (!value.IsDate())
|
reslutMsg = "必须为日期格式";
|
}
|
else if (dbType == SqlDbTypeName.Float || dbType == SqlDbTypeName.Decimal || dbType == SqlDbTypeName.Double)
|
{
|
|
if (!val.IsNumber(null))
|
{
|
reslutMsg = "不是有效数字";
|
}
|
}
|
else if (dbType == SqlDbTypeName.UniqueIdentifier)
|
{
|
if (!val.IsGuid())
|
{
|
reslutMsg = propertyInfo.Name + "Guid不正确";
|
}
|
}
|
else if (propertyInfo != null
|
&& (dbType == SqlDbTypeName.VarChar
|
|| dbType == SqlDbTypeName.NVarChar
|
|| dbType == SqlDbTypeName.NChar
|
|| dbType == SqlDbTypeName.Char
|
|| dbType == SqlDbTypeName.Text))
|
{
|
|
//默认nvarchar(max) 、text 长度不能超过20000
|
if (val.Length > 200000)
|
{
|
reslutMsg = $"字符长度最多【200000】";
|
}
|
else
|
{
|
|
int length = sugarColumn.Length;
|
if (length == 0) { return (true, null, null); }
|
//判断双字节与单字段
|
else if (length < 8000 &&
|
((dbType.Substring(0, 1) != "n"
|
&& Encoding.UTF8.GetBytes(val.ToCharArray()).Length > length)
|
|| val.Length > length)
|
)
|
{
|
reslutMsg = $"最多只能【{length}】个字符。";
|
}
|
}
|
}
|
if (!string.IsNullOrEmpty(reslutMsg) && propertyInfo != null)
|
{
|
reslutMsg = sugarColumn.ColumnDescription + reslutMsg;
|
}
|
return (reslutMsg == "" ? true : false, reslutMsg, value);
|
}
|
|
public static List<(bool, string, object)> ValidationValueForDbType(this PropertyInfo propertyInfo, params object[] values)
|
{
|
List<(bool, string, object)> result = new List<(bool, string, object)>();
|
foreach (object value in values)
|
{
|
result.Add(propertyInfo.ValidationVal(value));
|
}
|
return result;
|
}
|
|
private static readonly Dictionary<Type, string> ProperWithDbType = new Dictionary<Type, string>() {
|
{ typeof(string),SqlDbTypeName.NVarChar },
|
{ typeof(DateTime),SqlDbTypeName.DateTime},
|
{typeof(long),SqlDbTypeName.BigInt },
|
{typeof(int),SqlDbTypeName.Int},
|
{ typeof(decimal),SqlDbTypeName.Decimal },
|
{ typeof(float),SqlDbTypeName.Float },
|
{ typeof(double),SqlDbTypeName.Double },
|
{ typeof(byte),SqlDbTypeName.Int },//类型待完
|
{ typeof(Guid),SqlDbTypeName.UniqueIdentifier}
|
};
|
|
public static string GetProperWithDbType(this PropertyInfo propertyInfo)
|
{
|
bool result = ProperWithDbType.TryGetValue(propertyInfo.PropertyType, out string value);
|
if (result)
|
{
|
return value;
|
}
|
return SqlDbTypeName.NVarChar;
|
}
|
|
/// <summary>
|
/// 判断hash的列是否为对应的实体,并且值是否有效
|
/// </summary>
|
/// <param name="typeinfo"></param>
|
/// <param name="dic"></param>
|
/// <param name="removeNotContains">移除不存在字段</param>
|
/// <param name="removerKey">移除主键</param>
|
/// <returns></returns>
|
public static string ValidateDicInEntity(this Type typeinfo, Dictionary<string, object> dic, bool removerKey, PropertyInfo[] propertyInfo, string[] ignoreFields = null)
|
{
|
if (dic == null || dic.Count == 0) { return "参数无效"; }
|
|
// 不存在的字段直接移除
|
dic.Where(x => !propertyInfo.Any(p => p.Name == x.Key.FirstLetterToUpper())).Select(s => s.Key).ToList().ForEach(f =>
|
{
|
dic.Remove(f);
|
});
|
|
string keyName = typeinfo.GetKeyName();
|
//移除主键
|
if (removerKey)
|
dic.Remove(keyName);
|
//else
|
//{
|
// if (!dic.ContainsKey(keyName))
|
// return "请传入主键参数";
|
//}
|
|
foreach (PropertyInfo property in propertyInfo)
|
{
|
SugarColumn sugarColumn = property.GetCustomAttribute<SugarColumn>();
|
if (sugarColumn == null)
|
return "请配置SugarColumn属性";
|
//忽略与主键的字段不做验证
|
if (property.Name == keyName.FirstLetterToUpper() || (ignoreFields != null && ignoreFields.Contains(property.Name)) || sugarColumn.IsOnlyIgnoreInsert || sugarColumn.IsOnlyIgnoreUpdate || sugarColumn.IsIgnore)
|
continue;
|
|
//不在编辑中的列,是否也要必填
|
if (!dic.ContainsKey(property.Name.FirstLetterToLower()))
|
{
|
if (!sugarColumn.IsNullable)
|
{
|
if (sugarColumn.DefaultValue == null)
|
return sugarColumn.ColumnDescription + "为必须提交项";
|
continue;
|
}
|
continue;
|
}
|
if(dic[property.Name.FirstLetterToLower()] != null)
|
{
|
string str = dic[property.Name.FirstLetterToLower()].ToString();
|
//将所有空值设置为null
|
if (str == string.Empty)
|
dic[property.Name.FirstLetterToLower()] = null;
|
}
|
|
}
|
return string.Empty;
|
}
|
|
public static string ValidateDicInEntity(this Type typeinfo, List<Dictionary<string, object>> dicList, bool removerKey, string[] ignoreFields = null)
|
{
|
PropertyInfo[] propertyInfo = typeinfo.GetProperties();
|
string reslutMsg = string.Empty;
|
foreach (Dictionary<string, object> dic in dicList)
|
{
|
reslutMsg = typeinfo.ValidateDicInEntity(dic, removerKey, propertyInfo, ignoreFields);
|
if (!string.IsNullOrEmpty(reslutMsg))
|
return reslutMsg;
|
}
|
return reslutMsg;
|
}
|
|
public static string GetKeyName(this Type typeinfo)
|
{
|
return typeinfo.GetProperties().GetKeyName();
|
}
|
|
public static string GetKeyName(this PropertyInfo[] properties)
|
{
|
foreach (PropertyInfo property in properties)
|
{
|
SugarColumn sugarColumn = property.GetCustomAttribute<SugarColumn>();
|
if (sugarColumn.IsPrimaryKey)
|
return property.Name;
|
}
|
return null;
|
}
|
|
public static PropertyInfo GetKeyProperty(this Type typeinfo)
|
{
|
PropertyInfo[] properties = typeinfo.GetProperties();
|
foreach (PropertyInfo property in properties)
|
{
|
SugarColumn sugarColumn = property.GetCustomAttribute<SugarColumn>();
|
if (sugarColumn?.IsPrimaryKey ?? false)
|
{
|
return property;
|
}
|
}
|
return null;
|
}
|
|
public static Type GetDetailType(this Type typeinfo)
|
{
|
PropertyInfo[] properties = typeinfo.GetProperties();
|
foreach (PropertyInfo property in properties)
|
{
|
Navigate? navigate = property.GetCustomAttribute<Navigate>();
|
if (navigate is not null)
|
{
|
if (navigate.GetNavigateType() == NavigateType.OneToOne)
|
return property.PropertyType;
|
else
|
return property.PropertyType.GenericTypeArguments[0];
|
}
|
}
|
return null;
|
}
|
|
public static string GetMainIdByDetail(this Type typeinfo)
|
{
|
PropertyInfo[] properties = typeinfo.GetProperties();
|
foreach (PropertyInfo property in properties)
|
{
|
Navigate? navigate = property.GetCustomAttribute<Navigate>();
|
if (navigate is not null)
|
{
|
return navigate.GetName();
|
}
|
}
|
return null;
|
}
|
|
public static void SetDetailId<T>(this Type typeinfo, T enetiy, object id, string name)
|
{
|
PropertyInfo property = typeinfo.GetProperty(name);
|
if (property != null)
|
{
|
property.SetValue(enetiy, id);
|
}
|
}
|
|
public static PropertyInfo? GetNavigatePro(this Type typeinfo)
|
{
|
PropertyInfo[] properties = typeinfo.GetProperties();
|
foreach (PropertyInfo property in properties)
|
{
|
Navigate? navigate = property.GetCustomAttribute<Navigate>();
|
if (navigate is not null)
|
{
|
return property;
|
}
|
}
|
return null;
|
}
|
|
public static object GetPropertyValue<T>(this Type typeinfo, T data, string propertyName)
|
{
|
if (typeinfo != typeof(T))
|
return null;
|
|
PropertyInfo? property = typeinfo.GetProperty(propertyName);
|
if (property != null)
|
{
|
return property.GetValue(data);
|
}
|
return null;
|
}
|
}
|
}
|