diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs index c06b3d1c7c9c7e6a1689ff68cc24505c793d35ac..e929de1152153fe951dc22b314769ed1a2b6bc23 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs @@ -72,14 +72,14 @@ namespace SqlSugar.OceanBaseForOracle } } } - - public override string GetLimit() - { - return "AND ROWNUM=1"; - } } public partial class OceanBaseForOracleMethod : DefaultDbMethod, IDbMethods { + public override string IsNullOrEmpty(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NULL )", parameter.MemberName); + } public override string WeekOfYear(MethodCallExpressionModel mode) { var parameterNameA = mode.Args[0].MemberName; @@ -104,7 +104,14 @@ namespace SqlSugar.OceanBaseForOracle } public override string GetStringJoinSelector(string result, string separator) { - return $"listagg(to_char({result}),'{separator}') within group(order by {result}) "; + if (result.Contains(",")) + { + return $"listagg(to_char({result.Split(',').First()}),'{separator}') within group(order by {result.Split(',').Last()}) "; + } + else + { + return $"listagg(to_char({result}),'{separator}') within group(order by {result}) "; + } } public override string HasValue(MethodCallExpressionModel model) { @@ -211,8 +218,10 @@ namespace SqlSugar.OceanBaseForOracle return string.Format("(CAST(TO_CHAR({0},'mi') AS NUMBER))", parameter.MemberName); case DateType.Millisecond: return string.Format("(CAST(TO_CHAR({0},'ff3') AS NUMBER))", parameter.MemberName); + case DateType.Quarter: + return string.Format("(CAST(TO_CHAR({0},'q') AS NUMBER))", parameter.MemberName); case DateType.Weekday: - return $" to_char({parameter.MemberName},'day') "; + return $" (TO_NUMBER(TO_CHAR({parameter.MemberName}, 'D'))-1) "; case DateType.Day: default: return string.Format("(CAST(TO_CHAR({0},'dd') AS NUMBER))", parameter.MemberName); @@ -275,6 +284,7 @@ namespace SqlSugar.OceanBaseForOracle var parameter = model.Args[0]; return string.Format(" TO_TIMESTAMP({0}, 'YYYY-MM-DD HH24:MI:SS.FF') ", parameter.MemberName); } + public override string ToDateShort(MethodCallExpressionModel model) { var parameter = model.Args[0]; @@ -311,7 +321,47 @@ namespace SqlSugar.OceanBaseForOracle } public override string DateIsSameByType(MethodCallExpressionModel model) { - throw new NotSupportedException("Oracle NotSupportedException DateIsSameDay"); + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + + var dateType = parameter3.MemberValue.ObjToString().ToLower(); + var date1 = parameter.MemberName; + var date2 = parameter2.MemberName; + + if (dateType == "year") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}))", date1, date2); + } + else if (dateType == "month") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}) AND EXTRACT(MONTH FROM {0}) = EXTRACT(MONTH FROM {1}))", date1, date2); + } + else if (dateType == "day") + { + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } + else if (dateType == "hour") + { + return string.Format("(TRUNC({0}, 'HH24') = TRUNC({1}, 'HH24'))", date1, date2); + } + else if (dateType == "minute") + { + return string.Format("(TRUNC({0}, 'MI') = TRUNC({1}, 'MI'))", date1, date2); + } + else if (dateType == "second") + { + return string.Format("(TRUNC({0}, 'SS') = TRUNC({1}, 'SS'))", date1, date2); + } + else if (dateType == "week" || dateType == "weekday") + { + return string.Format("(TRUNC({0}, 'IW') = TRUNC({1}, 'IW'))", date1, date2); + } + else + { + // 默认按天比较 + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } } public override string Length(MethodCallExpressionModel model) { @@ -380,7 +430,28 @@ namespace SqlSugar.OceanBaseForOracle { var parameterNameA = mode.Args[0].MemberName; var parameterNameB = mode.Args[1].MemberName; - return $" SUBSTR({parameterNameA}, -2, {parameterNameB}) "; + return $" SUBSTR({parameterNameA}, (LENGTH({parameterNameA})-2), {parameterNameB}) "; + } + + public override string Ceil(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" CEIL({parameterNameA}) "; + } + + public override string NewUid(MethodCallExpressionModel mode) + { + return " SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 1, 8) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 9, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 13, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 17, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 21) "; + } + public override string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = "(" + string.Join(",", mode.Args[0].MemberValue as List) + ")"; + } + var searchWord = mode.Args[1].MemberName; + return $" CONTAINS({columns}, {searchWord}, 1) "; } } } diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs index feed531828cc3f55b69b99aa961d83a8cd263cd3..3849d93e9d7abf10d244548867952f1aa2b8a310 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs @@ -37,7 +37,7 @@ namespace SqlSugar.OceanBaseForOracle { var isFirst = pkList.First() == item; var whereString = isFirst ? " " : " AND "; - whereString += GetOracleUpdateColums(item); + whereString += GetOracleUpdateColums(item, true); whereList.Add(whereString); } return string.Format("{0} {1} WHERE {2};", updateTable, setValues, string.Join("", whereList)); @@ -46,9 +46,15 @@ namespace SqlSugar.OceanBaseForOracle return sb.ToString(); } - private string GetOracleUpdateColums(DbColumnInfo m) + private string GetOracleUpdateColums(DbColumnInfo m, bool isWhere = false) { - return string.Format("\"{0}\"={1} ", m.DbColumnName.ToUpper(IsUppper), base.GetDbColumn(m, FormatValue(m.Value, m.IsPrimarykey, m.PropertyName))); + + var result = string.Format("\"{0}\"={1} ", m.DbColumnName.ToUpper(IsUppper), base.GetDbColumn(m, FormatValue(m.Value, m.IsPrimarykey, m.PropertyName))); + if (isWhere && m.Value == null) + { + result = result.Replace("=NULL ", " is NULL "); + } + return result; } int i = 0; public object FormatValue(object value, bool isPrimaryKey, string name) diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/QueryableFormat.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/QueryableFormat.cs new file mode 100644 index 0000000000000000000000000000000000000000..8eab177ed6683c00eb8573734d2b060f63ba5268 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/QueryableFormat.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.OceanBaseForOracle +{ + internal class QueryableFormat + { + public Type Type { get; set; } + public string TypeString { get; set; } + public string Format { get; set; } + public string PropertyName { get; set; } + public string MethodName { get; set; } + public MethodInfo MethodInfo { get; set; } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs index a5225abf4e9975e23f327b114c4621c454a92c20..fa0445b87b69885e616e7fd51598f29511b6072c 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Dynamic; using System.Linq; +using System.Linq.Expressions; using System.Text; namespace SqlSugar.OceanBaseForOracle { @@ -10,17 +11,22 @@ namespace SqlSugar.OceanBaseForOracle public const string Dot = "."; public const char DotChar = '.'; internal const string Space = " "; - internal const char SpaceChar =' '; - internal const string AssemblyName = "SqlSugar"; - internal const string ReplaceKey = "{662E689B-17A1-4D06-9D27-F29EAB8BC3D6}"; + internal const char SpaceChar = ' '; + internal const string AssemblyName = "SqlSugar.OceanBaseForOracle"; + internal static string ReplaceKey = "{" + Guid.NewGuid() + "}"; internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + internal const string GroupReplaceKey = "{GroupReplaceKey_l33asdysaas1231s}"; + internal static Type UShortType = typeof(ushort); + internal static Type ULongType = typeof(ulong); + internal static Type UIntType = typeof(uint); internal static Type IntType = typeof(int); internal static Type LongType = typeof(long); internal static Type GuidType = typeof(Guid); internal static Type BoolType = typeof(bool); internal static Type BoolTypeNull = typeof(bool?); internal static Type ByteType = typeof(Byte); + internal static Type SByteType = typeof(sbyte); internal static Type ObjType = typeof(object); internal static Type DobType = typeof(double); internal static Type FloatType = typeof(float); @@ -31,7 +37,7 @@ namespace SqlSugar.OceanBaseForOracle internal static Type DateTimeOffsetType = typeof(DateTimeOffset); internal static Type TimeSpanType = typeof(TimeSpan); internal static Type ByteArrayType = typeof(byte[]); - internal static Type ModelType= typeof(ModelContext); + internal static Type ModelType = typeof(ModelContext); internal static Type DynamicType = typeof(ExpandoObject); internal static Type Dicii = typeof(KeyValuePair); internal static Type DicIS = typeof(KeyValuePair); @@ -42,6 +48,8 @@ namespace SqlSugar.OceanBaseForOracle internal static Type DicArraySS = typeof(Dictionary); internal static Type DicArraySO = typeof(Dictionary); + public static Type SqlConvertType = typeof(SqlSugar.DbConvert.NoParameterCommonPropertyConvert); + public static Type SugarType = typeof(SqlSugarProvider); @@ -56,7 +64,7 @@ namespace SqlSugar.OceanBaseForOracle typeof(short), typeof(ushort), }; - + //internal static CultureInfo EnCultureInfo = new CultureInfo("en"); internal static string[] DateTypeStringList = new string[] { @@ -69,5 +77,8 @@ namespace SqlSugar.OceanBaseForOracle "Millisecond", "Date" }; + + public static ConstantExpression ExpTrue = Expression.Constant(true); + public static ConstantExpression ExpFalse = Expression.Constant(false); } } diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs index feb4fb09d601786d9f58b4bd0b5aab423fd8d76f..624cd15911b6ad7f40f036ab9fbcce0ee1631a4a 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs @@ -1,9 +1,11 @@ using System; +using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Globalization; +using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -16,492 +18,1897 @@ namespace SqlSugar.OceanBaseForOracle { public class UtilMethods { - internal static DateTime GetMinDate(ConnectionConfig currentConnectionConfig) + public static string EscapeLikeValue(ISqlSugarClient db, string value, char wildcard = '%') { - if (currentConnectionConfig.MoreSettings == null) - { - return Convert.ToDateTime("1900-01-01"); - } - else if (currentConnectionConfig.MoreSettings.DbMinDate == null) + var dbType = db.CurrentConnectionConfig.DbType; + if (db.CurrentConnectionConfig?.MoreSettings?.DatabaseModel != null) { - return Convert.ToDateTime("1900-01-01"); + dbType = db.CurrentConnectionConfig.MoreSettings.DatabaseModel.Value; } - else + if (string.IsNullOrEmpty(value)) + return value; + + string wildcardStr = wildcard.ToString(); + + switch (dbType) { - return currentConnectionConfig.MoreSettings.DbMinDate.Value; + // 支持标准 SQL LIKE 转义,通常使用中括号 [] 或反斜杠 \ 进行转义 + case DbType.SqlServer: + case DbType.Access: + case DbType.Odbc: + case DbType.TDSQLForPGODBC: + // SQL Server 使用中括号转义 %, _ 等 + value = value.Replace("[", "[[]") + .Replace("]", "[]]") + .Replace(wildcardStr, $"[{wildcard}]"); + break; + + // PostgreSQL 风格数据库,使用反斜杠进行 LIKE 转义 + case DbType.PostgreSQL: + case DbType.OpenGauss: + case DbType.TDSQL: + case DbType.GaussDB: + case DbType.GaussDBNative: + // MySQL 和兼容库,使用反斜杠进行转义 + case DbType.MySql: + case DbType.MySqlConnector: + case DbType.Tidb: + case DbType.PolarDB: + case DbType.OceanBase: + case DbType.Oracle: + case DbType.OceanBaseForOracle: + case DbType.HG: + case DbType.Dm: + case DbType.GBase: + case DbType.DB2: + case DbType.HANA: + case DbType.GoldenDB: + case DbType.Sqlite: + case DbType.DuckDB: + case DbType.QuestDB: + case DbType.Doris: + case DbType.Xugu: + case DbType.Vastbase: + default: + value = value + .Replace(wildcardStr, "\\\\" + wildcard); + break; } + + return value; } - internal static DateTime ConvertFromDateTimeOffset(DateTimeOffset dateTime) + + + public static List CopySugarParameters(List pars) { - if (dateTime.Offset.Equals(TimeSpan.Zero)) - return dateTime.UtcDateTime; - else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) - return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local); - else - return dateTime.DateTime; + if (pars == null) return null; + var newParameters = pars.Select(it => new SugarParameter(it.ParameterName, it.Value) + { + TypeName = it.TypeName, + Value = it.Value, + IsRefCursor = it.IsRefCursor, + IsArray = it.IsArray, + IsJson = it.IsJson, + ParameterName = it.ParameterName, + IsNvarchar2 = it.IsNvarchar2, + IsNClob = it.IsClob, + IsClob = it.IsClob, + UdtTypeName = it.UdtTypeName, + CustomDbType = it.CustomDbType, + DbType = it.DbType, + Direction = it.Direction, + Precision = it.Precision, + Size = it.Size, + Scale = it.Scale, + IsNullable = it.IsNullable, + SourceColumn = it.SourceColumn, + SourceColumnNullMapping = it.SourceColumnNullMapping, + SourceVersion = it.SourceVersion, + TempDate = it.TempDate, + _Size = it._Size + }); + return newParameters.ToList(); } - - internal static object To(object value, Type destinationType) + public static bool IsTuple(Type tType, List classProperties) { - return To(value, destinationType, CultureInfo.InvariantCulture); + if (classProperties?.Any() != true) + { + return false; + } + return tType.FullName?.StartsWith("System.Tuple`") == true && classProperties.FirstOrDefault()?.Name == "Item1"; } - internal static object To(object value, Type destinationType, CultureInfo culture) + internal static string GetTableByDbLink(SqlSugarProvider context, string tableName, string oldTableName, TenantAttribute attr) { - if (value != null) + QueryBuilder queryBuilder = InstanceFactory.GetQueryBuilderWithContext(context); + var dbLinkName = context.Root.GetConnection(attr.configId).CurrentConnectionConfig.DbLinkName; + if (dbLinkName != null) { - destinationType = UtilMethods.GetUnderType(destinationType); - var sourceType = value.GetType(); + if (dbLinkName.First() == '@') + { + tableName = queryBuilder.Builder.GetTranslationColumnName(oldTableName) + dbLinkName; + } + else if (dbLinkName.Last() == '_') + { + tableName = dbLinkName + oldTableName; + } + else + { + tableName = dbLinkName + "." + queryBuilder.Builder.GetTranslationColumnName(oldTableName); + } + } + return tableName; + } + public static List> GetColumnInfo(IDataReader reader) + { + var columnInfo = new List>(); - var destinationConverter = TypeDescriptor.GetConverter(destinationType); - if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) - return destinationConverter.ConvertFrom(null, culture, value); + // 获取列的数量 + int columnCount = reader.FieldCount; - var sourceConverter = TypeDescriptor.GetConverter(sourceType); - if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType)) - return sourceConverter.ConvertTo(null, culture, value, destinationType); + // 遍历每一列 + for (int i = 0; i < columnCount; i++) + { + // 获取列名 + string columnName = reader.GetName(i); - if (destinationType.IsEnum && value is int) - return Enum.ToObject(destinationType, (int)value); + // 获取列的数据类型 + Type columnType = reader.GetFieldType(i); - if (!destinationType.IsInstanceOfType(value)) - return Convert.ChangeType(value, destinationType, culture); + // 将列名和类型添加到列表中 + columnInfo.Add(Tuple.Create(columnName, columnType)); } - return value; + + return columnInfo; } - public static bool IsAnyAsyncMethod(StackFrame[] methods) + public static object ConvertToObjectList(Type targetType, List sourceList) { - bool isAsync = false; - foreach (var item in methods) + // 创建 List 类型的实例 + object resultList = Activator.CreateInstance(typeof(List<>).MakeGenericType(targetType)); + // 获取 Add 方法 + var addMethod = resultList.GetType().GetMethod("Add"); + foreach (var obj in sourceList) { - if (UtilMethods.IsAsyncMethod(item.GetMethod())) - { - isAsync = true; - break; - } + addMethod.Invoke(resultList, new object[] { obj }); } - return isAsync; + return resultList; } - - public static bool IsAsyncMethod(MethodBase method) + public static Dictionary DataRowToDictionary(DataRow row) { - if (method == null) - { - return false; - } - if (method.DeclaringType != null) + Dictionary dictionary = new Dictionary(); + + // 遍历所有列并将其添加到字典中 + foreach (DataColumn column in row.Table.Columns) { - if (method.DeclaringType.GetInterfaces().Contains(typeof(IAsyncStateMachine))) + if (column.ColumnName != "Items" && column.DataType.Name.IsCollectionsList() == false) { - return true; + dictionary.Add(column.ColumnName, row[column]); } } - var name = method.Name; - if (name.Contains("OutputAsyncCausalityEvents")) - { - return true; - } - if (name.Contains("OutputWaitEtwEvents")) - { - return true; - } - if (name.Contains("ExecuteAsync")) - { - return true; - } - Type attType = typeof(AsyncStateMachineAttribute); - var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType); - return (attrib != null); - } - public static StackTraceInfo GetStackTrace() + return dictionary; + } + public static IEnumerable BuildTree(ISqlSugarClient db, IEnumerable list, string idName, string pIdName, string childName, object rootValue) { + var entityInfo = db.EntityMaintenance.GetEntityInfo(); ; + var mainIdProp = entityInfo.Type.GetProperty(idName); + var pIdProp = entityInfo.Type.GetProperty(pIdName); + var childProp = entityInfo.Type.GetProperty(childName); - StackTrace st = new StackTrace(true); - StackTraceInfo info = new StackTraceInfo(); - info.MyStackTraceList = new List(); - info.SugarStackTraceList = new List(); - for (int i = 0; i < st.FrameCount; i++) + Dictionary kvList; + IEnumerable> group; + BuildTreeGroup(list, mainIdProp, pIdProp, out kvList, out group); + + var root = rootValue != null ? group.FirstOrDefault(x => x.Key == rootValue.ObjToString()) : group.FirstOrDefault(x => x.Key == null || x.Key == "" || x.Key == "0" || x.Key == Guid.Empty.ToString()); + + if (root != null) { - var frame = st.GetFrame(i); - if (frame.GetMethod().Module.Name.ToLower() != "sqlsugar.dll" && frame.GetMethod().Name.First() != '<') - { - info.MyStackTraceList.Add(new StackTraceInfoItem() - { - FileName = frame.GetFileName(), - MethodName = frame.GetMethod().Name, - Line = frame.GetFileLineNumber() - }); - } - else + foreach (var item in group) { - info.SugarStackTraceList.Add(new StackTraceInfoItem() + if (kvList.TryGetValue(item.Key, out var parent)) { - FileName = frame.GetFileName(), - MethodName = frame.GetMethod().Name, - Line = frame.GetFileLineNumber() - }); + childProp.SetValue(parent, item.ToList()); + } } } - return info; + + return root; } - internal static T To(object value) + private static void BuildTreeGroup(IEnumerable list, PropertyInfo mainIdProp, PropertyInfo pIdProp, out Dictionary kvList, out IEnumerable> group) { - return (T)To(value, typeof(T)); + kvList = list.ToDictionary(x => mainIdProp.GetValue(x).ObjToString()); + group = list.GroupBy(x => pIdProp.GetValue(x).ObjToString()); } - internal static Type GetUnderType(Type oldType) + + internal static bool? _IsErrorDecimalString { get; set; } + internal static bool? IsErrorDecimalString() { - Type type = Nullable.GetUnderlyingType(oldType); - return type == null ? oldType : type; + if (_IsErrorDecimalString == null) + { + decimal dec = Convert.ToDecimal(1.1); + _IsErrorDecimalString = dec.ToString().Contains(","); + } + return _IsErrorDecimalString; } - public static string ReplaceSqlParameter(string itemSql, SugarParameter itemParameter, string newName) + internal static bool IsParameterConverter(EntityColumnInfo columnInfo) { - itemSql = Regex.Replace(itemSql, string.Format(@"{0} ", "\\" + itemParameter.ParameterName), newName + " ", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"{0}\)", "\\" + itemParameter.ParameterName), newName + ")", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"{0}\,", "\\" + itemParameter.ParameterName), newName + ",", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"{0}$", "\\" + itemParameter.ParameterName), newName, RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"\+{0}\+", "\\" + itemParameter.ParameterName), "+" + newName + "+", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"\+{0} ", "\\" + itemParameter.ParameterName), "+" + newName + " ", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@" {0}\+", "\\" + itemParameter.ParameterName), " " + newName + "+", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"\|\|{0}\|\|", "\\" + itemParameter.ParameterName), "||" + newName + "||", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"\={0}\+", "\\" + itemParameter.ParameterName), "=" + newName + "+", RegexOptions.IgnoreCase); - itemSql = Regex.Replace(itemSql, string.Format(@"{0}\|\|", "\\" + itemParameter.ParameterName), newName + "||", RegexOptions.IgnoreCase); - return itemSql; + return columnInfo != null && columnInfo.SqlParameterDbType != null && columnInfo.SqlParameterDbType is Type + && typeof(ISugarDataConverter).IsAssignableFrom(columnInfo.SqlParameterDbType as Type); } - internal static Type GetRootBaseType(Type entityType) + internal static SugarParameter GetParameterConverter(int index, ISqlSugarClient db, object value, Expression oppoSiteExpression, EntityColumnInfo columnInfo) { - var baseType = entityType.BaseType; - while (baseType != null && baseType.BaseType != UtilConstants.ObjType) - { - baseType = baseType.BaseType; - } - return baseType; + var entity = db.EntityMaintenance.GetEntityInfo(oppoSiteExpression.Type); + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; + return p; } - - - internal static Type GetUnderType(PropertyInfo propertyInfo, ref bool isNullable) + internal static SugarParameter GetParameterConverter(int index, ISqlSugarClient db, object value, EntityInfo entity, EntityColumnInfo columnInfo) { - Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); - isNullable = unType != null; - unType = unType ?? propertyInfo.PropertyType; - return unType; + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; + return p; } - - internal static Type GetUnderType(PropertyInfo propertyInfo) + internal static object QueryConverter(int index, ISqlSugarClient db, IDataReader dataReader, EntityInfo entity, EntityColumnInfo columnInfo) { - Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); - unType = unType ?? propertyInfo.PropertyType; - return unType; + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("QueryConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { dataReader, index }); + return p; } - - internal static bool IsNullable(PropertyInfo propertyInfo) + internal static bool IsErrorParameterName(ConnectionConfig connectionConfig, DbColumnInfo columnInfo) { - Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); - return unType != null; + return connectionConfig.MoreSettings?.IsCorrectErrorSqlParameterName == true && + columnInfo.DbColumnName.IsContainsIn("-", " ", ".", "(", ")", "(", ")"); } - internal static bool IsNullable(Type type) + public static bool StringCheckFirstAndLast(string withString, string first, string last) { - Type unType = Nullable.GetUnderlyingType(type); - return unType != null; + return withString.StartsWith(first) && withString.EndsWith(last); } - //internal static T IsNullReturnNew(T returnObj) where T : new() - //{ - // if (returnObj.IsNullOrEmpty()) - // { - // returnObj = new T(); - // } - // return returnObj; - //} - public static object ChangeType2(object value, Type type) + public static bool HasInterface(Type targetType, Type interfaceType) { - if (value == null && type.IsGenericType) return Activator.CreateInstance(type); - if (value == null) return null; - if (type == value.GetType()) return value; - if (type.IsEnum) + if (targetType == null || interfaceType == null || !interfaceType.IsInterface) { - if (value is string) - return Enum.Parse(type, value as string); - else - return Enum.ToObject(type, value); + return false; } - if (!type.IsInterface && type.IsGenericType) + + return interfaceType.IsAssignableFrom(targetType); + } + public static void ClearPublicProperties(T obj, EntityInfo entity) + { + if (obj == null) { - Type innerType = type.GetGenericArguments()[0]; - object innerValue = ChangeType(value, innerType); - return Activator.CreateInstance(type, new object[] { innerValue }); + throw new ArgumentNullException(nameof(obj)); } - if (value is string && type == typeof(Guid)) return new Guid(value as string); - if (value is string && type == typeof(Version)) return new Version(value as string); - if (!(value is IConvertible)) return value; - return Convert.ChangeType(value, type); - } - internal static T ChangeType(T obj, Type type) - { - return (T)Convert.ChangeType(obj, type); - } + Type type = typeof(T); - internal static T ChangeType(T obj) - { - return (T)Convert.ChangeType(obj, typeof(T)); + foreach (var column in entity.Columns) + { + if (column.PropertyInfo.CanWrite && column.PropertyInfo.GetSetMethod() != null) + { + Type propertyType = column.PropertyInfo.PropertyType; + object defaultValue = propertyType.IsValueType ? Activator.CreateInstance(propertyType) : null; + column.PropertyInfo.SetValue(obj, defaultValue); + } + } } - internal static DateTimeOffset GetDateTimeOffsetByDateTime(DateTime date) + internal static Expression GetIncludeExpression(string navMemberName, EntityInfo entityInfo, out Type properyItemType, out bool isList) { - date = DateTime.SpecifyKind(date, DateTimeKind.Utc); - DateTimeOffset utcTime2 = date; - return utcTime2; + var navInfo = entityInfo.Columns.Where(it => it.Navigat != null && it.PropertyName.EqualCase(navMemberName)).FirstOrDefault(); + var properyType = navInfo.PropertyInfo.PropertyType; + properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + isList = true; + } + else + { + isList = false; + } + return ExpressionBuilderHelper.CreateExpressionSelectField(entityInfo.Type, navInfo.PropertyName, properyType); } - - //internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) - //{ - // if (appendSql.HasValue() && parameters.HasValue()) - // { - // foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) - // { - // //Compatible with.NET CORE parameters case - // var name = parameter.ParameterName; - // string newName = name + append + addIndex; - // appendSql = ReplaceSqlParameter(appendSql, parameter, newName); - // parameter.ParameterName = newName; - // } - // } - //} - - internal static string GetPackTable(string sql, string shortName) + public static string RemoveEqualOne(string value) { - return string.Format(" ({0}) {1} ", sql, shortName); + value = value.TrimEnd(' ').TrimEnd('1').TrimEnd('='); + return value; } - - public static Func GetTypeConvert(object value) + /// + /// Available only in Select,Handles logic that cannot be completed by an expression + /// + /// + /// + /// + internal static object GetFormatValue(object addValue, QueryableFormat valueFomatInfo) { - if (value is int || value is uint || value is int? || value is uint?) + if (valueFomatInfo.MethodName == "ToString") { - return x => Convert.ToInt32(x); + if (valueFomatInfo.Type == UtilConstants.GuidType) + { + addValue = Guid.Parse(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.ByteType) + { + addValue = Convert.ToByte(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.IntType) + { + addValue = Convert.ToInt32(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.LongType) + { + addValue = Convert.ToInt64(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.UIntType) + { + addValue = Convert.ToUInt32(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.ULongType) + { + addValue = Convert.ToUInt64(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.DecType) + { + addValue = Convert.ToDecimal(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.DobType) + { + addValue = Convert.ToDouble(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.TypeString == "Enum") + { + addValue = ChangeType2(addValue, valueFomatInfo.Type)?.ToString(); + } } - else if (value is short || value is ushort || value is short? || value is ushort?) + else if (valueFomatInfo.MethodName == "OnlyInSelectConvertToString") { - return x => Convert.ToInt16(x); + + var methodInfo = valueFomatInfo.MethodInfo; + if (methodInfo != null) + { + // 如果方法是静态的,传递null作为第一个参数,否则传递类的实例 + object instance = methodInfo.IsStatic ? null : Activator.CreateInstance(methodInfo.ReflectedType); + + // 创建一个包含参数值的object数组 + object[] parameters = new object[] { addValue }; + + // 调用方法 + addValue = methodInfo.Invoke(instance, parameters); + } } - else if (value is long || value is long? || value is ulong? || value is long?) + return addValue; + } + public static int CountSubstringOccurrences(string mainString, string searchString) + { + string[] substrings = mainString.Split(new string[] { searchString }, StringSplitOptions.None); + return substrings.Length - 1; + } + public static string RemoveBeforeFirstWhere(string query) + { + int whereIndex = query.IndexOf("WHERE", StringComparison.OrdinalIgnoreCase); + if (whereIndex >= 0) { - return x => Convert.ToInt64(x); + return query.Substring(whereIndex + "WHERE".Length); } - else if (value is DateTime|| value is DateTime?) + else { - return x => Convert.ToDateTime(x); + return query; } - else if (value is bool||value is bool?) + } + public static List ConvertToListOfObjects(object inValues) + { + // 创建一个新的List并逐个将元素转换并添加到其中 + List resultList = new List(); + foreach (var item in (IEnumerable)inValues) { - return x => Convert.ToBoolean(x); + resultList.Add(item); } - return null; - } - internal static string GetTypeName(object value) + return resultList; + } + public static bool IsValueTypeArray(object memberValue) { - if (value == null) + return memberValue is List || + memberValue is string[] || + memberValue is List || + memberValue is int[] || + memberValue is List || + memberValue is Guid[] || + memberValue is List || + memberValue is long[] || + memberValue is List || + memberValue is int?[] || + memberValue is List || + memberValue is Guid?[] || + memberValue is List || + memberValue is long?[] || + memberValue is List || + memberValue is float[] || + memberValue is List || + memberValue is double[] || + memberValue is List || + memberValue is decimal[] || + memberValue is List || + memberValue is DateTime[] || + memberValue is List || + memberValue is TimeSpan[] || + memberValue is List || + memberValue is bool[] || + memberValue is List || + memberValue is byte[] || + memberValue is List || + memberValue is char[] || + memberValue is List || + memberValue is short[] || + memberValue is List || + memberValue is ushort[] || + memberValue is List || + memberValue is uint[] || + memberValue is List || + memberValue is ulong[] || + memberValue is List || + memberValue is sbyte[] || + memberValue is List || + memberValue is object[] || + memberValue is List || + memberValue is int?[] || + memberValue is List || + memberValue is Guid?[] || + memberValue is List || + memberValue is long?[]; + } + internal static void EndCustomSplitTable(ISqlSugarClient context, Type entityType) + { + if (context == null || entityType == null) { - return null; + return; } - else + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute == null) { - return value.GetType().Name; + return; + } + if (splitTableAttribute.CustomSplitTableService != null) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = null; } } - internal static string GetParenthesesValue(string dbTypeName) + internal static void StartCustomSplitTable(ISqlSugarClient context, Type entityType) { - if (Regex.IsMatch(dbTypeName, @"\(.+\)")) + if (context == null || entityType == null) { - dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", ""); + return; + } + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute == null) + { + return; + } + if (splitTableAttribute.CustomSplitTableService != null) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService + = (ISplitTableService)Activator.CreateInstance(splitTableAttribute.CustomSplitTableService); + } + if ( + context?.CurrentConnectionConfig?.ConfigureExternalServices?.SplitTableService != null + && splitTableAttribute.CustomSplitTableService == null + && context.EntityMaintenance.GetEntityInfo(entityType).DbTableName?.EndsWith("_{year}{month}{day}") == true + && !context.EntityMaintenance.GetEntityInfo(entityType).DbTableName?.Replace("_{year}{month}{day}", "")?.Contains("{") == true + ) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService + = null; } - dbTypeName = dbTypeName.Trim(); - return dbTypeName; } - - internal static T GetOldValue(T value, Action action) + public static void ConvertParameter(SugarParameter p, ISqlBuilder builder) { - action(); - return value; + if (!p.ParameterName.StartsWith(builder.SqlParameterKeyWord)) + { + p.ParameterName = (builder.SqlParameterKeyWord + p.ParameterName.TrimStart('@')); + } } - - internal static object DefaultForType(Type targetType) + public static object SetAnonymousObjectPropertyValue(object obj, string propertyName, object propertyValue) { - return targetType.IsValueType ? Activator.CreateInstance(targetType) : null; + if (obj.GetType().IsAnonymousType()) // 判断是否为匿名对象 + { + var objType = obj.GetType(); + var objFields = objType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); + foreach (var field in objFields) // 遍历字段列表,查找需要修改的属性 + { + if (field.Name == $"<{propertyName}>i__Field") + { + field.SetValue(obj, propertyValue); // 使用反射修改属性值 + break; + } + } + } + else + { + obj.GetType().GetProperty(propertyName).SetValue(obj, propertyValue); + } + return obj; } - internal static Int64 GetLong(byte[] bytes) + internal static bool IsNumberArray(Type type) { - return Convert.ToInt64(string.Join("", bytes).PadRight(20, '0')); + + return type.IsIn(typeof(int[]), + typeof(long[]), + typeof(short[]), + typeof(uint[]), + typeof(ulong[]), + typeof(ushort[]), + typeof(int?[]), + typeof(long?[]), + typeof(short?[]), + typeof(uint?[]), + typeof(ulong?[]), + typeof(ushort?[]), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List)); } - public static object GetPropertyValue(T t, string PropertyName) + public static string GetNativeSql(string sql, SugarParameter[] pars) { - return t.GetType().GetProperty(PropertyName).GetValue(t, null); + if (pars == null || pars.Length == 0) + return "\r\n[Sql]:" + sql + "\r\n"; + return $"\r\n[Sql]:{sql} \r\n[Pars]:{string.Join(" ", pars.Select(it => $"\r\n[Name]:{it.ParameterName} [Value]:{it.Value} [Type]:{it.DbType} {(it.IsNvarchar2 ? "nvarchar2" : "")} "))} \r\n"; } - internal static string GetMD5(string myString) + public static string ToUnderLine(string str, bool isToUpper = false) { - MD5 md5 = new MD5CryptoServiceProvider(); - byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString); - byte[] targetData = md5.ComputeHash(fromData); - string byte2String = null; - - for (int i = 0; i < targetData.Length; i++) + if (str == null || str.Contains("_")) { - byte2String += targetData[i].ToString("x"); + return str; } - - return byte2String; + else if (isToUpper) + { + return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToUpper(); + } + else + { + return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); + } + } + internal static bool IsArrayMember(Expression expression, SqlSugarProvider context) + { + if (expression == null) + return false; + if (!(expression is LambdaExpression)) + return false; + var lambda = (LambdaExpression)expression; + if (!(lambda.Body is MemberExpression)) + return false; + var member = lambda.Body as MemberExpression; + if (!(member.Type.IsClass())) + return false; + if (member.Expression == null) + return false; + var entity = context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var json = entity.Columns.FirstOrDefault(z => z.IsArray && z.PropertyName == member.Member.Name); + return json != null; + } + internal static bool IsJsonMember(Expression expression, SqlSugarProvider context) + { + if (expression == null) + return false; + if (!(expression is LambdaExpression)) + return false; + var lambda = (LambdaExpression)expression; + if (!(lambda.Body is MemberExpression)) + return false; + var member = lambda.Body as MemberExpression; + if (!(member.Type.IsClass())) + return false; + if (member.Expression == null) + return false; + var entity = context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var json = entity.Columns.FirstOrDefault(z => z.IsJson && z.PropertyName == member.Member.Name); + return json != null; + } + public static string GetSeparatorChar() + { + return Path.Combine("a", "a").Replace("a", ""); + } + public static bool IsParentheses(object name) + { + return name.ObjToString().Trim().Last() == ')' && name.ObjToString().Trim().First() == '('; } - //public static string EncodeBase64(string code) - //{ - // if (code.IsNullOrEmpty()) return code; - // string encode = ""; - // byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(code); - // try - // { - // encode = Convert.ToBase64String(bytes); - // } - // catch - // { - // encode = code; - // } - // return encode; - //} - public static string ConvertNumbersToString(string value) + internal static bool IsDefaultValue(object value) { - string[] splitInt = value.Split(new char[] { '9' }, StringSplitOptions.RemoveEmptyEntries); + if (value == null) return true; + return value.Equals(UtilMethods.GetDefaultValue(value.GetType())); + } - var splitChars = splitInt.Select(s => Convert.ToChar( - Convert.ToInt32(s, 8) - ).ToString()); + internal static DateTime ConvertFromDateTimeOffset(DateTimeOffset dateTime) + { + if (dateTime.Offset.Equals(TimeSpan.Zero)) + return dateTime.UtcDateTime; + else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) + return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local); + else + return dateTime.DateTime; + } - return string.Join("", splitChars); + internal static object To(object value, Type destinationType) + { + return To(value, destinationType, CultureInfo.InvariantCulture); } - public static string ConvertStringToNumbers(string value) + + internal static object To(object value, Type destinationType, CultureInfo culture) { - StringBuilder sb = new StringBuilder(); + if (value != null) + { + destinationType = UtilMethods.GetUnderType(destinationType); + var sourceType = value.GetType(); + if (destinationType.Name == "DateOnly" && sourceType == typeof(string)) + { + var type = Type.GetType("System.DateOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromDateTime"); + return method.Invoke(null, new object[] { Convert.ToDateTime(value) }); + } + else if (destinationType.FullName == "System.Ulid") + { + var method = destinationType.GetMyMethod("Parse", 1); + if (method != null) + { + var result = method.Invoke(null, new object[] { value }); + return result; + } + } + else if (value is byte[] bytes && bytes.Length == 1 && destinationType == typeof(char)) + { + return (char)(bytes)[0]; + } + else if (value is DateTime && destinationType == typeof(TimeSpan)) + { + value = Convert.ToDateTime(value).TimeOfDay; + } + else if (value is DateTime && destinationType.FullName == "System.TimeOnly") + { + value = Convert.ToDateTime(value).TimeOfDay; + } + var destinationConverter = TypeDescriptor.GetConverter(destinationType); + if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) + return destinationConverter.ConvertFrom(null, culture, value); - foreach (char c in value) + var sourceConverter = TypeDescriptor.GetConverter(sourceType); + if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType)) + return sourceConverter.ConvertTo(null, culture, value, destinationType); + + if (destinationType.IsEnum && value is int) + return Enum.ToObject(destinationType, (int)value); + + if (destinationType.Name == "TimeOnly" && sourceType.Name != "TimeOnly") + { + var type = Type.GetType("System.TimeOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromTimeSpan"); + return method.Invoke(null, new object[] { value }); + } + if (destinationType.Name == "DateOnly" && sourceType.Name != "DateOnly") + { + var type = Type.GetType("System.DateOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromDateTime"); + return method.Invoke(null, new object[] { value }); + } + + if (!destinationType.IsInstanceOfType(value)) + return Convert.ChangeType(value, destinationType, culture); + } + return value; + } + public static bool IsAnyAsyncMethod(StackFrame[] methods) + { + bool isAsync = false; + foreach (var item in methods) { - int cAscil = (int)c; - sb.Append(Convert.ToString(c, 8) + "9"); + if (UtilMethods.IsAsyncMethod(item.GetMethod())) + { + isAsync = true; + break; + } } + return isAsync; + } - return sb.ToString(); + + public static ConnectionConfig CopyConfig(ConnectionConfig it) + { + return new ConnectionConfig() + { + AopEvents = it.AopEvents == null ? null : new AopEvents() + { + DataExecuting = it.AopEvents?.DataExecuting, + OnDiffLogEvent = it.AopEvents?.OnDiffLogEvent, + OnError = it.AopEvents?.OnError, + OnExecutingChangeSql = it.AopEvents?.OnExecutingChangeSql, + OnLogExecuted = it.AopEvents?.OnLogExecuted, + OnLogExecuting = it.AopEvents?.OnLogExecuting, + DataExecuted = it.AopEvents?.DataExecuted, + CheckConnectionExecuted = it.AopEvents?.CheckConnectionExecuted, + CheckConnectionExecuting = it.AopEvents?.CheckConnectionExecuting, + OnGetDataReadered = it.AopEvents?.OnGetDataReadered, + OnGetDataReadering = it.AopEvents?.OnGetDataReadering, + }, + ConfigId = it.ConfigId, + ConfigureExternalServices = it.ConfigureExternalServices == null ? null : new ConfigureExternalServices() + { + AppendDataReaderTypeMappings = it.ConfigureExternalServices.AppendDataReaderTypeMappings, + DataInfoCacheService = it.ConfigureExternalServices.DataInfoCacheService, + EntityNameService = it.ConfigureExternalServices.EntityNameService, + EntityService = it.ConfigureExternalServices.EntityService, + RazorService = it.ConfigureExternalServices.RazorService, + ReflectionInoCacheService = it.ConfigureExternalServices.ReflectionInoCacheService, + SerializeService = it.ConfigureExternalServices.SerializeService, + SplitTableService = it.ConfigureExternalServices.SplitTableService, + SqlFuncServices = it.ConfigureExternalServices.SqlFuncServices + }, + ConnectionString = it.ConnectionString, + DbType = it.DbType, + DbLinkName = it.DbLinkName, + IndexSuffix = it.IndexSuffix, + InitKeyType = it.InitKeyType, + IsAutoCloseConnection = it.IsAutoCloseConnection, + LanguageType = it.LanguageType, + MoreSettings = it.MoreSettings == null ? null : new ConnMoreSettings() + { + DefaultCacheDurationInSeconds = it.MoreSettings.DefaultCacheDurationInSeconds, + DisableNvarchar = it.MoreSettings.DisableNvarchar, + PgSqlIsAutoToLower = it.MoreSettings.PgSqlIsAutoToLower, + PgSqlIsAutoToLowerCodeFirst = it.MoreSettings.PgSqlIsAutoToLowerCodeFirst, + IsAutoRemoveDataCache = it.MoreSettings.IsAutoRemoveDataCache, + IsWithNoLockQuery = it.MoreSettings.IsWithNoLockQuery, + DisableWithNoLockWithTran = it.MoreSettings.DisableWithNoLockWithTran, + TableEnumIsString = it.MoreSettings.TableEnumIsString, + DisableMillisecond = it.MoreSettings.DisableMillisecond, + DbMinDate = it.MoreSettings.DbMinDate, + IsNoReadXmlDescription = it.MoreSettings.IsNoReadXmlDescription, + SqlServerCodeFirstNvarchar = it.MoreSettings.SqlServerCodeFirstNvarchar, + OracleCodeFirstNvarchar2 = it.MoreSettings.OracleCodeFirstNvarchar2, + IsAutoToUpper = it.MoreSettings.IsAutoToUpper, + IsAutoDeleteQueryFilter = it.MoreSettings.IsAutoDeleteQueryFilter, + IsAutoUpdateQueryFilter = it.MoreSettings.IsAutoUpdateQueryFilter, + EnableModelFuncMappingColumn = it.MoreSettings.EnableModelFuncMappingColumn, + EnableOracleIdentity = it.MoreSettings.EnableOracleIdentity, + IsWithNoLockSubquery = it.MoreSettings.IsWithNoLockSubquery, + EnableCodeFirstUpdatePrecision = it.MoreSettings.EnableCodeFirstUpdatePrecision, + SqliteCodeFirstEnableDefaultValue = it.MoreSettings.SqliteCodeFirstEnableDefaultValue, + SqliteCodeFirstEnableDescription = it.MoreSettings.SqliteCodeFirstEnableDescription, + IsCorrectErrorSqlParameterName = it.MoreSettings.IsCorrectErrorSqlParameterName, + SqliteCodeFirstEnableDropColumn = it.MoreSettings.SqliteCodeFirstEnableDropColumn, + MaxParameterNameLength = it.MoreSettings.MaxParameterNameLength, + DisableQueryWhereColumnRemoveTrim = it.MoreSettings.DisableQueryWhereColumnRemoveTrim, + DatabaseModel = it.MoreSettings.DatabaseModel, + EnableILike = it.MoreSettings.EnableILike, + ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal, + PgSqlIsAutoToLowerSchema = it.MoreSettings.PgSqlIsAutoToLowerSchema + + }, + SqlMiddle = it.SqlMiddle == null ? null : new SqlMiddle + { + IsSqlMiddle = it.SqlMiddle.IsSqlMiddle, + ExecuteCommand = it.SqlMiddle.ExecuteCommand, + ExecuteCommandAsync = it.SqlMiddle.ExecuteCommandAsync, + GetDataReader = it.SqlMiddle.GetDataReader, + GetDataReaderAsync = it.SqlMiddle.GetDataReaderAsync, + GetDataSetAll = it.SqlMiddle.GetDataSetAll, + GetDataSetAllAsync = it.SqlMiddle.GetDataSetAllAsync, + GetScalar = it.SqlMiddle.GetScalar, + GetScalarAsync = it.SqlMiddle.GetScalarAsync + }, + SlaveConnectionConfigs = it.SlaveConnectionConfigs + }; } - //public static string DecodeBase64(string code) - //{ - // try - // { - // if (code.IsNullOrEmpty()) return code; - // string decode = ""; - // byte[] bytes = Convert.FromBase64String(code); - // try - // { - // decode = Encoding.GetEncoding("utf-8").GetString(bytes); - // } - // catch - // { - // decode = code; - // } - // return decode; - // } - // catch - // { - // return code; - // } - //} + internal static object GetRandomByType(Type underType) + { + if (underType == UtilConstants.GuidType) + { + return Guid.NewGuid(); + } + else if (underType == UtilConstants.LongType) + { + return SnowFlakeSingle.Instance.NextId(); + } + else if (underType == UtilConstants.StringType) + { + return Guid.NewGuid() + ""; + } + else if (underType == UtilConstants.DateType) + { + return System.DateTime.Now; + } + else + { + return Guid.NewGuid() + ""; + } + } - public static void DataInoveByExpresson(Type[] datas, MethodCallExpression callExpresion) + public static bool IsAsyncMethod(MethodBase method) { - var methodInfo = callExpresion.Method; - foreach (var item in datas) + if (method == null) + { + return false; + } + if (method.DeclaringType != null) + { + if (method.DeclaringType.GetInterfaces().Contains(typeof(IAsyncStateMachine))) + { + return true; + } + } + var name = method.Name; + if (name.Contains("OutputAsyncCausalityEvents")) + { + return true; + } + if (name.Contains("OutputWaitEtwEvents")) { - if (callExpresion.Arguments.Count == 0) + return true; + } + if (name.Contains("ExecuteAsync")) + { + return true; + } + //if (method?.DeclaringType?.FullName?.Contains("Furion.InternalApp")==true) + //{ + // return false; + //} + Type attType = typeof(AsyncStateMachineAttribute); + var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType); + return (attrib != null); + } + + public static StackTraceInfo GetStackTrace() + { + + StackTrace st = new StackTrace(true); + StackTraceInfo info = new StackTraceInfo(); + info.MyStackTraceList = new List(); + info.SugarStackTraceList = new List(); + for (int i = 0; i < st.FrameCount; i++) + { + var frame = st.GetFrame(i); + if (frame.GetMethod().Module.Name.ToLower() != "sqlsugar.dll" && frame.GetMethod().Name.First() != '<') { - methodInfo.Invoke(item, null); + info.MyStackTraceList.Add(new StackTraceInfoItem() + { + FileName = frame.GetFileName(), + MethodName = frame.GetMethod().Name, + Line = frame.GetFileLineNumber() + }); } else { - List methodParameters = new List(); - foreach (var callItem in callExpresion.Arguments) + info.SugarStackTraceList.Add(new StackTraceInfoItem() { - var parameter = callItem.GetType().GetProperties().FirstOrDefault(it => it.Name == "Value"); - if (parameter == null) - { - var value = LambdaExpression.Lambda(callItem).Compile().DynamicInvoke(); - methodParameters.Add(value); - } - else - { - var value = parameter.GetValue(callItem, null); - methodParameters.Add(value); - } - } - methodInfo.Invoke(item, methodParameters.ToArray()); + FileName = frame.GetFileName(), + MethodName = frame.GetMethod().Name, + Line = frame.GetFileLineNumber() + }); } } + return info; } - public static Dictionary EnumToDictionary() + internal static object GetConvertValue(object entityValue) { - Dictionary dic = new Dictionary(); - if (!typeof(T).IsEnum) + if (entityValue != null && entityValue is DateTime) { - return dic; + entityValue = entityValue.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff"); } - string desc = string.Empty; - foreach (var item in Enum.GetValues(typeof(T))) + return entityValue; + } + + internal static T To(object value) + { + return (T)To(value, typeof(T)); + } + + internal static DateTime GetMinDate(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.MoreSettings == null) { - var key = item.ToString().ToLower(); - if (!dic.ContainsKey(key)) - dic.Add(key, (T)item); + return Convert.ToDateTime("1900-01-01"); } - return dic; + else if (currentConnectionConfig.MoreSettings.DbMinDate == null) + { + return Convert.ToDateTime("1900-01-01"); + } + else + { + return currentConnectionConfig.MoreSettings.DbMinDate.Value; + } + } + + public static Type GetUnderType(Type oldType) + { + Type type = Nullable.GetUnderlyingType(oldType); + return type == null ? oldType : type; + } + public static object GetDefaultValue(Type type) + { + return type.IsValueType ? Activator.CreateInstance(type) : null; + } + public static string ReplaceFirstMatch(string input, string pattern, string replacement) + { + Regex regex = new Regex(pattern); + return regex.Replace(input, replacement, 1); + } + public static string ReplaceSqlParameter(string itemSql, SugarParameter itemParameter, string newName) + { + itemSql = Regex.Replace(itemSql, string.Format(@"{0} ", "\\" + itemParameter.ParameterName), newName + " ", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\)", "\\" + itemParameter.ParameterName), newName + ")", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\,", "\\" + itemParameter.ParameterName), newName + ",", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}$", "\\" + itemParameter.ParameterName), newName, RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\+{0}\+", "\\" + itemParameter.ParameterName), "+" + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\+{0} ", "\\" + itemParameter.ParameterName), "+" + newName + " ", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@" {0}\+", "\\" + itemParameter.ParameterName), " " + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\|\|{0}\|\|", "\\" + itemParameter.ParameterName), "||" + newName + "||", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\={0}\+", "\\" + itemParameter.ParameterName), "=" + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\|\|", "\\" + itemParameter.ParameterName), newName + "||", RegexOptions.IgnoreCase); + return itemSql; + } + internal static Type GetRootBaseType(Type entityType) + { + var baseType = entityType.BaseType; + while (baseType != null && baseType.BaseType != UtilConstants.ObjType) + { + baseType = baseType.BaseType; + } + return baseType; + } + + + internal static Type GetUnderType(PropertyInfo propertyInfo, ref bool isNullable) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + isNullable = unType != null; + unType = unType ?? propertyInfo.PropertyType; + return unType; + } + + internal static Type GetUnderType(PropertyInfo propertyInfo) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + unType = unType ?? propertyInfo.PropertyType; + return unType; + } + + internal static bool IsNullable(PropertyInfo propertyInfo) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + return unType != null; + } + + internal static bool IsNullable(Type type) + { + Type unType = Nullable.GetUnderlyingType(type); + return unType != null; + } + internal static T IsNullReturnNew(T returnObj) where T : new() + { + if (returnObj.IsNullOrEmpty()) + { + returnObj = new T(); + } + return returnObj; + } + public static object ChangeType2(object value, Type type) + { + if (value is byte[] && type == UtilConstants.StringType) + { + return Encoding.UTF8.GetString(value as byte[]); + } + if (value == null && type.IsGenericType) return Activator.CreateInstance(type); + if (value == null) return null; + if (type == value.GetType()) return value; + if (type.IsEnum) + { + if (value is string) + return Enum.Parse(type, value as string); + else + return Enum.ToObject(type, value); + } + if (value is string && type == typeof(Guid?)) return value.IsNullOrEmpty() ? null : (Guid?)new Guid(value as string); + if (!type.IsInterface && type.IsGenericType) + { + Type innerType = type.GetGenericArguments()[0]; + object innerValue = ChangeType(value, innerType); + return Activator.CreateInstance(type, new object[] { innerValue }); + } + if (value is string && type == typeof(Guid)) return new Guid(value as string); + if (value is string && type == typeof(Version)) return new Version(value as string); + if (!(value is IConvertible)) return value; + if (value is DateTime && type.FullName == "System.DateOnly") + { + value = UtilMethods.DateTimeToDateOnly(value); + } + return Convert.ChangeType(value, type); + } + + internal static T ChangeType(T obj, Type type) + { + return (T)Convert.ChangeType(obj, type); + } + + internal static T ChangeType(T obj) + { + return (T)Convert.ChangeType(obj, typeof(T)); + } + + internal static DateTimeOffset GetDateTimeOffsetByDateTime(DateTime date) + { + date = DateTime.SpecifyKind(date, DateTimeKind.Utc); + DateTimeOffset utcTime2 = date; + return utcTime2; + } + + internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + { + if (appendSql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + string newName = name + append + addIndex; + appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + parameter.ParameterName = newName; + } + } + } + internal static void RepairReplicationParameters(ISqlSugarClient db, ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + { + if (appendSql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + string newName = name + append + addIndex; + var maxLength = db.CurrentConnectionConfig.MoreSettings.MaxParameterNameLength; + if (newName.Length > maxLength) + { + newName = (name.Substring(0, 1) + name.GetNonNegativeHashCodeString() + "_" + addIndex); + } + appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + parameter.ParameterName = newName; + } + } + } + + internal static string GetPackTable(string sql, string shortName) + { + return string.Format(" ({0}) {1} ", sql, shortName); + } + + public static Func GetTypeConvert(object value) + { + if (value is int || value is uint || value is int? || value is uint?) + { + return x => Convert.ToInt32(x); + } + else if (value is short || value is ushort || value is short? || value is ushort?) + { + return x => Convert.ToInt16(x); + } + else if (value is long || value is long? || value is ulong? || value is long?) + { + return x => Convert.ToInt64(x); + } + else if (value is DateTime || value is DateTime?) + { + return x => Convert.ToDateTime(x); + } + else if (value is bool || value is bool?) + { + return x => Convert.ToBoolean(x); + } + return null; + } + + internal static string GetTypeName(object value) + { + if (value == null) + { + return null; + } + else + { + return value.GetType().Name; + } + } + + internal static string GetParenthesesValue(string dbTypeName) + { + if (Regex.IsMatch(dbTypeName, @"\(.+\)")) + { + if (Regex.IsMatch(dbTypeName, @"SimpleAggregateFunction")) + dbTypeName = Regex.Match(dbTypeName, @"((?<=,\s)[^Nullable]\w+)|((?<=Nullable\()\w+)").Value; + else + dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", ""); + } + dbTypeName = dbTypeName.Trim(); + return dbTypeName; + } + + internal static T GetOldValue(T value, Action action) + { + action(); + return value; + } + + internal static object DefaultForType(Type targetType) + { + return targetType.IsValueType ? Activator.CreateInstance(targetType) : null; + } + + internal static Int64 GetLong(byte[] bytes) + { + return Convert.ToInt64(string.Join("", bytes).PadRight(20, '0')); + } + public static object GetPropertyValue(T t, string PropertyName) + { + return t.GetType().GetProperty(PropertyName).GetValue(t, null); + } + internal static string GetMD5(string myString) + { + MD5 md5 = new MD5CryptoServiceProvider(); + byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString); + byte[] targetData = md5.ComputeHash(fromData); + string byte2String = null; + + for (int i = 0; i < targetData.Length; i++) + { + byte2String += targetData[i].ToString("x"); + } + + return byte2String; + } + + public static string EncodeBase64(string code) + { + if (StaticConfig.Encode != null) + { + return StaticConfig.Encode(code); + } + if (code.IsNullOrEmpty()) return code; + string encode = ""; + byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(code); + try + { + encode = Convert.ToBase64String(bytes); + } + catch + { + encode = code; + } + return encode; + } + public static string ConvertNumbersToString(string value) + { + string[] splitInt = value.Split(new char[] { '9' }, StringSplitOptions.RemoveEmptyEntries); + + var splitChars = splitInt.Select(s => Convert.ToChar( + Convert.ToInt32(s, 8) + ).ToString()); + + return string.Join("", splitChars); + } + public static string ConvertStringToNumbers(string value) + { + StringBuilder sb = new StringBuilder(); + + foreach (char c in value) + { + int cAscil = (int)c; + sb.Append(Convert.ToString(c, 8) + "9"); + } + + return sb.ToString(); + } + + public static string DecodeBase64(string code) + { + try + { + if (StaticConfig.Decode != null) + { + return StaticConfig.Decode(code); + } + if (code.IsNullOrEmpty()) return code; + string decode = ""; + byte[] bytes = Convert.FromBase64String(code); + try + { + decode = Encoding.GetEncoding("utf-8").GetString(bytes); + } + catch + { + decode = code; + } + return decode; + } + catch + { + return code; + } + } + + public static string GetSqlValue(object value) + { + if (value == null) + { + return "null"; + } + else if (UtilMethods.IsNumber(value.GetType().Name)) + { + return value.ObjToString(); + } + else if (value is DateTime) + { + return UtilMethods.GetConvertValue(value) + ""; + } + else + { + return value.ToSqlValue(); + } + } + + public static void DataInoveByExpresson(Type[] datas, MethodCallExpression callExpresion) + { + var methodInfo = callExpresion.Method; + foreach (var item in datas) + { + if (item != null) + { + if (callExpresion.Arguments.Count == 0) + { + methodInfo.Invoke(item, null); + } + else + { + List methodParameters = new List(); + foreach (var callItem in callExpresion.Arguments) + { + var parameter = callItem.GetType().GetProperties().FirstOrDefault(it => it.Name == "Value"); + if (parameter == null) + { + var value = LambdaExpression.Lambda(callItem).Compile().DynamicInvoke(); + methodParameters.Add(value); + } + else + { + var value = parameter.GetValue(callItem, null); + methodParameters.Add(value); + } + } + methodInfo.Invoke(item, methodParameters.ToArray()); + } + } + } + } + + public static Dictionary EnumToDictionary() + { + Dictionary dic = new Dictionary(); + if (!typeof(T).IsEnum) + { + return dic; + } + string desc = string.Empty; + foreach (var item in Enum.GetValues(typeof(T))) + { + var key = item.ToString().ToLower(); + if (!dic.ContainsKey(key)) + dic.Add(key, (T)item); + } + return dic; + } + + public static Type GetTypeByTypeName(string ctypename) + { + + if (ctypename.EqualCase(UtilConstants.DecType.Name)) + { + return UtilConstants.DecType; + } + else if (ctypename.EqualCase(UtilConstants.DobType.Name)) + { + return UtilConstants.DobType; + } + else if (ctypename.EqualCase(UtilConstants.DateType.Name)) + { + return UtilConstants.DateType; + } + else if (ctypename.EqualCase(UtilConstants.IntType.Name)) + { + return UtilConstants.IntType; + } + else if (ctypename.EqualCase(UtilConstants.BoolType.Name)) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase(UtilConstants.LongType.Name)) + { + return UtilConstants.LongType; + } + else if (ctypename.EqualCase(UtilConstants.ShortType.Name)) + { + return UtilConstants.ShortType; + } + else if (ctypename.EqualCase(UtilConstants.DateTimeOffsetType.Name)) + { + return UtilConstants.DateTimeOffsetType; + } + else if (ctypename.EqualCase(UtilConstants.GuidType.Name)) + { + return UtilConstants.GuidType; + } + else if (ctypename.EqualCase("int")) + { + return UtilConstants.IntType; + } + else if (ctypename.EqualCase("long")) + { + return UtilConstants.LongType; + } + else if (ctypename.EqualCase("short")) + { + return UtilConstants.ShortType; + } + else if (ctypename.EqualCase("byte")) + { + return UtilConstants.ByteType; + } + else if (ctypename.EqualCase("uint")) + { + return UtilConstants.UIntType; + } + else if (ctypename.EqualCase("ulong")) + { + return UtilConstants.ULongType; + } + else if (ctypename.EqualCase("ushort")) + { + return UtilConstants.UShortType; + } + else if (ctypename.EqualCase("uint32")) + { + return UtilConstants.UIntType; + } + else if (ctypename.EqualCase("uint64")) + { + return UtilConstants.ULongType; + } + else if (ctypename.EqualCase("bool")) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase("ToBoolean")) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase("uint16")) + { + return UtilConstants.UShortType; + } + else if (ctypename.EqualCase(UtilConstants.ByteArrayType.Name)) + { + return UtilConstants.ByteArrayType; + } + else + { + return UtilConstants.StringType; + } + } + public static object ConvertDataByTypeName(string ctypename, string value) + { + var item = new ConditionalModel() + { + CSharpTypeName = ctypename, + FieldValue = value + }; + if (item.FieldValue == string.Empty && item.CSharpTypeName.HasValue() && !item.CSharpTypeName.EqualCase("string")) + { + return null; + } + if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) + { + return Convert.ToDecimal(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) + { + return Convert.ToDouble(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DateType.Name)) + { + return Convert.ToDateTime(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) + { + return Convert.ToInt32(item.FieldValue); + } + else if (item.FieldValue != null && item.CSharpTypeName.EqualCase(UtilConstants.BoolType.Name)) + { + return Convert.ToBoolean(item.FieldValue.ToLower()); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) + { + return Convert.ToInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) + { + return Convert.ToInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DateTimeOffsetType.Name)) + { + DateTimeOffset dt; + if (DateTimeOffset.TryParse(item.FieldValue, out dt)) + { + return dt; + } + return UtilMethods.GetDateTimeOffsetByDateTime(Convert.ToDateTime(item.FieldValue)); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.GuidType.Name)) + { + return Guid.Parse(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("int")) + { + return Convert.ToInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("long")) + { + return Convert.ToInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("float")) + { + return Convert.ToSingle(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("single")) + { + return Convert.ToSingle(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("short")) + { + return Convert.ToInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("byte")) + { + return Convert.ToByte(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint")) + { + return Convert.ToUInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ulong")) + { + return Convert.ToUInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ushort")) + { + return Convert.ToUInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint32")) + { + return Convert.ToUInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint64")) + { + return Convert.ToUInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("bool")) + { + return Convert.ToBoolean(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ToBoolean")) + { + return Convert.ToBoolean(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint16")) + { + return Convert.ToUInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("byte[]") && item.FieldValue != null && item.FieldValue.Contains("|")) + { + return item.FieldValue.Split('|').Select(it => Convert.ToByte(it)).ToArray(); + } + else + { + return item.FieldValue; + } + } + + public static bool IsNumber(string ctypename) + { + if (ctypename.IsNullOrEmpty()) + { + return false; + } + var item = new ConditionalModel() + { + CSharpTypeName = ctypename, + }; + if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("int")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("long")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("short")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("byte")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("ulong")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("ushort")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint32")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint64")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint16")) + { + return true; + } + else + { + return false; + } + } + + /// + /// Get Week Last Day Sun + /// + /// + /// + public static DateTime GetWeekLastDaySun(DateTime datetime) + { + //星期天为最后一天 + int weeknow = Convert.ToInt32(datetime.DayOfWeek); + weeknow = (weeknow == 0 ? 7 : weeknow); + int daydiff = (7 - weeknow); + + //本周最后一天 + string LastDay = datetime.AddDays(daydiff).ToString("yyyy-MM-dd"); + return Convert.ToDateTime(LastDay); + } + /// + /// Get Week First Day Mon + /// + /// + /// + public static DateTime GetWeekFirstDayMon(DateTime datetime) + { + //星期一为第一天 + int weeknow = Convert.ToInt32(datetime.DayOfWeek); + + //因为是以星期一为第一天,所以要判断weeknow等于0时,要向前推6天。 + weeknow = (weeknow == 0 ? (7 - 1) : (weeknow - 1)); + int daydiff = (-1) * weeknow; + + //本周第一天 + string FirstDay = datetime.AddDays(daydiff).ToString("yyyy-MM-dd"); + return Convert.ToDateTime(FirstDay); + } + public static string GetSqlString(DbType dbType, string sql, SugarParameter[] parametres, bool DisableNvarchar = false) + { + if (parametres == null) + parametres = new SugarParameter[] { }; + return GetSqlString(new ConnectionConfig() + { + DbType = dbType, + MoreSettings = new ConnMoreSettings() + { + DisableNvarchar = DisableNvarchar + } + }, new KeyValuePair>(sql, parametres.ToList())); + } + public static string GetSqlString(ConnectionConfig connectionConfig, KeyValuePair> sqlObj) + { + var guid = Guid.NewGuid() + ""; + var result = sqlObj.Key; + if (sqlObj.Value != null) + { + foreach (var item in UtilMethods.CopySugarParameters(sqlObj.Value).OrderByDescending(it => it.ParameterName.Length)) + { + if (item.ParameterName.StartsWith(":") && !result.Contains(item.ParameterName)) + { + item.ParameterName = "@" + item.ParameterName.TrimStart(':'); + } + if (connectionConfig.MoreSettings == null) + { + connectionConfig.MoreSettings = new ConnMoreSettings(); + } + if (item.Value != null && item.Value is DateTime && ((DateTime)item.Value == DateTime.MinValue)) + { + item.Value = connectionConfig.MoreSettings.DbMinDate; + } + if (item.Value == null || item.Value == DBNull.Value) + { + result = result.Replace(item.ParameterName, "null"); + } + else if (UtilMethods.IsNumber(item.Value.GetType().Name)) + { + result = result.Replace(item.ParameterName, item.Value.ObjToString()); + } + else if (item.Value is DateTime && connectionConfig.DbType == DbType.SqlServer) + { + result = result.Replace(item.ParameterName, "CAST('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff") + "' AS DATETIME)"); + } + else if (item.Value is DateTime && connectionConfig.DbType.IsIn(DbType.Dm, DbType.Oracle)) + { + if (item.DbType == System.Data.DbType.Date || connectionConfig?.MoreSettings?.DisableMillisecond == true) + { + var value = "to_date('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; ; + result = result.Replace(item.ParameterName, value); + } + else + { + var value = "to_timestamp('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + result = result.Replace(item.ParameterName, value); + } + } + else if (item.Value is DateTime) + { + result = result.Replace(item.ParameterName, "'" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"); + } + else if (item.IsArray) + { + result = result.Replace(item.ParameterName, "'{" + new SerializeService().SerializeObject(item.Value).TrimStart('[').TrimEnd(']') + "}'"); + } + else if (item.Value is byte[] && connectionConfig.DbType == DbType.PostgreSQL) + { + result = result.Replace(item.ParameterName, ByteArrayToPostgreByteaLiteral(item.Value as byte[])); + } + else if (item.Value is byte[]) + { + result = result.Replace(item.ParameterName, "0x" + BitConverter.ToString((byte[])item.Value).Replace("-", "")); + } + else if (item.Value is bool) + { + if (connectionConfig.DbType == DbType.PostgreSQL) + { + result = result.Replace(item.ParameterName, (Convert.ToBoolean(item.Value) ? "true" : "false")); + } + else + { + result = result.Replace(item.ParameterName, (Convert.ToBoolean(item.Value) ? 1 : 0) + ""); + } + } + else if (item.Value.GetType() != UtilConstants.StringType && connectionConfig.DbType == DbType.PostgreSQL && PostgreSQLDbBind.MappingTypesConst.Any(x => x.Value.ToString().EqualCase(item.Value.GetType().Name))) + { + var type = PostgreSQLDbBind.MappingTypesConst.First(x => x.Value.ToString().EqualCase(item.Value.GetType().Name)).Key; + var replaceValue = string.Format("CAST('{0}' AS {1})", item.Value, type); + result = result.Replace(item.ParameterName, replaceValue); + } + else if (connectionConfig.MoreSettings?.DisableNvarchar == true || item.DbType == System.Data.DbType.AnsiString || connectionConfig.DbType == DbType.Sqlite) + { + result = result.Replace(item.ParameterName, $"'{item.Value.ObjToString().Replace("@", guid).ToSqlFilter()}'"); + } + else + { + result = result.Replace(item.ParameterName, $"N'{item.Value.ObjToString().Replace("@", guid).ToSqlFilter()}'"); + } + } + } + result = result.Replace(guid, "@"); + return result; + } + public static string ByteArrayToPostgreByteaLiteral(byte[] data) + { + var sb = new StringBuilder("E'"); + + foreach (var b in data) + { + if (b >= 32 && b < 127 && !char.IsControl((char)b)) // 可打印的ASCII字符 + { + sb.Append((char)b); + } + else // 非打印字符或控制字符 + { + sb.Append("\\\\"); + sb.Append(Convert.ToString(b, 8).PadLeft(3, '0')); + } + } + + sb.Append("'::bytea"); + return sb.ToString(); + } + public static void CheckArray(T[] insertObjs) where T : class, new() + { + + if (insertObjs != null + && insertObjs.Length == 1 + && insertObjs.FirstOrDefault() != null + && insertObjs.FirstOrDefault().GetType().FullName.Contains("System.Collections.Generic.List`")) + { + Check.ExceptionEasy("Insertable(T []) is an array and your argument is a List", "二次封装引起的进错重载,当前方法是 Insertable(T []) 参数是一个数组,而你的参数是一个List"); + } + } + + [Obsolete("请使用新名字:FieldNameSql")] + public static string FiledNameSql() + { + return $"[value=sql{UtilConstants.ReplaceKey}]"; + } + public static string FieldNameSql() + { + if (StaticConfig.TableQuerySqlKey != null && StaticConfig.TableQuerySqlKey != Guid.Empty) + { + return $"[value=sql{StaticConfig.TableQuerySqlKey}]"; + } + return $"[value=sql{UtilConstants.ReplaceKey}]"; + } + + internal static object TimeOnlyToTimeSpan(object value) + { + if (value == null) return null; + var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToTimeSpan"); + return method.Invoke(value, new object[] { }); + } + + internal static object DateOnlyToDateTime(object value) + { + if (value == null) return null; + var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToShortDateString"); + return method.Invoke(value, new object[] { }); + } + internal static object DateTimeToDateOnly(object value) + { + if (value == null) return null; + + // 获取DateOnly类型 + Type dateOnlyType = Type.GetType("System.DateOnly, System.Runtime", throwOnError: false); + if (dateOnlyType == null) + { + throw new InvalidOperationException("DateOnly type not found."); + } + + // 获取DateOnly的构造函数 + var constructor = dateOnlyType.GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + if (constructor == null) + { + throw new InvalidOperationException("DateOnly constructor not found."); + } + + // 使用反射调用DateTime的属性 + var yearProperty = value.GetType().GetProperty("Year"); + var monthProperty = value.GetType().GetProperty("Month"); + var dayProperty = value.GetType().GetProperty("Day"); + + if (yearProperty == null || monthProperty == null || dayProperty == null) + { + throw new InvalidOperationException("DateTime properties not found."); + } + + int year = (int)yearProperty.GetValue(value); + int month = (int)monthProperty.GetValue(value); + int day = (int)dayProperty.GetValue(value); + + // 使用反射创建DateOnly实例 + return constructor.Invoke(new object[] { year, month, day }); + } + + + internal static void AddDiscrimator(Type type, ISugarQueryable queryable, string shortName = null) + { + var entityInfo = queryable.Context?.EntityMaintenance?.GetEntityInfoWithAttr(type); + if (entityInfo != null && entityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + queryable.Where(shortName + name, "=", value); + } + } + } + internal static string GetDiscrimator(EntityInfo entityInfo, ISqlBuilder builer) + { + List wheres = new List(); + if (entityInfo != null && entityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + wheres.Add($"{builer.GetTranslationColumnName(name)}={value.ToSqlValue()} "); + } + } + return string.Join(" AND ", wheres); + } + + internal static bool NoErrorParameter(string parameterName) + { + if (parameterName == null) + { + return false; + } + if (parameterName.Contains(" ")) + { + return false; + } + if (parameterName.Contains("(")) + { + return false; + } + if (parameterName.Contains("(")) + { + return false; + } + if (parameterName.Contains(".")) + { + return false; + } + return true; + } + + internal static ConnMoreSettings GetMoreSetting(ExpressionContext context) + { + return context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings ?? new ConnMoreSettings(); } - //public static object ConvertDataByTypeName(string ctypename,string value) - //{ - // var item = new ConditionalModel() { - // CSharpTypeName = ctypename, - // FieldValue = value - // }; - // if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) - // { - // return Convert.ToDecimal(item.FieldValue); - // } - // else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) - // { - // return Convert.ToDouble(item.FieldValue); - // } - // else if (item.CSharpTypeName.EqualCase(UtilConstants.DateType.Name)) - // { - // return Convert.ToDateTime(item.FieldValue); - // } - // else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) - // { - // return Convert.ToInt32(item.FieldValue); - // } - // else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) - // { - // return Convert.ToInt64(item.FieldValue); - // } - // else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) - // { - // return Convert.ToInt16(item.FieldValue); - // } - // else if (item.CSharpTypeName.EqualCase(UtilConstants.DateTimeOffsetType.Name)) - // { - // return UtilMethods.GetDateTimeOffsetByDateTime(Convert.ToDateTime(item.FieldValue)); - // } - // else - // { - // return item.FieldValue; - // } - //} } } diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs index 6c655487da0aef8121e639495757f4d7bf4c3152..72583bf678e35efdd9ce12c57cda46d3fb3892ed 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs @@ -8,6 +8,7 @@ namespace SqlSugar.TDSQLForPGODBC { public override string GetDbTypeName(string csharpTypeName) { + csharpTypeName = GetValidCsharpTypeName(csharpTypeName); if (csharpTypeName == UtilConstants.ByteArrayType.Name) return "bytea"; if (csharpTypeName.ToLower() == "int32") @@ -26,18 +27,38 @@ namespace SqlSugar.TDSQLForPGODBC else return "varchar"; } + + private string GetValidCsharpTypeName(string csharpTypeName) + { + if (csharpTypeName?.StartsWith("ora") == true && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase) + { + csharpTypeName = csharpTypeName.Replace("ora", ""); + } + else if (csharpTypeName?.StartsWith("mssql_") == true && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase) + { + csharpTypeName = csharpTypeName.Replace("mssql_", ""); + } + else if (csharpTypeName?.StartsWith("sys.") == true) + { + csharpTypeName = csharpTypeName.Replace("sys.", ""); + } + return csharpTypeName; + } + public override string GetPropertyTypeName(string dbTypeName) { dbTypeName = dbTypeName.ToLower(); + dbTypeName = GetValidCsharpTypeName(dbTypeName); var propertyTypes = MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName || it.Key.ToLower() == dbTypeName); if (propertyTypes == null) { return "other"; } - else if (dbTypeName == "xml" || dbTypeName == "string"|| dbTypeName == "jsonb"|| dbTypeName == "json") + else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json") { return "string"; - }else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + } + else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar { return "char"; } @@ -50,7 +71,11 @@ namespace SqlSugar.TDSQLForPGODBC if (dbTypeName.StartsWith("_")) { var dbTypeName2 = dbTypeName.TrimStart('_'); - return MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName2 || it.Key.ToLower() == dbTypeName2).Select(it => it.Value + "[]").First(); + return MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName2 || it.Key.ToLower() == dbTypeName2).Select(it => it.Value + "[]").First(); + } + else if (dbTypeName.EndsWith("geometry") || dbTypeName.EndsWith("geography")) + { + return CSharpDataType.@string.ToString(); } Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); return null; @@ -85,7 +110,7 @@ namespace SqlSugar.TDSQLForPGODBC //new KeyValuePair("int1",CSharpDataType.@byte), new KeyValuePair("smallint",CSharpDataType.@short), new KeyValuePair("smallint",CSharpDataType.@byte), - new KeyValuePair("int4",CSharpDataType.@int), + new KeyValuePair("int4",CSharpDataType.@int), new KeyValuePair("serial",CSharpDataType.@int), new KeyValuePair("integer",CSharpDataType.@int), new KeyValuePair("int8",CSharpDataType.@long), @@ -146,7 +171,16 @@ namespace SqlSugar.TDSQLForPGODBC new KeyValuePair("time",CSharpDataType.TimeSpan), new KeyValuePair("public.geometry",CSharpDataType.@object), new KeyValuePair("public.geography",CSharpDataType.@object), - new KeyValuePair("inet",CSharpDataType.@object) + new KeyValuePair("inet",CSharpDataType.@object), + + new KeyValuePair("number",CSharpDataType.@int), + new KeyValuePair("number",CSharpDataType.@float), + new KeyValuePair("number",CSharpDataType.@short), + new KeyValuePair("number",CSharpDataType.@byte), + new KeyValuePair("number",CSharpDataType.@double), + new KeyValuePair("number",CSharpDataType.@long), + new KeyValuePair("number",CSharpDataType.@bool), + new KeyValuePair("number",CSharpDataType.@decimal), }; public override List StringThrow { diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs index e86932bb3b67f7d3417e2c48a213b5f565e2dfe7..c5a8e717a5db22a8f989d164a4c5bda8b26d2dd0 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs @@ -30,8 +30,11 @@ namespace SqlSugar.TDSQLForPGODBC col_description(pclass.oid, pcolumn.ordinal_position) as ColumnDescription, case when pkey.colname = pcolumn.column_name then true else false end as IsPrimaryKey, - case when pcolumn.column_default like 'nextval%' - then true else false end as IsIdentity, + CASE + WHEN (current_setting('server_version_num')::INT >= 100000 AND pcolumn.is_identity = 'YES') THEN true + WHEN pcolumn.column_default LIKE 'nextval%' THEN true + ELSE false + END AS IsIdentity, case when pcolumn.is_nullable = 'YES' then true else false end as IsNullable from (select * from pg_tables where upper(tablename) = upper('{0}') and schemaname='" + schema + @"') ptables inner join pg_class pclass @@ -70,7 +73,7 @@ namespace SqlSugar.TDSQLForPGODBC { get { - return @"select table_name as name from information_schema.views where table_schema ='" + GetSchema()+"' "; + return @"select table_name as name from information_schema.views where table_schema ='" + GetSchema() + "' "; } } #endregion @@ -247,6 +250,18 @@ namespace SqlSugar.TDSQLForPGODBC #endregion #region Methods + public override bool IsAnyTable(string tableName, bool isCache = true) + { + if (isCache == false) + { + var sql = $" SELECT 1 FROM pg_catalog.pg_tables \r\n WHERE schemaname = '" + GetSchema() + "' \r\n AND Lower(tablename) = '" + tableName.ToLower() + "' "; + return this.Context.Ado.GetInt(sql) > 0; + } + else + { + return base.IsAnyTable(tableName, isCache); + } + } public override List GetDbTypes() { var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT data_type @@ -260,7 +275,7 @@ FROM information_schema.columns"); result.Add("time"); result.Add("date"); result.Add("float8"); - result.Add("float4"); + result.Add("float4"); result.Add("json"); result.Add("jsonp"); return result.Distinct().ToList(); @@ -269,7 +284,7 @@ FROM information_schema.columns"); { return this.Context.Ado.SqlQuery(@"SELECT tgname FROM pg_trigger -WHERE tgrelid = '"+tableName+"'::regclass"); +WHERE tgrelid = '" + tableName + "'::regclass"); } public override List GetFuncList() { @@ -287,26 +302,26 @@ WHERE tgrelid = '"+tableName+"'::regclass"); } public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) { - if (defaultValue?.StartsWith("'")==true&& defaultValue?.EndsWith("'") == true&& defaultValue?.Contains("(") == false - &&!defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + if (defaultValue?.StartsWith("'") == true && defaultValue?.EndsWith("'") == true && defaultValue?.Contains("(") == false + && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) { - string sql = string.Format(AddDefaultValueSql,this.SqlBuilder.GetTranslationColumnName( tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); return this.Context.Ado.ExecuteCommand(sql) > 0; } else if (defaultValue.EqualCase("current_timestamp") || defaultValue.EqualCase("current_date")) { - string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue ); + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); return this.Context.Ado.ExecuteCommand(sql) > 0; } else if (defaultValue?.Contains("(") == false && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) { - string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), "'"+defaultValue+"'"); + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), "'" + defaultValue + "'"); return this.Context.Ado.ExecuteCommand(sql) > 0; } else if (defaultValue?.ToLower()?.Contains("cast(") == true && defaultValue?.StartsWith("'") == true && defaultValue?.EndsWith("'") == true) { - string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue.Replace("''","'").TrimEnd('\'').TrimStart('\'')); + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue.Replace("''", "'").TrimEnd('\'').TrimStart('\'')); return this.Context.Ado.ExecuteCommand(sql) > 0; } else if (defaultValue?.ToLower()?.Contains("now()") == true) @@ -341,11 +356,11 @@ WHERE tgrelid = '"+tableName+"'::regclass"); { ConvertCreateColumnInfo(columnInfo); tableName = this.SqlBuilder.GetTranslationTableName(tableName); - var columnName= this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + var columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); string sql = GetUpdateColumnSql(tableName, columnInfo); this.Context.Ado.ExecuteCommand(sql); - var isnull = columnInfo.IsNullable?" DROP NOT NULL ": " SET NOT NULL "; - this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}",tableName,columnName, isnull)); + var isnull = columnInfo.IsNullable ? " DROP NOT NULL " : " SET NOT NULL "; + this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}", tableName, columnName, isnull)); return true; } @@ -382,7 +397,16 @@ WHERE tgrelid = '"+tableName+"'::regclass"); } var oldDatabaseName = this.Context.Ado.Connection.Database; var connection = this.Context.CurrentConnectionConfig.ConnectionString; - connection = connection.Replace(oldDatabaseName, "postgres"); + if (Regex.Matches(connection, oldDatabaseName).Count > 1) + { + var builder = new Npgsql.NpgsqlConnectionStringBuilder(connection); + builder.Database = "postgres"; + connection = builder.ConnectionString; + } + else + { + connection = connection.Replace(oldDatabaseName, "postgres"); + } var newDb = new SqlSugarClient(new ConnectionConfig() { DbType = this.Context.CurrentConnectionConfig.DbType, @@ -391,13 +415,13 @@ WHERE tgrelid = '"+tableName+"'::regclass"); }); if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) { - var isVast = this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel==DbType.Vastbase; + var isVast = this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase; var dbcompatibility = ""; - if (isVast) + if (isVast) { - dbcompatibility=" dbcompatibility = 'PG'"; + dbcompatibility = " dbcompatibility = 'PG'"; } - newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft+databaseName+this.SqlBuilder.SqlTranslationRight, databaseDirectory)+ dbcompatibility); + newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft + databaseName + this.SqlBuilder.SqlTranslationRight, databaseDirectory) + dbcompatibility); } return true; } @@ -451,7 +475,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); protected override bool IsAnyDefaultValue(string tableName, string columnName, List columns) { var defaultValue = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)).First().DefaultValue; - if (defaultValue?.StartsWith("NULL::") == true) + if (defaultValue?.StartsWith("NULL::") == true) { return false; } @@ -475,7 +499,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); // dataType = "varchar"; //} string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; - if (item.DecimalDigits > 0&&item.Length>0 && dataType == "numeric") + if (item.DecimalDigits > 0 && item.Length > 0 && dataType == "numeric") { dataSize = $"({item.Length},{item.DecimalDigits})"; } @@ -484,7 +508,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), dataType, dataSize, nullType, primaryKey, ""); if (item.IsIdentity) { - if (dataType?.ToLower() == "int") + if (dataType?.ToLower() == "int") { dataSize = "int4"; } @@ -513,7 +537,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); public override List GetColumnInfosByTableName(string tableName, bool isCache = true) { - var result= base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); + var result = base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); if (result == null || result.Count() == 0) { result = base.GetColumnInfosByTableName(tableName, isCache); @@ -533,24 +557,24 @@ WHERE tgrelid = '"+tableName+"'::regclass"); List pkList = new List(); if (isCache) { - pkList=GetListOrCache("GetColumnInfosByTableName_N_Pk"+tableName, sql); + pkList = GetListOrCache("GetColumnInfosByTableName_N_Pk" + tableName, sql); } else { pkList = this.Context.Ado.SqlQuery(sql); } - if (pkList.Count >1) + if (pkList.Count > 1) { foreach (var item in result) { - if (pkList.Select(it=>it.ToUpper()).Contains(item.DbColumnName.ToUpper())) + if (pkList.Select(it => it.ToUpper()).Contains(item.DbColumnName.ToUpper())) { item.IsPrimarykey = true; } } } } - catch + catch { } @@ -579,28 +603,50 @@ WHERE tgrelid = '"+tableName+"'::regclass"); private string GetSchema() { var schema = "public"; - if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + var pgSqlIsAutoToLowerSchema = this.Context?.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLowerSchema == false; + if (pgSqlIsAutoToLowerSchema) { - var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; - if (regValue.HasValue()) + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString, "searchpath=", RegexOptions.IgnoreCase)) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString, @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString, "search path=", RegexOptions.IgnoreCase)) { - schema = regValue; + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } } } - else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + else { - var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; - if (regValue.HasValue()) + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) { - schema = regValue; + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } } } - return schema; } private static void ConvertCreateColumnInfo(DbColumnInfo x) { - string[] array = new string[] { "uuid","int4", "text", "int2", "int8", "date", "bit", "text", "timestamp" }; + string[] array = new string[] { "uuid", "int4", "text", "int2", "int8", "date", "bit", "text", "timestamp" }; if (array.Contains(x.DataType?.ToLower())) { diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs index 939dafc6c305ca99c3344358ef5082ce21ac79a5..8342eee35f3478481f1d1e8f02001291d4f8bb03 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs @@ -54,7 +54,7 @@ namespace SqlSugar.TDSQLForPGODBC { var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); - var tableName = mappingInfo?.DbTableName+""; + var tableName = mappingInfo?.DbTableName + ""; if (tableName.Contains(".")) { tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); @@ -102,7 +102,7 @@ namespace SqlSugar.TDSQLForPGODBC } } - public string GetValue(object entityValue) + public string GetValue(object entityValue) { if (entityValue == null) return null; @@ -120,7 +120,7 @@ namespace SqlSugar.TDSQLForPGODBC } }); } - else + else { return this.DbMehtods.ToString(new MethodCallExpressionModel() { @@ -180,7 +180,7 @@ namespace SqlSugar.TDSQLForPGODBC var parameter = model.Args[0]; var parameter2 = model.Args[1]; var parameter3 = model.Args[2]; - if (parameter.Type == UtilConstants.BoolType) + if (parameter.Type == UtilConstants.BoolType) { parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); parameter2.MemberName = false; @@ -229,7 +229,7 @@ namespace SqlSugar.TDSQLForPGODBC { return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) "; } - + return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName); } @@ -237,13 +237,19 @@ namespace SqlSugar.TDSQLForPGODBC { var parameter = model.Args[0]; var parameter2 = model.Args[1]; - return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName ); + return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName); } public override string StartsWith(MethodCallExpressionModel model) { var parameter = model.Args[0]; var parameter2 = model.Args[1]; + var parameter2Info = model.Parameters?.FirstOrDefault(it => it.ParameterName.EqualCase(parameter2.MemberName + "")); + if (parameter2Info != null && parameter2.MemberName?.ToString()?.StartsWith("@MethodConst") == true) + { + parameter2Info.Value = parameter2.MemberValue + "%"; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } return string.Format(" ({0} like concat({1},'%')) ", parameter.MemberName, parameter2.MemberName); } @@ -251,7 +257,13 @@ namespace SqlSugar.TDSQLForPGODBC { var parameter = model.Args[0]; var parameter2 = model.Args[1]; - return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName,parameter2.MemberName); + var parameter2Info = model.Parameters?.FirstOrDefault(it => it.ParameterName.EqualCase(parameter2.MemberName + "")); + if (parameter2Info != null && parameter2.MemberName?.ToString()?.StartsWith("@MethodConst") == true) + { + parameter2Info.Value = "%" + parameter2.MemberValue; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } + return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName, parameter2.MemberName); } public override string DateIsSameDay(MethodCallExpressionModel model) @@ -272,11 +284,11 @@ namespace SqlSugar.TDSQLForPGODBC var parameter = model.Args[0]; var parameter2 = model.Args[1]; var parameter3 = model.Args[2]; - DateType dateType =(DateType)parameter3.MemberValue; + DateType dateType = (DateType)parameter3.MemberValue; var format = "yyyy-MM-dd"; if (dateType == DateType.Quarter) { - return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName,format); + return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName, format); } switch (dateType) { @@ -375,8 +387,8 @@ namespace SqlSugar.TDSQLForPGODBC } public override string IsNullOrEmpty(MethodCallExpressionModel model) { - if ( - model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase|| + if ( + model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase || model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.GaussDB) { var parameter = model.Args[0]; @@ -390,7 +402,7 @@ namespace SqlSugar.TDSQLForPGODBC public override string MergeString(params string[] strings) { var key = Guid.NewGuid() + ""; - return " concat("+string.Join(",", strings.Select(it=>it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; + return " concat(" + string.Join(",", strings.Select(it => it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; } public override string IsNull(MethodCallExpressionModel model) { @@ -418,10 +430,10 @@ namespace SqlSugar.TDSQLForPGODBC var parameter1 = model.Args[1]; //var parameter2 = model.Args[2]; //var parameter3= model.Args[3]; - var result= GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count()==2); - if (model.Args.Count > 2) + var result = GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count() == 2); + if (model.Args.Count > 2) { - result = GetJson(result, model.Args[2].MemberName, model.Args.Count() == 3); + result = GetJson(result, model.Args[2].MemberName, model.Args.Count() == 3); } if (model.Args.Count > 3) { @@ -445,13 +457,13 @@ namespace SqlSugar.TDSQLForPGODBC return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})"; } - private string GetJson(object memberName1, object memberName2,bool isLast) + private string GetJson(object memberName1, object memberName2, bool isLast) { if (isLast) { return $"({memberName1}::json->>{memberName2})"; } - else + else { return $"({memberName1}->{memberName2})"; } @@ -477,11 +489,20 @@ namespace SqlSugar.TDSQLForPGODBC { return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb "; } - else + else { return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb "; } } + public override string GetStringJoinSelector(string result, string separator) + { + if (result?.ToLower()?.Contains("distinct") == true) + { + return $"string_agg({result},'{separator}') "; + } + return $"string_agg(({result})::text,'{separator}') "; + } + public override string JsonListObjectAny(MethodCallExpressionModel model) { if (UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs index fd3e00ce9c703eb29a798f286879d9d76bbc6bcf..dc41d9793fe412ea5f578331c23529dcdd256636 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs @@ -242,6 +242,10 @@ namespace SqlSugar.TDSQLForPGODBC { return v.ToString(CultureInfo.InvariantCulture); } + else if (value is double dou) + { + return dou.ToString(CultureInfo.InvariantCulture); + } else { return N + "'" + value.ToString() + "'"; diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs index f601583850f045272fc9299d5cd9c2ec1e3f3d85..fee5d38029a081ee919788a60b96ac204ee6ab71 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs @@ -91,6 +91,10 @@ namespace SqlSugar.TDSQLForPGODBC { return v.ToString(CultureInfo.InvariantCulture); } + else if (value is double dou) + { + return dou.ToString(CultureInfo.InvariantCulture); + } else { return "'" + value.ToString() + "'"; @@ -285,3 +289,4 @@ namespace SqlSugar.TDSQLForPGODBC } } } + diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs index 86ce50d2fb63041ddbaeb4dbf76faba2a8a80de5..a442ca6d9a20b80ba466aedde27227420b38b1df 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Dynamic; using System.Linq; +using System.Linq.Expressions; using System.Text; namespace SqlSugar.TDSQLForPGODBC { @@ -11,9 +12,10 @@ namespace SqlSugar.TDSQLForPGODBC public const char DotChar = '.'; internal const string Space = " "; internal const char SpaceChar = ' '; - internal const string AssemblyName = "SqlSugar"; + internal const string AssemblyName = "SqlSugar.TDSQLForPGODBC"; internal static string ReplaceKey = "{" + Guid.NewGuid() + "}"; internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + internal const string GroupReplaceKey = "{GroupReplaceKey_l33asdysaas1231s}"; internal static Type UShortType = typeof(ushort); internal static Type ULongType = typeof(ulong); @@ -62,7 +64,7 @@ namespace SqlSugar.TDSQLForPGODBC typeof(short), typeof(ushort), }; - + //internal static CultureInfo EnCultureInfo = new CultureInfo("en"); internal static string[] DateTypeStringList = new string[] { @@ -75,5 +77,8 @@ namespace SqlSugar.TDSQLForPGODBC "Millisecond", "Date" }; + + public static ConstantExpression ExpTrue = Expression.Constant(true); + public static ConstantExpression ExpFalse = Expression.Constant(false); } } diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs index 2a8ab2cf23bfcf885b701dac561a8db59131aa6d..3f10fd70bb310a7e8320f1bcc3d2d973271d265c 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs @@ -18,6 +18,66 @@ namespace SqlSugar.TDSQLForPGODBC { public class UtilMethods { + public static string EscapeLikeValue(ISqlSugarClient db, string value, char wildcard = '%') + { + var dbType = db.CurrentConnectionConfig.DbType; + if (db.CurrentConnectionConfig?.MoreSettings?.DatabaseModel != null) + { + dbType = db.CurrentConnectionConfig.MoreSettings.DatabaseModel.Value; + } + if (string.IsNullOrEmpty(value)) + return value; + + string wildcardStr = wildcard.ToString(); + + switch (dbType) + { + // 支持标准 SQL LIKE 转义,通常使用中括号 [] 或反斜杠 \ 进行转义 + case DbType.SqlServer: + case DbType.Access: + case DbType.Odbc: + case DbType.TDSQLForPGODBC: + // SQL Server 使用中括号转义 %, _ 等 + value = value.Replace("[", "[[]") + .Replace("]", "[]]") + .Replace(wildcardStr, $"[{wildcard}]"); + break; + + // PostgreSQL 风格数据库,使用反斜杠进行 LIKE 转义 + case DbType.PostgreSQL: + case DbType.OpenGauss: + case DbType.TDSQL: + case DbType.GaussDB: + case DbType.GaussDBNative: + // MySQL 和兼容库,使用反斜杠进行转义 + case DbType.MySql: + case DbType.MySqlConnector: + case DbType.Tidb: + case DbType.PolarDB: + case DbType.OceanBase: + case DbType.Oracle: + case DbType.OceanBaseForOracle: + case DbType.HG: + case DbType.Dm: + case DbType.GBase: + case DbType.DB2: + case DbType.HANA: + case DbType.GoldenDB: + case DbType.Sqlite: + case DbType.DuckDB: + case DbType.QuestDB: + case DbType.Doris: + case DbType.Xugu: + case DbType.Vastbase: + default: + value = value + .Replace(wildcardStr, "\\\\" + wildcard); + break; + } + + return value; + } + public static List CopySugarParameters(List pars) { @@ -193,6 +253,14 @@ namespace SqlSugar.TDSQLForPGODBC var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; return p; } + internal static object QueryConverter(int index, ISqlSugarClient db, IDataReader dataReader, EntityInfo entity, EntityColumnInfo columnInfo) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("QueryConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { dataReader, index }); + return p; + } internal static bool IsErrorParameterName(ConnectionConfig connectionConfig, DbColumnInfo columnInfo) { return connectionConfig.MoreSettings?.IsCorrectErrorSqlParameterName == true && @@ -610,6 +678,14 @@ namespace SqlSugar.TDSQLForPGODBC { return (char)(bytes)[0]; } + else if (value is DateTime && destinationType == typeof(TimeSpan)) + { + value = Convert.ToDateTime(value).TimeOfDay; + } + else if (value is DateTime && destinationType.FullName == "System.TimeOnly") + { + value = Convert.ToDateTime(value).TimeOfDay; + } var destinationConverter = TypeDescriptor.GetConverter(destinationType); if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) return destinationConverter.ConvertFrom(null, culture, value); @@ -722,7 +798,8 @@ namespace SqlSugar.TDSQLForPGODBC DisableQueryWhereColumnRemoveTrim = it.MoreSettings.DisableQueryWhereColumnRemoveTrim, DatabaseModel = it.MoreSettings.DatabaseModel, EnableILike = it.MoreSettings.EnableILike, - ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal + ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal, + PgSqlIsAutoToLowerSchema = it.MoreSettings.PgSqlIsAutoToLowerSchema }, SqlMiddle = it.SqlMiddle == null ? null : new SqlMiddle