From 3518862257c3a7ca7742f45c0dbe8484b267341a Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Thu, 27 Jun 2024 11:20:20 +0800 Subject: [PATCH] =?UTF-8?q?=E8=99=9A=E8=B0=B7=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataTableExtensions/XuguDataAdapter.cs | 98 +++++ .../SqlSugar.XuguCore.csproj | 26 ++ .../SqlSugar.XuguCore/Tools/ErrorMessage.cs | 64 +++ .../SqlSugar.XuguCore/Tools/FileHelper.cs | 57 +++ .../SqlSugar.XuguCore/Tools/UtilConstants.cs | 73 ++++ .../SqlSugar.XuguCore/Tools/UtilExtensions.cs | 100 +++++ .../SqlSugar.XuguCore/Tools/UtilMethods.cs | 398 ++++++++++++++++++ .../Tools/ValidateExtensions.cs | 147 +++++++ .../Xugu/CodeFirst/XuguCodeFirst.cs | 97 +++++ .../Xugu/DbBind/XuguDbBind.cs | 102 +++++ .../Xugu/DbFirst/XuguDbFirst.cs | 9 + .../Xugu/DbMaintenance/XuguDbMaintenance.cs | 334 +++++++++++++++ .../Xugu/Queryable/XuguQueryable.cs | 58 +++ .../Xugu/SqlBuilder/XuguBlukCopy.cs | 129 ++++++ .../Xugu/SqlBuilder/XuguBuilder.cs | 29 ++ .../Xugu/SqlBuilder/XuguDeleteBuilder.cs | 10 + .../Xugu/SqlBuilder/XuguExpressionContext.cs | 97 +++++ .../Xugu/SqlBuilder/XuguFastBuilder.cs | 44 ++ .../Xugu/SqlBuilder/XuguInsertBuilder.cs | 115 +++++ .../Xugu/SqlBuilder/XuguQueryBuilder.cs | 112 +++++ .../Xugu/SqlBuilder/XuguUpdateBuilder.cs | 78 ++++ .../SqlSugar.XuguCore/Xugu/XuguEntry.cs | 34 ++ .../SqlSugar.XuguCore/Xugu/XuguProvider.cs | 283 +++++++++++++ Src/Asp.NetCore2/SqlSugarCore.sln | 31 +- Src/Asp.NetCore2/XuGuTest/2XuGuTest.csproj | 19 + Src/Asp.NetCore2/XuGuTest/BaseDataLogic.cs | 216 ++++++++++ Src/Asp.NetCore2/XuGuTest/Program.cs | 56 +++ Src/Asp.NetCore2/XuGuTest/T_USER.cs | 329 +++++++++++++++ 28 files changed, 3144 insertions(+), 1 deletion(-) create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/DataTableExtensions/XuguDataAdapter.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/SqlSugar.XuguCore.csproj create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ErrorMessage.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/FileHelper.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilConstants.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilExtensions.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilMethods.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ValidateExtensions.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/CodeFirst/XuguCodeFirst.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbBind/XuguDbBind.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbFirst/XuguDbFirst.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbMaintenance/XuguDbMaintenance.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/Queryable/XuguQueryable.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBlukCopy.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguDeleteBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguExpressionContext.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguFastBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguInsertBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguQueryBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguUpdateBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguEntry.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguProvider.cs create mode 100644 Src/Asp.NetCore2/XuGuTest/2XuGuTest.csproj create mode 100644 Src/Asp.NetCore2/XuGuTest/BaseDataLogic.cs create mode 100644 Src/Asp.NetCore2/XuGuTest/Program.cs create mode 100644 Src/Asp.NetCore2/XuGuTest/T_USER.cs diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/DataTableExtensions/XuguDataAdapter.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/DataTableExtensions/XuguDataAdapter.cs new file mode 100644 index 000000000..49cf97363 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/DataTableExtensions/XuguDataAdapter.cs @@ -0,0 +1,98 @@ +using System.Data; +using XuguClient; + +namespace SqlSugar.Xugu +{ + /// + /// 虚谷数据填充器 + /// + public class XuguDataAdapter : IDataAdapter + { + private string sql; + private XGConnection _sqlConnection; + private XGCommand command; + /// + /// 构造函数 + /// + public XuguDataAdapter() { } + /// + /// 构造函数 + /// + /// SQL命令 + public XuguDataAdapter(XGCommand command) => this.command = command; + /// + /// 构造函数 + /// + /// SQL语句 + /// 连接对象 + public XuguDataAdapter(string sql, XGConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + /// + /// 查询SQL命令对象 + /// + public XGCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = this._sqlConnection.CreateCommand(); + this.command.CommandText = sql; + } + return this.command; + } + set + { + this.command = value; + } + } + /// + /// 填充数据(当前集合) + /// + /// 填充目标DataTable + private DataTable Fill(XGDataReader dr, DataTable dt = null) + { + if (dt == null) dt = new DataTable(); + var columns = dt.Columns; + //构造列 + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + //重名时的处理 + if (!columns.Contains(name)) name += i; + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + } + //填充行 + while (dr.Read()) + { + DataRow row = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + row[columns[i].ColumnName] = dr.GetValue(i); + dt.Rows.Add(row); + } + dt.AcceptChanges(); + return dt; + } + /// + /// 填充数据(单个集合) + /// + /// 填充目标DataTable + public void Fill(DataTable dt) { using (var dr = command.ExecuteReader()) Fill(dt); } + /// + /// 填充数据(多个集合) + /// + /// 填充目标DataSet + public void Fill(DataSet ds) + { + if (ds == null) ds = new DataSet(); + using (var dr = command.ExecuteReader()) + { + do ds.Tables.Add(Fill(dr)); + while (dr.NextResult()); + } + } + } +} \ No newline at end of file diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/SqlSugar.XuguCore.csproj b/Src/Asp.NetCore2/SqlSugar.XuguCore/SqlSugar.XuguCore.csproj new file mode 100644 index 000000000..1e96aa945 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/SqlSugar.XuguCore.csproj @@ -0,0 +1,26 @@ + + + + netstandard2.1 + enable + True + SqlSugar操作 Xugu 虚谷数据库 + SqlSugar操作 Xugu 虚谷数据库 + dreamsfly900 + 1.0.3 + 北京知天智为气象科技有限公司 + + + + + + + + + + + + + + + diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ErrorMessage.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ErrorMessage.cs new file mode 100644 index 000000000..40f82f3e1 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ErrorMessage.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +namespace SqlSugar.Xugu +{ + internal static partial class ErrorMessage + { + internal static LanguageType SugarLanguageType { get; set; } = LanguageType.Default; + internal static string ObjNotExist + { + get + { + return GetThrowMessage("{0} does not exist.", + "{0}不存在。"); + } + } + internal static string EntityMappingError + { + get + { + return GetThrowMessage("Entity mapping error.{0}", + "实体与表映射出错。{0}"); + } + } + + public static string NotSupportedDictionary + { + get + { + return GetThrowMessage("This type of Dictionary is not supported for the time being. You can try Dictionary, or contact the author!!", + "暂时不支持该类型的Dictionary 你可以试试 Dictionary或者联系作者!!"); + } + } + + public static string NotSupportedArray + { + get + { + return GetThrowMessage("This type of Array is not supported for the time being. You can try object[] or contact the author!!", + "暂时不支持该类型的Array 你可以试试 object[] 或者联系作者!!"); + } + } + + internal static string GetThrowMessage(string enMessage, string cnMessage, params string[] args) + { + if (SugarLanguageType == LanguageType.Default) + { + List formatArgs = new List() { enMessage, cnMessage }; + formatArgs.AddRange(args); + return string.Format(@"中文提示 : {1} +English Message : {0}", formatArgs.ToArray()); + } + else if (SugarLanguageType == LanguageType.English) + { + return enMessage; + } + else + { + return cnMessage; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/FileHelper.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/FileHelper.cs new file mode 100644 index 000000000..254d5c583 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/FileHelper.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace SqlSugar.Xugu +{ + internal class FileHelper + { + public static void CreateFile(string filePath, string text, Encoding encoding) + { + try + { + if (IsExistFile(filePath)) DeleteFile(filePath); + if (!IsExistFile(filePath)) + { + string directoryPath = GetDirectoryFromFilePath(filePath); + CreateDirectory(directoryPath); + + FileInfo file = new FileInfo(filePath); + using (FileStream stream = file.Create()) + { + using (StreamWriter writer = new StreamWriter(stream, encoding)) + { + writer.Write(text); + writer.Flush(); + } + } + } + } + catch (Exception ex) + { + throw ex; + } + } + public static bool IsExistDirectory(string directoryPath) + { + return Directory.Exists(directoryPath); + } + public static void CreateDirectory(string directoryPath) + { + if (!IsExistDirectory(directoryPath)) Directory.CreateDirectory(directoryPath); + } + public static void DeleteFile(string filePath) + { + if (IsExistFile(filePath)) File.Delete(filePath); + } + public static string GetDirectoryFromFilePath(string filePath) + { + FileInfo file = new FileInfo(filePath); + DirectoryInfo directory = file.Directory; + return directory.FullName; + } + public static bool IsExistFile(string filePath)=> File.Exists(filePath); + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilConstants.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilConstants.cs new file mode 100644 index 000000000..d0adefdf0 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilConstants.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Text; +namespace SqlSugar.Xugu +{ + internal static class UtilConstants + { + 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 string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + + 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 ObjType = typeof(object); + internal static Type DobType = typeof(double); + internal static Type FloatType = typeof(float); + internal static Type ShortType = typeof(short); + internal static Type DecType = typeof(decimal); + internal static Type StringType = typeof(string); + internal static Type DateType = typeof(DateTime); + 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 DynamicType = typeof(ExpandoObject); + internal static Type Dicii = typeof(KeyValuePair); + internal static Type DicIS = typeof(KeyValuePair); + internal static Type DicSi = typeof(KeyValuePair); + internal static Type DicSS = typeof(KeyValuePair); + internal static Type DicOO = typeof(KeyValuePair); + internal static Type DicSo = typeof(KeyValuePair); + internal static Type DicArraySS = typeof(Dictionary); + internal static Type DicArraySO = typeof(Dictionary); + + public static Type SugarType = typeof(SqlSugarProvider); + + + internal static Type[] NumericalTypes = new Type[] + { + typeof(int), + typeof(uint), + typeof(byte), + typeof(sbyte), + typeof(long), + typeof(ulong), + typeof(short), + typeof(ushort), + }; + + + internal static string[] DateTypeStringList = new string[] + { + "Year", + "Month", + "Day", + "Hour", + "Second" , + "Minute", + "Millisecond", + "Date" + }; + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilExtensions.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilExtensions.cs new file mode 100644 index 000000000..1ceab74a8 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilExtensions.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +namespace SqlSugar.Xugu +{ + /// + ///Common Extensions for external users + /// + public static class UtilExtensions + { + public static bool EqualCase(this string thisValue, string equalValue) + { + if (thisValue != null && equalValue != null)return thisValue.ToLower() == equalValue.ToLower(); + else return thisValue == equalValue; + } + public static string ToLower(this string value, bool isLower) + { + if (isLower) return value.ObjToString().ToLower(); + return value.ObjToString(); + } + public static int ObjToInt(this object thisValue) + { + int reval = 0; + if (thisValue == null) return 0; + if (thisValue is Enum) return (int)thisValue; + if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) return reval; + return reval; + } + + public static int ObjToInt(this object thisValue, int errorValue) + { + int reval = 0; + if (thisValue is Enum) return (int)thisValue; + if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) return reval; + return errorValue; + } + + public static double ObjToMoney(this object thisValue) + { + double reval = 0; + if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) return reval; + return 0; + } + + public static double ObjToMoney(this object thisValue, double errorValue) + { + double reval = 0; + if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) return reval; + return errorValue; + } + + public static string ObjToString(this object thisValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return string.Empty; + } + + public static string ObjToString(this object thisValue, string errorValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return errorValue; + } + + public static Decimal ObjToDecimal(this object thisValue) + { + Decimal reval = 0; + if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) return reval; + return 0; + } + + public static Decimal ObjToDecimal(this object thisValue, decimal errorValue) + { + Decimal reval = 0; + if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) return reval; + return errorValue; + } + + public static DateTime ObjToDate(this object thisValue) + { + DateTime reval = DateTime.MinValue; + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) return reval; + return reval; + } + + public static DateTime ObjToDate(this object thisValue, DateTime errorValue) + { + DateTime reval = DateTime.MinValue; + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) return reval; + return errorValue; + } + + public static bool ObjToBool(this object thisValue) + { + bool reval = false; + if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval)) return reval; + return reval; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilMethods.cs new file mode 100644 index 000000000..747225c8b --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/UtilMethods.cs @@ -0,0 +1,398 @@ +using NetTaste; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar.Xugu +{ + public class UtilMethods + { + internal static DateTime GetMinDate(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.MoreSettings == null) return Convert.ToDateTime("1900-01-01"); + else if (currentConnectionConfig.MoreSettings.DbMinDate == null) return Convert.ToDateTime("1900-01-01"); + else return currentConnectionConfig.MoreSettings.DbMinDate.Value; + } + 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; + } + + internal static object To(object value, Type destinationType)=> To(value, destinationType, CultureInfo.InvariantCulture); + + internal static object To(object value, Type destinationType, CultureInfo culture) + { + if (value != null) + { + destinationType = UtilMethods.GetUnderType(destinationType); + var sourceType = value.GetType(); + + var destinationConverter = TypeDescriptor.GetConverter(destinationType); + if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) + return destinationConverter.ConvertFrom(null, culture, 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.IsInstanceOfType(value)) + return Convert.ChangeType(value, destinationType, culture); + } + return value; + } + public static bool IsAnyAsyncMethod(StackFrame[] methods) + { + bool isAsync = false; + foreach (var item in methods) + { + if (UtilMethods.IsAsyncMethod(item.GetMethod())) + { + isAsync = true; + break; + } + } + return isAsync; + } + + public static bool IsAsyncMethod(MethodBase method) + { + 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")) 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() + { + + 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() != '<') + { + info.MyStackTraceList.Add(new StackTraceInfoItem() + { + FileName = frame.GetFileName(), + MethodName = frame.GetMethod().Name, + Line = frame.GetFileLineNumber() + }); + } + else + { + info.SugarStackTraceList.Add(new StackTraceInfoItem() + { + FileName = frame.GetFileName(), + MethodName = frame.GetMethod().Name, + Line = frame.GetFileLineNumber() + }); + } + } + return info; + } + + internal static T To(object value)=> (T)To(value, typeof(T)); + internal static Type GetUnderType(Type oldType) + { + Type type = Nullable.GetUnderlyingType(oldType); + return type == null ? oldType : type; + } + 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 == 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 (!type.IsInterface && type.IsGenericType) + { + Type innerType = type.GetGenericArguments()[0]; + + if (innerType == typeof(TimeSpan) && value!=null) + { + if (value is DateTime) return ((DateTime)value).TimeOfDay; + if (value is DateTimeOffset) return ((DateTimeOffset)value).LocalDateTime.TimeOfDay; + } + + 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; + return Convert.ChangeType(value, type); + } + + internal static T ChangeType(T obj, Type type)=> (T)Convert.ChangeType(obj, type); + + internal static T ChangeType(T obj)=> (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 string GetPackTable(string sql, string shortName)=>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)=> value?.GetType().Name; + + internal static string GetParenthesesValue(string dbTypeName) + { + if (Regex.IsMatch(dbTypeName, @"\(.+\)")) dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", ""); + return dbTypeName.Trim(); + } + + internal static T GetOldValue(T value, Action action) + { + action(); + return value; + } + + internal static object DefaultForType(Type targetType)=> targetType.IsValueType ? Activator.CreateInstance(targetType) : null; + + internal static Int64 GetLong(byte[] bytes)=> Convert.ToInt64(string.Join("", bytes).PadRight(20, '0')); + public static object GetPropertyValue(T t, string PropertyName)=> 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 (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 (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 void DataInoveByExpresson(Type[] datas, MethodCallExpression callExpresion) + { + var methodInfo = callExpresion.Method; + foreach (var item in datas) + { + 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 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.XuguCore/Tools/ValidateExtensions.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ValidateExtensions.cs new file mode 100644 index 000000000..5c6abb0c5 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Tools/ValidateExtensions.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +namespace SqlSugar.Xugu +{ + internal static class ValidateExtensions + { + public static bool IsInRange(this int thisValue, int begin, int end)=> thisValue >= begin && thisValue <= end; + + public static bool IsInRange(this DateTime thisValue, DateTime begin, DateTime end)=> thisValue >= begin && thisValue <= end; + + public static bool IsIn(this T thisValue, params T[] values)=> values.Contains(thisValue); + + public static bool IsContainsIn(this string thisValue, params string[] inValues)=>inValues.Any(it => thisValue.Contains(it)); + + public static bool IsNullOrEmpty(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return true; + return thisValue.ToString() == ""; + } + + public static bool IsNullOrEmpty(this Guid? thisValue) + { + if (thisValue == null) return true; + return thisValue == Guid.Empty; + } + + public static bool IsNullOrEmpty(this Guid thisValue) + { + if (thisValue == null) return true; + return thisValue == Guid.Empty; + } + + public static bool IsNullOrEmpty(this IEnumerable thisValue) + { + if (thisValue == null || thisValue.Count() == 0) return true; + return false; + } + + public static bool HasValue(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return false; + return thisValue.ToString() != ""; + } + + public static bool HasValue(this IEnumerable thisValue) + { + if (thisValue == null || thisValue.Count() == 0) return false; + return true; + } + + public static bool IsValuable(this IEnumerable> thisValue) + { + if (thisValue == null || thisValue.Count() == 0) return false; + return true; + } + + public static bool IsZero(this object thisValue) => (thisValue == null || thisValue.ToString() == "0"); + + public static bool IsInt(this object thisValue) + { + if (thisValue == null) return false; + return Regex.IsMatch(thisValue.ToString(), @"^\d+$"); + } + + public static bool IsNoInt(this object thisValue) + { + if (thisValue == null) return true; + return !Regex.IsMatch(thisValue.ToString(), @"^\d+$"); + } + + public static bool IsMoney(this object thisValue) + { + if (thisValue == null) return false; + double outValue = 0; + return double.TryParse(thisValue.ToString(), out outValue); + } + public static bool IsGuid(this object thisValue) + { + if (thisValue == null) return false; + Guid outValue = Guid.Empty; + return Guid.TryParse(thisValue.ToString(), out outValue); + } + + public static bool IsDate(this object thisValue) + { + if (thisValue == null) return false; + DateTime outValue = DateTime.MinValue; + return DateTime.TryParse(thisValue.ToString(), out outValue); + } + + public static bool IsEamil(this object thisValue) + { + if (thisValue == null) return false; + return Regex.IsMatch(thisValue.ToString(), @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"); + } + + public static bool IsMobile(this object thisValue) + { + if (thisValue == null) return false; + return Regex.IsMatch(thisValue.ToString(), @"^\d{11}$"); + } + + public static bool IsTelephone(this object thisValue) + { + if (thisValue == null) return false; + return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}$"); + + } + + public static bool IsIDcard(this object thisValue) + { + if (thisValue == null) return false; + return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$"); + } + + public static bool IsFax(this object thisValue) + { + if (thisValue == null) return false; + return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$"); + } + + public static bool IsMatch(this object thisValue, string pattern) + { + if (thisValue == null) return false; + Regex reg = new Regex(pattern); + return reg.IsMatch(thisValue.ToString()); + } + public static bool IsAnonymousType(this Type type) + { + string typeName = type.Name; + return typeName.Contains("<>") && typeName.Contains("__") && typeName.Contains("AnonymousType"); + } + public static bool IsCollectionsList(this string thisValue) + { + return (thisValue + "").StartsWith("System.Collections.Generic.List")|| (thisValue + "").StartsWith("System.Collections.Generic.IEnumerable"); + } + public static bool IsStringArray(this string thisValue)=> (thisValue + "").IsMatch(@"System\.[a-z,A-Z,0-9]+?\[\]"); + public static bool IsEnumerable(this string thisValue)=> (thisValue + "").StartsWith("System.Linq.Enumerable"); + + public static Type StringType = typeof (string); + + public static bool IsClass(this Type thisValue)=> thisValue != StringType && thisValue.IsEntity() && thisValue != UtilConstants.ByteArrayType; + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/CodeFirst/XuguCodeFirst.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/CodeFirst/XuguCodeFirst.cs new file mode 100644 index 000000000..bb7a5b004 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/CodeFirst/XuguCodeFirst.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +namespace SqlSugar.Xugu +{ + public class XuguCodeFirst : CodeFirstProvider + { + protected override int DefultLength { get; set; } = -1; + public virtual bool IsNoTran { get; set; } = true; + public override void ExistLogic(EntityInfo entityInfo) + { + base.ExistLogic(entityInfo); + //this.Context.Ado.ExecuteCommand("select '不支持修改表' from dual "); + } + protected override void ConvertColumns(List dbColumns) + { + dbColumns.ForEach(d => { d.Length = 0;d.IsNullable = false; }); + } + protected override bool IsNoSamgeType(EntityColumnInfo ec, DbColumnInfo dc) + { + var o = new DbColumnInfo(); + GetDbType(ec, UtilMethods.GetUnderType(ec.PropertyInfo), o); + ec.DataType = o.DataType; + //if (ec.UnderType == UtilConstants.GuidType) ec.Length = 32; + if (ec.UnderType == UtilConstants.ByteArrayType) ec.DataType = "BINARY"; + if (ec.UnderType == UtilConstants.DateType) ec.DataType = "DATETIME"; + if (ec.UnderType == UtilConstants.DateTimeOffsetType) ec.DataType = "DATETIME WITH TIME ZONE"; + if (ec.UnderType == UtilConstants.FloatType) ec.DataType = "FLOAT"; + if (ec.UnderType == UtilConstants.DecType) ec.DataType = "DECIMAL"; + if (ec.UnderType == UtilConstants.StringType) ec.DataType = "VARCHAR"; + if (ec.UnderType == typeof(Version)) ec.DataType = "ROWVERSION"; + + if (!string.IsNullOrWhiteSpace(ec.DataType)) ec.DataType = ec.DataType.ToUpper(); + ec.IsNullable = Nullable.GetUnderlyingType(ec.PropertyInfo.PropertyType) != null + || !ec.PropertyInfo.PropertyType.IsValueType + || !UtilConstants.NumericalTypes.Contains(ec.PropertyInfo.PropertyType); + + return base.IsNoSamgeType(ec, dc); + } + + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var result = base.EntityColumnToDbColumn(entityInfo, tableName, item); + //if (item.UnderType == UtilConstants.GuidType) result.Length = 32; + if (item.UnderType == UtilConstants.ByteArrayType) result.DataType = "BINARY"; + if (item.UnderType == UtilConstants.DateType) result.DataType = "DATETIME"; + if (item.UnderType == UtilConstants.DateTimeOffsetType) result.DataType = "DATETIME WITH TIME ZONE"; + if (item.UnderType == UtilConstants.FloatType) result.DataType = "FLOAT"; + if (item.UnderType == UtilConstants.DecType) result.DataType = "DECIMAL"; + if (item.UnderType == UtilConstants.StringType) result.DataType = "VARCHAR"; + if (item.UnderType == typeof(Version)) result.DataType = "ROWVERSION"; + + if (!string.IsNullOrWhiteSpace(item.DataType)) result.DataType = item.DataType.ToUpper(); + result.IsNullable = Nullable.GetUnderlyingType(item.PropertyInfo.PropertyType) != null + || !item.PropertyInfo.PropertyType.IsValueType + || !UtilConstants.NumericalTypes.Contains(item.PropertyInfo.PropertyType); + return result; + } + protected override string GetTableName(EntityInfo entityInfo) + { + var table = this.Context.EntityMaintenance.GetTableName(entityInfo.EntityName); + var tableArray = table.Split('.'); + var noFormat = table.Split(']').Length == 1; + if (tableArray.Length > 1 && noFormat) + { + var dbMain = new XuguDbMaintenance() { Context = this.Context }; + return dbMain.SqlBuilder.GetTranslationTableName(table); + } + return table; + } + + protected override void ExistLogicEnd(List dbColumns) + { + foreach (EntityColumnInfo column in dbColumns) + { + if (column.DefaultValue != null) + { + this.Context.DbMaintenance.AddDefaultValue(column.DbTableName, column.DbColumnName, column.DefaultValue.ToSqlValue()); + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + string keyName = this.Context.Ado.GetString(@$"SELECT I.INDEX_NAME FROM USER_INDEXES I +LEFT JOIN USER_TABLES T ON I.TABLE_ID=T.TABLE_ID +WHERE T.TABLE_NAME='{tableName}' AND FIND_IN_SET('""{item.DbColumnName}""',I.KEYS)>0 AND T.DB_ID=CURRENT_DB_ID + AND T.USER_ID=CURRENT_USERID AND T.SCHEMA_ID=CURRENT_SCHEMAID"); + if (!item.IsPrimarykey && !string.IsNullOrWhiteSpace(keyName)) + this.Context.DbMaintenance.DropConstraint(tableName, keyName); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbBind/XuguDbBind.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbBind/XuguDbBind.cs new file mode 100644 index 000000000..c55eec73e --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbBind/XuguDbBind.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +namespace SqlSugar.Xugu +{ + public class XuguDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) => csharpTypeName == nameof(DateTimeOffset) ? nameof(DateTimeOffset) : base.GetDbTypeName(csharpTypeName); + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService != null && extService.AppendDataReaderTypeMappings.HasValue()) + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + else + return MappingTypesConst; + } + } + public static List> MappingTypesConst = new List>() + { + new KeyValuePair("BIGINT",CSharpDataType.@long), + new KeyValuePair("BINARY",CSharpDataType.@byteArray), + new KeyValuePair("BLOB",CSharpDataType.@object), + new KeyValuePair("BOOLEAN",CSharpDataType.@bool), + new KeyValuePair("CHAR",CSharpDataType.@string), + new KeyValuePair("CLOB",CSharpDataType.@string), + new KeyValuePair("DATE", CSharpDataType.DateTime), + new KeyValuePair("DATETIME", CSharpDataType.DateTime), + new KeyValuePair("DATETIME WITH TIME ZONE", CSharpDataType.DateTimeOffset), + new KeyValuePair("DECIMAL", CSharpDataType.@decimal), + new KeyValuePair("DOUBLE", CSharpDataType.@double), + new KeyValuePair("FLOAT", CSharpDataType.@float), + new KeyValuePair("GUID", CSharpDataType.Guid), + new KeyValuePair("INT", CSharpDataType.@int), + new KeyValuePair("INTEGER", CSharpDataType.@int), + new KeyValuePair("INTERVAL YEAR", CSharpDataType.@string), + new KeyValuePair("INTERVAL YEAR TO MONTH", CSharpDataType.@string), + new KeyValuePair("INTERVAL MONTH", CSharpDataType.@string), + new KeyValuePair("INTERVAL DAY", CSharpDataType.@string), + new KeyValuePair("INTERVAL DAY TO HOUR", CSharpDataType.@string), + new KeyValuePair("INTERVAL DAY TO MINUTE", CSharpDataType.@string), + new KeyValuePair("INTERVAL DAY TO SECOND", CSharpDataType.@string), + new KeyValuePair("INTERVAL HOUR", CSharpDataType.@string), + new KeyValuePair("INTERVAL HOUR TO MINUTE", CSharpDataType.@string), + new KeyValuePair("INTERVAL HOUR TO SECOND", CSharpDataType.@string), + new KeyValuePair("INTERVAL MINUTE", CSharpDataType.@string), + new KeyValuePair("INTERVAL MINUTE TO SECOND", CSharpDataType.@string), + new KeyValuePair("INTERVAL SECOND", CSharpDataType.@string), + new KeyValuePair("NCHAR", CSharpDataType.@string), + new KeyValuePair("NUMERIC", CSharpDataType.@decimal), + new KeyValuePair("NVARCHAR", CSharpDataType.@string), + new KeyValuePair("ROWID", CSharpDataType.@string), + new KeyValuePair("ROWVERSION", CSharpDataType.@object),//需要手动修改为System.Version + new KeyValuePair("TIME", CSharpDataType.TimeSpan), + new KeyValuePair("TIME WITH TIME ZONE", CSharpDataType.TimeSpan), + new KeyValuePair("TIMESTAMP", CSharpDataType.DateTime), + new KeyValuePair("TIMESTAMP AUTO UPDATE", CSharpDataType.DateTime), + new KeyValuePair("TINYINT", CSharpDataType.@sbyte), + new KeyValuePair("VARCHAR", CSharpDataType.@string), + }; + }; + + public class DateTimeOffsetConvert : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + string name = ":XuguParam" + columnIndex; + Type underType = UtilMethods.GetUnderType(typeof(T)); + return new SugarParameter(name, columnValue, underType); + } + public T QueryConverter(IDataRecord dr, int i) + { + var value = dr.GetString(i); + if (DateTimeOffset.TryParse(value, out DateTimeOffset o)) return (T)UtilMethods.ChangeType2(o, typeof(T)); + else return default(T); + } + } +} +/*生成模型类后需要手动修改的地方。所以尽量少使用rowid\rowversion\blob\time\time with time zone\datetime with time zone 这几种类型 + * +====================================================================================== +//增加特性配置 +[SugarColumn(SqlParameterDbType = typeof(DateTimeOffsetConvert))] +public TimeSpan? C_TIME { get; set; } + +[SugarColumn(SqlParameterDbType = typeof(DateTimeOffsetConvert))] +public TimeSpan C_TIME_WITH_TIME_ZONE { get; set; } + +[SugarColumn(SqlParameterDbType = typeof(DateTimeOffsetConvert))] +public DateTimeOffset C_DATETIME_WITH_TIME_ZONE { get; set; } +======================================================================================可以使用类型BINARY +//增加特性配置,写值可以写byte[]或者XGBlob +[SugarColumn(SqlParameterDbType = typeof(CommonPropertyConvert))] +public object C_BLOB { get; set; } +======================================================================================尽量不使用 +//上传内容为ANSI编码读取 +public string C_CLOB { get; set; } +//手动修改为类型Version +public Version C_ROWVERSION { get; set; } +*/ \ No newline at end of file diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbFirst/XuguDbFirst.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbFirst/XuguDbFirst.cs new file mode 100644 index 000000000..d61c65b3d --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbFirst/XuguDbFirst.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar.Xugu +{ + public class XuguDbFirst : DbFirstProvider { } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbMaintenance/XuguDbMaintenance.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbMaintenance/XuguDbMaintenance.cs new file mode 100644 index 000000000..5816e4677 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/DbMaintenance/XuguDbMaintenance.cs @@ -0,0 +1,334 @@ +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using static Npgsql.Replication.PgOutput.Messages.RelationMessage; + +namespace SqlSugar.Xugu +{ + public class XuguDbMaintenance : DbMaintenanceProvider + { + #region DML + /// + /// 列出所有数据库名 + /// + protected override string GetDataBaseSql => "SELECT DB_NAME FROM USER_DATABASES"; + /// + /// 列出指定表所有的列属性 + /// + protected override string GetColumnInfosByTableNameSql + { + get + { + //重命名的列必须经过处理,否则会找不到(官方DLL的BUG) + string sql = @"SELECT C.TABLE_ID+0 `TABLEID`, + TRIM(T.TABLE_NAME) `TABLENAME`, + TRIM(C.COL_NAME) `DBCOLUMNNAME`, + TRIM(C.TYPE_NAME) `DATATYPE`, + CASE WHEN C.SCALE>=65536 THEN -1 ELSE C.SCALE END `LENGTH`, + TRIM(C.DEF_VAL) `DEFAULTVALUE`, + TRIM(C.COMMENTS) `COLUMNDESCRIPTION`, + CASE WHEN C.SCALE>=65536 THEN FLOOR(C.SCALE / 65536) ELSE -1 END `SCALE`, + CASE WHEN C.SCALE>=65536 THEN C.SCALE - FLOOR(C.SCALE / 65536)*65536 ELSE -1 END `DECIMALDIGITS`, + CASE WHEN C.NOT_NULL THEN FALSE ELSE TRUE END `ISNULLABLE`, + CASE WHEN C.IS_SERIAL THEN TRUE ELSE FALSE END `ISIDENTITY`, + CASE WHEN I.IS_PRIMARY THEN TRUE ELSE FALSE END `ISPRIMARYKEY` +FROM USER_COLUMNS C +LEFT JOIN USER_TABLES T ON T.TABLE_ID=C.TABLE_ID +LEFT JOIN USER_INDEXES I ON T.TABLE_ID=I.TABLE_ID AND I.KEYS LIKE '%""'+C.COL_NAME+'""%' +WHERE T.TABLE_NAME='{0}' AND T.DB_ID=CURRENT_DB_ID + AND T.USER_ID=CURRENT_USERID AND T.SCHEMA_ID=CURRENT_SCHEMAID +ORDER BY C.COL_NO";//FIND_IN_SET('""'+C.COL_NAME+'""',I.KEYS)>0 + return sql; + } + } + /// + /// 获取用户所有表名、描述 + /// + protected override string GetTableInfoListSql=> "SELECT TRIM(TABLE_NAME) name,TRIM(COMMENTS) Description FROM USER_TABLES"; + /// + /// 获取用户所有视图名、描述 + /// + protected override string GetViewInfoListSql=> "SELECT TRIM(VIEW_NAME) name,TRIM(COMMENTS) Description FROM USER_VIEWS"; + #endregion + + #region DDL + /// + /// 创建数据库 + /// + protected override string CreateDataBaseSql => "CREATE DATABASE {0} "; + protected override string AddPrimaryKeySql=> "ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY({2})"; + protected override string AddColumnToTableSql=> "ALTER TABLE {0} ADD COLUMN {1} {2}{3} @IDENT@{6} @PK@{5} {4}"; + protected override string AlterColumnToTableSql=> "ALTER TABLE {0} ALTER COLUMN {1} {2}{3} @IDENT@{6} @PK@{5} {4}"; + /// + /// 备份数据库,文件路径为服务器上相对于XHOME的路径 + /// + protected override string BackupDataBaseSql => "BACKUP DATABASE TO '{1}'"; + protected override string CreateTableSql=> "CREATE TABLE {0}(\r\n{1})"; + protected override string CreateTableColumn=> "{0} {1}{2} {3} {4} {5}"; + /// + /// 清空表 + /// + protected override string TruncateTableSql=> "TRUNCATE TABLE {0}"; + protected override string BackupTableSql=> "SELECT TOP {0} * INTO {1} FROM {2}"; + protected override string DropTableSql=> "DROP TABLE {0}"; + protected override string DropColumnToTableSql=> "ALTER TABLE {0} DROP COLUMN {1}"; + protected override string DropConstraintSql=> "ALTER TABLE {0} DROP CONSTRAINT {1}"; + protected override string RenameColumnSql => "ALTER TABLE {0} RENAME COLUMN {1} TO {2}"; + protected override string AddColumnRemarkSql => "COMMENT ON COLUMN {1}.{0} IS '{2}'"; + + protected override string DeleteColumnRemarkSql => "COMMENT ON COLUMN {1}.{0} IS ''"; + + protected override string IsAnyColumnRemarkSql + { + get + { + return @"SELECT T.TABLE_NAME AS table_name,C.COL_NAME AS column_name,C.COMMENTS AS column_description +FROM USER_COLUMNS C +LEFT JOIN USER_TABLES T ON T.TABLE_ID=C.TABLE_ID +WHERE T.TABLE_NAME='{1}' AND C.COL_NAME='{0}' AND T.DB_ID=CURRENT_DB_ID + AND T.USER_ID=CURRENT_USERID AND T.SCHEMA_ID=CURRENT_SCHEMAID"; + + } + } + + protected override string AddTableRemarkSql=> "COMMENT ON TABLE {0} IS '{1}'"; + + protected override string DeleteTableRemarkSql=> "COMMENT ON TABLE {0} IS ''"; + + protected override string IsAnyTableRemarkSql + { + get + { + return @"SELECT TRIM(COMMENTS) class_desc +FROM USER_TABLES T +WHERE T.TABLE_NAME='{0}' AND T.DB_ID=CURRENT_DB_ID + AND T.USER_ID=CURRENT_USERID AND T.SCHEMA_ID=CURRENT_SCHEMAID"; + } + + } + + protected override string RenameTableSql => "ALTER TABLE {0} RENAME TO {1}"; + + protected override string CreateIndexSql=> "CREATE {3} INDEX IX_{0}_{2} ON {0}({1})";//NONCLUSTERED + protected override string AddDefaultValueSql=> "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT '{2}'"; + protected override string IsAnyIndexSql => "SELECT COUNT(*) FROM USER_INDEXES WHERE INDEX_NAME='{0}'"; + #endregion + + #region Check + /// + /// 判断是否能够读取系统表user_tables + /// + protected override string CheckSystemTablePermissionsSql=> "SELECT TOP 1 * FROM USER_TABLES"; + #endregion + + #region Scattered + protected override string CreateTableNull=> string.Empty;// "NULL"; + protected override string CreateTableNotNull=> "NOT NULL"; + protected override string CreateTablePirmaryKey=> " PRIMARY KEY "; + protected override string CreateTableIdentity=> " IDENTITY ";//(1,1) + #endregion + + #region Methods + //public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + //{ + // string cacheKey = "DbMaintenanceProvider.GetColumnInfosByTableName." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower(); + // cacheKey = GetCacheKey(cacheKey); + // if (!isCache) + // return GetColumnInfosByTableName(tableName); + // else + // return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + // () => + // { + // return GetColumnInfosByTableName(tableName); + + // }); + //} + + private List GetColumnInfosByTableName(string tableName) + { + string sql = "select * /* " + Guid.NewGuid() + " */ from " + SqlBuilder.GetTranslationTableName(tableName) + " WHERE 1=2 "; + this.Context.Utilities.RemoveCache>("DbMaintenanceProvider.GetFieldComment." + tableName); + this.Context.Utilities.RemoveCache>("DbMaintenanceProvider.GetPrimaryKeyByTableNames." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower()); + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + using (var reader = this.Context.Ado.GetDataReader(sql)) + { + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + List result = new List(); + var schemaTable = reader.GetSchemaTable(); + int i = 0; + foreach (System.Data.DataRow row in schemaTable.Rows) + { + DbColumnInfo column = new DbColumnInfo() + { + TableName = tableName, + DataType = row["DataType"].ToString().Replace("System.", "").Trim(), + IsNullable = (bool)row["AllowDBNull"], + IsIdentity = (bool)row["IsAutoIncrement"], + // ColumnDescription = GetFieldComment(tableName, row["ColumnName"].ToString()), + DbColumnName = row["ColumnName"].ToString(), + //DefaultValue = row["defaultValue"].ToString(), + IsPrimarykey = i == 0,//no support get pk + Length = row["ColumnSize"].ObjToInt(), + Scale = row["numericscale"].ObjToInt() + }; + ++i; + result.Add(column); + } + return result; + } + } + protected override string GetCreateTableSql(string tableName, List columns) + { + List columnArray = new List(); + Check.Exception(columns.IsNullOrEmpty(), "No columns found "); + foreach (var item in columns) + { + string columnName = this.SqlBuilder.GetTranslationTableName(item.DbColumnName); + string dataType = item.DataType; + string dataSize = GetSize(item); + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + if (item.IsIdentity && item.IsPrimarykey) + { + dataSize = ""; + dataType += this.CreateTableIdentity + this.CreateTablePirmaryKey; + } + else if (item.IsIdentity) + { + dataSize = ""; + dataType += this.CreateTableIdentity; + } + else if (item.IsPrimarykey) + { + dataType = (dataType + dataSize + this.CreateTablePirmaryKey); + dataSize = ""; + } + //string identity = item.IsIdentity ? this.CreateTableIdentity : null; + string addItem = string.Format(this.CreateTableColumn, columnName, dataType, dataSize, nullType, "", ""); + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",\r\n", columnArray)); + return tableString; + } + + + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue == "''") + { + defaultValue = ""; + } + var template = AddDefaultValueSql; + if (defaultValue != null && defaultValue.ToLower() == "SYSDATE") + { + template = template.Replace("'{2}'", "{2}"); + } + string sql = string.Format(template, tableName, columnName, defaultValue); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + + /// + ///by current connection string + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + throw new NotSupportedException(); + } + public override void AddDefaultValue(EntityInfo entityInfo) + { + + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + foreach (var item in columns) + { + if (item.DataType == "decimal" && item.DecimalDigits == 0 && item.Length == 0) + { + item.DecimalDigits = 4; + item.Length = 18; + } + } + string sql = GetCreateTableSql(tableName, columns); + this.Context.Ado.ExecuteCommand(sql); + //if (isCreatePrimaryKey) + //{ + // var pkColumns = columns.Where(it => it.IsPrimarykey).ToList(); + // if (pkColumns.Count > 1) + // { + // this.Context.DbMaintenance.AddPrimaryKeys(tableName, pkColumns.Select(it => it.DbColumnName).ToArray()); + // } + // else + // { + // foreach (var item in pkColumns) + // { + // this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + // } + // } + //} + return true; + } + //public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + //{ + // tableName = SqlBuilder.GetNoTranslationColumnName(tableName); + // var result= base.GetColumnInfosByTableName(tableName, isCache); + // return result; + //} + public override bool RenameColumn(string tableName, string oldColumnName, string newColumnName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + oldColumnName = this.SqlBuilder.GetTranslationColumnName(oldColumnName); + newColumnName = this.SqlBuilder.GetNoTranslationColumnName(newColumnName); + string sql = string.Format(this.RenameColumnSql, tableName, oldColumnName, newColumnName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + protected override string GetAddColumnSql(string tableName, DbColumnInfo columnInfo) + { + return base.GetAddColumnSql(tableName, columnInfo) + .Replace("@IDENT@", columnInfo.IsIdentity?this.CreateTableIdentity:string.Empty) + .Replace("@PK@", columnInfo.IsPrimarykey ? this.CreateTablePirmaryKey : string.Empty); + } + protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + return base.GetUpdateColumnSql(tableName, columnInfo) + .Replace("@IDENT@", columnInfo.IsIdentity ? this.CreateTableIdentity : string.Empty) + .Replace("@PK@", columnInfo.IsPrimarykey ? this.CreateTablePirmaryKey : string.Empty); + } + public override bool UpdateColumn(string tableName, DbColumnInfo column) + { + try + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string sql = GetUpdateColumnSql(tableName, column); + Console.WriteLine(sql); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + catch { + //Console.WriteLine($"修改数据库列{tableName}.{column.DbColumnName}发生异常"); + return false; + } + } + public override bool AddPrimaryKey(string tableName, string columnName) + { + try + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + columnName = this.SqlBuilder.GetTranslationTableName(columnName); + string sql = string.Format(this.AddPrimaryKeySql, tableName, string.Format("PK_{0}_{1}", this.SqlBuilder.GetNoTranslationColumnName(tableName), this.SqlBuilder.GetNoTranslationColumnName(columnName)), columnName); + Console.WriteLine(sql); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + catch { + //Console.WriteLine($"添加主键 PK_{tableName}_{columnName}发生异常"); + return false; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/Queryable/XuguQueryable.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/Queryable/XuguQueryable.cs new file mode 100644 index 000000000..64f357423 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/Queryable/XuguQueryable.cs @@ -0,0 +1,58 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar.Xugu +{ + public class XuguQueryable:QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } + public class XuguQueryable : QueryableProvider + { + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBlukCopy.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBlukCopy.cs new file mode 100644 index 000000000..ed0d78afc --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBlukCopy.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Data; +using Microsoft.Data.SqlClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.Xugu +{ + public class XuguBlukCopy + { + internal List> DbColumnInfoList { get; set; } + internal SqlSugarProvider Context { get; set; } + internal ISqlBuilder Builder { get; set; } + internal InsertBuilder InsertBuilder { get; set; } + internal object[] Inserts { get; set; } + + public int ExecuteBulkCopy() + { + if (DbColumnInfoList == null || DbColumnInfoList.Count == 0) return 0; + + if (Inserts.First().GetType() == typeof(DataTable)) return WriteToServer(); + DataTable dt = GetCopyData(); + SqlBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString; + try + { + bulkCopy.WriteToServer(dt); + } + catch (Exception ex) + { + CloseDb(); + throw ex; + } + CloseDb(); + return DbColumnInfoList.Count; + } + + public async Task ExecuteBulkCopyAsync() + { + if (DbColumnInfoList == null || DbColumnInfoList.Count == 0) return 0; + + if (Inserts.First().GetType() == typeof(DataTable)) return WriteToServer(); + DataTable dt=GetCopyData(); + SqlBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString; + try + { + await bulkCopy.WriteToServerAsync(dt); + } + catch (Exception ex) + { + CloseDb(); + throw ex; + } + CloseDb(); + return DbColumnInfoList.Count; + } + + private int WriteToServer() + { + var dt = this.Inserts.First() as DataTable; + if (dt == null) return 0; + + Check.Exception(dt.TableName == "Table", "dt.TableName can't be null "); + dt = GetCopyWriteDataTable(dt); + SqlBulkCopy copy = GetBulkCopyInstance(); + copy.DestinationTableName = this.Builder.GetTranslationColumnName(dt.TableName); + copy.WriteToServer(dt); + CloseDb(); + return dt.Rows.Count; + } + private DataTable GetCopyWriteDataTable(DataTable dt) + { + var result = this.Context.Ado.GetDataTable("select top 0 * from " + this.Builder.GetTranslationColumnName(dt.TableName)); + foreach (DataRow item in dt.Rows) + { + DataRow dr= result.NewRow(); + foreach (DataColumn column in result.Columns) + { + if (dt.Columns.Cast().Select(it => it.ColumnName.ToLower()).Contains(column.ColumnName.ToLower())) + { + dr[column.ColumnName] = item[column.ColumnName]; + if (dr[column.ColumnName] == null) dr[column.ColumnName] = DBNull.Value; + } + } + result.Rows.Add(dr); + } + result.TableName = dt.TableName; + return result; + } + private SqlBulkCopy GetBulkCopyInstance() + { + SqlBulkCopy copy; + if (this.Context.Ado.Transaction == null) + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection); + else + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.CheckConstraints, (SqlTransaction)this.Context.Ado.Transaction); + if (this.Context.Ado.Connection.State == ConnectionState.Closed) this.Context.Ado.Connection.Open(); + copy.BulkCopyTimeout = this.Context.Ado.CommandTimeOut; + return copy; + } + private DataTable GetCopyData() + { + var dt = this.Context.Ado.GetDataTable("select top 0 * from " + InsertBuilder.GetTableNameString); + foreach (var rowInfos in DbColumnInfoList) + { + var dr = dt.NewRow(); + foreach (var value in rowInfos) + { + if (value.Value != null && UtilMethods.GetUnderType(value.Value.GetType()) == UtilConstants.DateType) + { + if (value.Value != null && value.Value.ToString() == DateTime.MinValue.ToString()) + value.Value = Convert.ToDateTime("1753/01/01"); + } + if (value.Value == null) value.Value = DBNull.Value; + dr[value.DbColumnName] = value.Value; + } + dt.Rows.Add(dr); + } + return dt; + } + private void CloseDb() + { + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) this.Context.Ado.Connection.Close(); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBuilder.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBuilder.cs new file mode 100644 index 000000000..22a19e4a9 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguBuilder.cs @@ -0,0 +1,29 @@ +using System; +using System.Linq; + +namespace SqlSugar.Xugu +{ + public class XuguBuilder : SqlBuilderProvider + { + public override string SqlParameterKeyWord => ":"; + public override string SqlTranslationLeft { get; } =string.Empty; + public override string SqlTranslationRight { get; } = string.Empty; + public override string GetNoTranslationColumnName(string name) => name; + public override string SqlDateNow { get; } = "SYSDATE"; + public override string FullSqlDateNow { get; } = "SELECT SYSDATE FROM DUAL"; + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(ErrorMessage.ObjNotExist, "Table Name")); + if (!name.Contains("<>f__AnonymousType") && name.IsContainsIn("(", ")") && name != "Dictionary`2") return name; + if (Context.MappingTables == null) return name; + var context = this.Context; + var mappingInfo = context + .MappingTables + .FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase)); + name = (mappingInfo == null ? name : mappingInfo.DbTableName); + if (name.IsContainsIn("(", ")", SqlTranslationLeft)) return name; + if (name.Contains(".")) return string.Join(".", name.Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + else return SqlTranslationLeft + name + SqlTranslationRight; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguDeleteBuilder.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguDeleteBuilder.cs new file mode 100644 index 000000000..930594f66 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguDeleteBuilder.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.Xugu +{ + public class XuguDeleteBuilder : DeleteBuilder { } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguExpressionContext.cs new file mode 100644 index 000000000..1cb5c4d38 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguExpressionContext.cs @@ -0,0 +1,97 @@ +using System; + +namespace SqlSugar.Xugu +{ + public partial class XuguExpressionContext : ExpressionContext, ILambdaExpressions + { + public override string SqlParameterKeyWord => ":"; + public SqlSugarProvider Context { get; set; } + public XuguExpressionContext() => base.DbMehtods = new XuguMethod(); + public override string SqlTranslationLeft { get; } = string.Empty; + public override string SqlTranslationRight { get; } = string.Empty; + public override bool IsTranslationText(string name)=> name.IsContainsIn(UtilConstants.Space, "(", ")"); + public override string GetLimit() => ""; + } + public partial class XuguMethod : DefaultDbMethod, IDbMethods + { + public override string ParameterKeyWord { get; set; } = ":"; + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0}) ", parameter.MemberName); + } + + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("NVL({0},{1})", parameter.MemberName, parameter1.MemberName); + } + + public override string MergeString(params string[] strings)=> string.Join("||", strings); + + public override string GetRandom()=> " SYS_GUID() "; + public override string GetForXmlPath() => null;// " FOR XML PATH('')),1,len(N','),'') "; + public override string GetStringJoinSelector(string result, string separator)=> $"REPLACE(WM_CONCAT({result}),',','{separator}')"; + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var type = (DateType)Enum.Parse(typeof(DateType), parameter2.MemberValue.ObjToString(), false); + switch (type) + { + case DateType.Year: return $"GETYEAR({parameter.MemberName})"; + case DateType.Month: return $"GETMONTH({parameter.MemberName})"; + case DateType.Day: return $"GETDAY({parameter.MemberName})"; + case DateType.Hour: return $"GETHOUR({parameter.MemberName})"; + case DateType.Minute: return $"GETMINUTE({parameter.MemberName})"; + case DateType.Second: return $"GETSECOND({parameter.MemberName})"; + case DateType.Weekday: return $"DAYOFWEEK({parameter.MemberName})"; + case DateType.Quarter: return $"CEIL(GETMONTH({parameter.MemberName})/3)"; + case DateType.Millisecond: + default: return $"DAYOFYEAR({parameter.MemberName})"; + } + } + public override string GetDate() => " SYSDATE "; + public override string HasValue(MethodCallExpressionModel model) + { + if (model.Args[0].Type == UtilConstants.GuidType) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL )", parameter.MemberName); + } + else + { + var parameter = model.Args[0]; + return string.Format("( {0}<>'' AND {0} IS NOT NULL )", parameter.MemberName); + } + } + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format("INSTR ({0},{1},1,1) ", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string Contains(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like '%'||{1}||'%') ", parameter.MemberName, parameter2.MemberName); + } + public override string StartsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like {1}||'%') ", parameter.MemberName, parameter2.MemberName); + } + public override string EndsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like '%'||{1}) ", parameter.MemberName, parameter2.MemberName); + } + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS NVARCHAR)", parameter.MemberName); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguFastBuilder.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguFastBuilder.cs new file mode 100644 index 000000000..354bf0d67 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguFastBuilder.cs @@ -0,0 +1,44 @@ +using Microsoft.Data.SqlClient; +using System; +using System.Data; +using System.Threading.Tasks; + +namespace SqlSugar.Xugu +{ + + public class XuguFastBuilder:FastBuilder,IFastBuilder + { + public override bool IsActionUpdateColumns { get; set; } = true; + public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() { + HasOffsetTime=true + }; + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + + SqlBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = dt.TableName; + try + { + await bulkCopy.WriteToServerAsync(dt); + } + catch (Exception ex) + { + CloseDb(); + throw ex; + } + CloseDb(); + return dt.Rows.Count; + } + public SqlBulkCopy GetBulkCopyInstance() + { + SqlBulkCopy copy; + if (this.Context.Ado.Transaction == null) + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection); + else + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.CheckConstraints, (SqlTransaction)this.Context.Ado.Transaction); + if (this.Context.Ado.Connection.State == ConnectionState.Closed) this.Context.Ado.Connection.Open(); + copy.BulkCopyTimeout = this.Context.Ado.CommandTimeOut; + return copy; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguInsertBuilder.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguInsertBuilder.cs new file mode 100644 index 000000000..a0fde1df3 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguInsertBuilder.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.Xugu +{ + public class XuguInsertBuilder : InsertBuilder + { + public override string SqlTemplateBatch { get; } = "INSERT into {0} ({1})"; + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) RETURNING $PrimaryKey未实现返回主键 " + UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", ""); + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) " + UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", ""); + } + } + } + public override string GetTableNameString + { + get + { + var result = Builder.GetTranslationTableName(EntityInfo.EntityName); + result += UtilConstants.Space; + if (this.TableWithString.HasValue()) result += TableWithString + UtilConstants.Space; + return result; + } + } + public override string ToSqlString() + { + if (IsNoInsertNull) DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList(); + var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList(); + var isSingle = groupList.Count() == 1; + string columnsString = string.Join(",", groupList.First().Select(it => Builder.GetTranslationColumnName(it.DbColumnName))); + if (isSingle) + { + string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => base.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName))); + return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = groupList.Count; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + batchInsetrSql.AppendFormat("SELECT * FROM ("); + int i = 0; + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) batchInsetrSql.Append(SqlTemplateBatchUnion); + batchInsetrSql.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, base.GetDbColumn(it, FormatValue(it.Value)), Builder.GetTranslationColumnName(it.DbColumnName)))) + " from dual"); + ++i; + } + pageIndex++; + batchInsetrSql.Append(") temp1\r\n;\r\n"); + } + return batchInsetrSql.ToString();// + " GETID "; + } + } + public override object FormatValue(object value) + { + var n = ""; + if (value == null) return "NULL"; + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) return GetDateTimeString(value); + else if (value is DateTimeOffset) return GetDateTimeOffsetString(value); + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value).Replace("-", ""); + return bytesString; + } + else if (type.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) return value.ToSqlValue(); + else return Convert.ToInt64(value); + } + else if (type == UtilConstants.BoolType) return value.ObjToBool() ? "1" : "0"; + else return n + "'" + value + "'"; + } + private object GetDateTimeOffsetString(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + if (date < UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig)) + date = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + + private object GetDateTimeString(object value) + { + var date = value.ObjToDate(); + if (date < UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig)) + date = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguQueryBuilder.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguQueryBuilder.cs new file mode 100644 index 000000000..2c7e4fc96 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguQueryBuilder.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace SqlSugar.Xugu +{ + public class XuguQueryBuilder: QueryBuilder + { + #region Sql Template + /* SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 0,10 */ + public override string PageTempalte { get; }= "SELECT {0} FROM {1} {2} {3} {4} LIMIT {5},{6}"; + public override string DefaultOrderByTemplate { get; } = "ORDER BY SYSDATE "; + #endregion + + #region Common Methods + public override bool IsComplexModel(string sql)=> Regex.IsMatch(sql, @"AS \`\w+\.\w+\`") || Regex.IsMatch(sql, @"AS \`\w+\.\w+\.\w+\`"); + public override string ToSqlString() + { + base.AppendFilter(); + string oldOrderValue = this.OrderByValue; + string result = null; + sql = new StringBuilder(); + sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString); + if (IsCount) { return sql.ToString(); } + if (Skip != null && Take == null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString, Skip.ObjToInt(), long.MaxValue); + } + else if (Skip == null && Take != null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt()); + } + else if (Skip != null && Take != null) + { + if (Skip == 0 && Take == 1 && this.OrderByValue == "ORDER BY SYSDATE ") this.OrderByValue = null; + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take); + } + else + { + result = sql.ToString(); + } + this.OrderByValue = oldOrderValue; + result = GetSqlQuerySql(result); + if (result.IndexOf("-- No table") > 0) return "-- No table"; + if (TranLock != null) result = result + TranLock; + return result; + } + private string ToCountSqlString() + { + //base.AppendFilter(); + string oldOrderValue = this.OrderByValue; + string result = null; + sql = new StringBuilder(); + sql.AppendFormat(SqlTemplate, "COUNT(*)", GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString); + if (IsCount) + { + if (sql.ToString().Contains("-- No table")) return "-- No table"; + return sql.ToString(); + } + if (Skip != null && Take == null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString, Skip.ObjToInt(), long.MaxValue); + } + else if (Skip == null && Take != null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt()); + } + else if (Skip != null && Take != null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take); + } + else + { + result = sql.ToString(); + } + this.OrderByValue = oldOrderValue; + return result; + } + public override string ToCountSql(string sql) + { + if (this.GroupByValue.HasValue() || this.IsDistinct) return base.ToCountSql(sql); + else return ToCountSqlString(); + } + #endregion + + #region Get SQL Partial + public override string GetSelectValue + { + get + { + string result = string.Empty; + if (this.SelectValue == null || this.SelectValue is string) result = GetSelectValueByString(); + else result = GetSelectValueByExpression(); + if (this.SelectType == ResolveExpressType.SelectMultiple) + this.SelectCacheKey = this.SelectCacheKey + string.Join("-", this.JoinQueryInfos.Select(it => it.TableName)); + if (IsDistinct) result = " DISTINCT " + result; + if (this.SubToListParameters != null && this.SubToListParameters.Any()) result = SubToListMethod(result); + return result; + } + } + #endregion + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguUpdateBuilder.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguUpdateBuilder.cs new file mode 100644 index 000000000..c5db51497 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/SqlBuilder/XuguUpdateBuilder.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace SqlSugar.Xugu +{ + public class XuguUpdateBuilder : UpdateBuilder + { + protected override string TomultipleSqlString(List> groupList) + { + if (groupList == null || groupList.Count == 0) return "SELECT 0 FROM DUAL"; + StringBuilder sb = new StringBuilder(); + int i = 0; + sb.AppendLine(string.Join(UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", ""), groupList.Select(t => + { + var updateTable = string.Format("UPDATE {0} SET ", base.GetTableNameStringNoWith); + var setValues = string.Join(",", t.Where(s => !s.IsPrimarykey).Select(m => GetOracleUpdateColums(i, m, false)).ToArray()); + var pkList = t.Where(s => s.IsPrimarykey).ToList(); + List whereList = new List(); + foreach (var item in pkList) + { + var isFirst = pkList.First() == item; + var whereString = ""; + whereString += GetOracleUpdateColums(i, item, true); + whereList.Add(whereString); + } + i++; + return string.Format("{0} {1} WHERE {2} ", updateTable, setValues, string.Join(" AND", whereList)); + }).ToArray())); + return sb.ToString(); + } + private object GetValue(DbColumnInfo it)=> FormatValue(it.Value); + private string GetOracleUpdateColums(int i, DbColumnInfo m, bool iswhere)=> string.Format("{0}={1}", m.DbColumnName, base.GetDbColumn(m, FormatValue(i, m.DbColumnName, m.Value, iswhere))); + public object FormatValue(int i, string name, object value, bool iswhere) + { + if (value == null) return "NULL"; + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType && iswhere == false) + { + var date = value.ObjToDate(); + if (date < UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig)) + date = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + + if (this.Context.CurrentConnectionConfig?.MoreSettings?.DisableMillisecond == true) + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss") + "'"; + else + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + else if (type == UtilConstants.DateType && iswhere) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else if (type.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) return value.ToSqlValue(); + else return Convert.ToInt64(value); + } + else if (type == UtilConstants.ByteArrayType) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else if (value is int || value is long || value is short || value is short || value is byte) return value; + else if (value is bool) return value.ObjToString().ToLower(); + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) return "'" + value.ToString().ToSqlFilter() + "'"; + else return "'" + value.ToString() + "'"; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguEntry.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguEntry.cs new file mode 100644 index 000000000..6f8f2305e --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguEntry.cs @@ -0,0 +1,34 @@ +namespace SqlSugar.Xugu +{ + /// + /// 入口点 + /// + public static class XuguEntry + { + /// + /// 使用虚谷数据库,并进行配置。 + /// + /// 引用包 SqlSugar.XuguCore + /// using SqlSugar.Xugu; + /// + /// protected static SqlSugarScope db = new SqlSugarScope(new ConnectionConfig() + /// { + /// ConnectionString = "IP=127.0.0.1;DB=SYSTEM;User=SYSDBA;PWD=SYSDBA;Port=5138;AUTO_COMMIT=on;CHAR_SET=GBK", + /// DbType = DbType.Custom.UseXugu(), + /// IsAutoCloseConnection = true, + /// }); + /// 不需要对 InstanceFactory.CustomDbName 等进行配置,已经配置好了 + /// 仅实现了简单的增删改查,未实现函数,未实现返回插入主键等高级用法 + /// + /// + /// 任意数据库类型,建议Custom + /// DbType.Custom + public static DbType UseXugu(this DbType type) + { + InstanceFactory.CustomDbName = "Xugu";//文件名前缀 + InstanceFactory.CustomDllName = "SqlSugar.XuguCore";//扩展的dll名字 + InstanceFactory.CustomNamespace = "SqlSugar.Xugu";//扩展dll的命名空间 + return DbType.Custom; + } + } +} \ No newline at end of file diff --git a/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguProvider.cs b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguProvider.cs new file mode 100644 index 000000000..61e363d10 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.XuguCore/Xugu/XuguProvider.cs @@ -0,0 +1,283 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using XuguClient; + +namespace SqlSugar.Xugu +{ + /// + /// 虚谷 ADO 提供器 + /// + public class XuguProvider : AdoProvider + { + /// + /// 构造函数 + /// + public XuguProvider() { } + /// + /// 数据库连接对象 + /// + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + base._DbConnection = new XGConnection(base.Context.CurrentConnectionConfig.ConnectionString); + } + catch (Exception ex) + { + throw ex; + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + public override string SqlParameterKeyWord => ":"; + public string SplitCommandTag => UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", ""); + public override object GetScalar(string sql, params SugarParameter[] parameters) + { + if (this.Context.Ado.Transaction != null) return _GetScalar(sql, parameters); + try + { + this.Context.Ado.BeginTran(); + var result = _GetScalar(sql, parameters); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception ex) + { + this.Context.Ado.RollbackTran(); + throw ex; + } + } + public override async Task GetScalarAsync(string sql, params SugarParameter[] parameters) + { + if (this.Context.Ado.Transaction != null) return await _GetScalarAsync(sql, parameters); + try + { + this.Context.Ado.BeginTran(); + var result = await _GetScalarAsync(sql, parameters); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception ex) + { + this.Context.Ado.RollbackTran(); + throw ex; + } + } + private void CheckSqlNull(string sql) { if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentNullException("sql", "SQL语句不能为空"); } + private object _GetScalar(string sql, SugarParameter[] parameters) + { + CheckSqlNull(sql); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + object result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") result = base.GetScalar(item, parameters); + } + return result; + } + else return base.GetScalar(sql, parameters); + } + private async Task _GetScalarAsync(string sql, SugarParameter[] parameters) + { + CheckSqlNull(sql); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + object result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") result = await base.GetScalarAsync(item, parameters); + } + return result; + } + else return await base.GetScalarAsync(sql, parameters); + } + + public override int ExecuteCommand(string sql, SugarParameter[] parameters) + { + CheckSqlNull(sql); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + int result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") result += base.ExecuteCommand(item, parameters); + } + return result; + } + else return base.ExecuteCommand(sql, parameters); + } + public override async Task ExecuteCommandAsync(string sql, SugarParameter[] parameters) + { + CheckSqlNull(sql); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + int result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") result += await base.ExecuteCommandAsync(item, parameters); + } + return result; + } + else return await base.ExecuteCommandAsync(sql, parameters); + } + + public override void BeginTran(string transactionName) + { + CheckConnection(); + base.Transaction = ((XGConnection)this.Connection).BeginTransaction(); + } + + public override void BeginTran(IsolationLevel iso, string transactionName) + { + CheckConnection(); + base.Transaction = ((XGConnection)this.Connection).BeginTransaction(iso); + } + + public override IDataAdapter GetAdapter()=> new XuguDataAdapter(); + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + CheckSqlNull(sql); + var helper = new XuguInsertBuilder(); + helper.Context = this.Context; + //if (parameters != null) + //{ + // foreach (var param in parameters.OrderByDescending(it => it.ParameterName.Length)) + // { + // sql = sql.Replace(param.ParameterName, "?");//helper.FormatValue(param.Value) + // } + //} + XGCommand sqlCommand = new XGCommand(sql, (XGConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + if (parameters != null && parameters.Length > 0) sqlCommand.Parameters.AddRange(GetSqlParameter(parameters)); + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) sqlCommand.Transaction = (XGTransaction)this.Transaction; + //if (parameters.HasValue()) + //{ + // OdbcParameter[] ipars = GetSqlParameter(parameters); + // sqlCommand.Parameters.AddRange(ipars); + //} + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command)=> ((XuguDataAdapter)dataAdapter).SelectCommand = (XGCommand)command; + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters)=> GetSqlParameter(parameters); + private int bufferSize = 1024000; + public XGParameters[] GetSqlParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + XGParameters[] result = new XGParameters[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new XGParameters(); + sqlParameter.ParameterName = parameter.ParameterName.Trim(this.SqlParameterKeyWord.ToCharArray()); + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = GetDbType(parameter); + if (parameter.DbType == System.Data.DbType.Time) + { + sqlParameter.Value = DateTime.Parse(parameter.Value?.ToString()).TimeOfDay; + } + if (parameter.Value is byte[] binary) + { + sqlParameter = new XGParameters(sqlParameter.ParameterName, XGDbType.Binary); + sqlParameter.Value = binary; + + int num = binary.Length / bufferSize; + int mod = binary.Length % bufferSize; + if (parameter.DbType == System.Data.DbType.AnsiString)//大概是 BLOB + { + sqlParameter = new XGParameters(sqlParameter.ParameterName, XGDbType.LongVarBinary); + var blob_obj = new XGBlob(); + blob_obj.BeginChunkWrite(); + for (int i = 0; i < num + (mod > 0 ? 1 : 0); i++) blob_obj.write(binary, i * bufferSize, i == num ? mod : bufferSize); + blob_obj.EndChunkWrite(); + sqlParameter.Value = blob_obj; + } + //这个基本没什么用。 + if (parameter.DbType == System.Data.DbType.String)//大概是 CLOB + { + sqlParameter = new XGParameters(sqlParameter.ParameterName, XGDbType.LongVarChar); + var clob_obj = new XGClob(); + clob_obj.BeginChunkWrite(); + for (int i = 0; i < num + (mod > 0 ? 1 : 0); i++) clob_obj.write(binary, i * bufferSize, i == num ? mod : bufferSize); + clob_obj.EndChunkWrite(); + sqlParameter.Value = clob_obj; + } + } + if (parameter.Value is XGClob clob) + { + sqlParameter = new XGParameters(sqlParameter.ParameterName, XGDbType.LongVarChar); + sqlParameter.Value = clob.Length == 0 ? null : parameter.Value; + } + if (parameter.Value is XGBlob blob) + { + sqlParameter = new XGParameters(sqlParameter.ParameterName, XGDbType.LongVarBinary); + sqlParameter.Value = blob.Length == 0 ? null : parameter.Value; + } + if (parameter.Value is TimeSpan) + { + sqlParameter.DbType = System.Data.DbType.String; + sqlParameter.Value = parameter.Value?.ToString(); + } + if (parameter.Value != null && parameter.Value != DBNull.Value && parameter.DbType == System.Data.DbType.DateTime) + { + var date = Convert.ToDateTime(parameter.Value); + if (date == DateTime.MinValue) + { + sqlParameter.Value = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + } + } + if (parameter.Value is DateTimeOffset dateTime) + { + //sqlParameter.DbType = System.Data.DbType.DateTime; + //sqlParameter.Value = UtilMethods.ConvertFromDateTimeOffset(dateTime); + sqlParameter.DbType = System.Data.DbType.String; + sqlParameter.Value = dateTime.ToString("yyyy-MM-dd HH:mm:ss.fff zzz"); + } + if (parameter.Direction == 0) + { + parameter.Direction = ParameterDirection.Input; + } + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + this.OutputParameters ??= new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + + ++index; + } + return result; + } + private static System.Data.DbType GetDbType(SugarParameter parameter) + { + if (parameter.DbType == System.Data.DbType.UInt16) return System.Data.DbType.Int16; + else if (parameter.DbType == System.Data.DbType.UInt32) return System.Data.DbType.Int32; + else if (parameter.DbType == System.Data.DbType.UInt64) return System.Data.DbType.Int64; + else return parameter.DbType; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugarCore.sln b/Src/Asp.NetCore2/SqlSugarCore.sln index 39254e618..d6590f558 100644 --- a/Src/Asp.NetCore2/SqlSugarCore.sln +++ b/Src/Asp.NetCore2/SqlSugarCore.sln @@ -72,7 +72,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "2VastbaseTest", "VastbaseTe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlSugar.QuestDb.RestAPI", "SqlSugar.QuestDb.RestApi\SqlSugar.QuestDb.RestAPI.csproj", "{6DED25D0-660B-468A-AD61-7646345145F5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DorisTest", "DorisTest\DorisTest.csproj", "{7AB57075-AAAC-462D-BD5E-D87B69270EDF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DorisTest", "DorisTest\DorisTest.csproj", "{7AB57075-AAAC-462D-BD5E-D87B69270EDF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlSugar.XuguCore", "SqlSugar.XuguCore\SqlSugar.XuguCore.csproj", "{86C30210-A729-4F66-958D-173ADC512B2B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2XuGuTest", "XuGuTest\2XuGuTest.csproj", "{4DA89736-24C7-4D20-B858-7DD304115E0A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -468,6 +472,30 @@ Global {7AB57075-AAAC-462D-BD5E-D87B69270EDF}.Release|ARM32.Build.0 = Release|Any CPU {7AB57075-AAAC-462D-BD5E-D87B69270EDF}.Release|x86.ActiveCfg = Release|Any CPU {7AB57075-AAAC-462D-BD5E-D87B69270EDF}.Release|x86.Build.0 = Release|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Debug|ARM32.ActiveCfg = Debug|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Debug|ARM32.Build.0 = Debug|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Debug|x86.ActiveCfg = Debug|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Debug|x86.Build.0 = Debug|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Release|Any CPU.Build.0 = Release|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Release|ARM32.ActiveCfg = Release|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Release|ARM32.Build.0 = Release|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Release|x86.ActiveCfg = Release|Any CPU + {86C30210-A729-4F66-958D-173ADC512B2B}.Release|x86.Build.0 = Release|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Debug|ARM32.ActiveCfg = Debug|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Debug|ARM32.Build.0 = Debug|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Debug|x86.ActiveCfg = Debug|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Debug|x86.Build.0 = Debug|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|Any CPU.Build.0 = Release|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|ARM32.ActiveCfg = Release|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|ARM32.Build.0 = Release|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|x86.ActiveCfg = Release|Any CPU + {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -481,6 +509,7 @@ Global {7CEB3DFE-8337-4B83-AE6A-D159D73E3CD3} = {88992AAF-146B-4253-9AD7-493E8F415B57} {A8FDDB0E-835A-4042-A955-66A2DB98207D} = {88992AAF-146B-4253-9AD7-493E8F415B57} {6DED25D0-660B-468A-AD61-7646345145F5} = {88992AAF-146B-4253-9AD7-493E8F415B57} + {86C30210-A729-4F66-958D-173ADC512B2B} = {88992AAF-146B-4253-9AD7-493E8F415B57} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {230A85B9-54F1-41B1-B1DA-80086581B2B4} diff --git a/Src/Asp.NetCore2/XuGuTest/2XuGuTest.csproj b/Src/Asp.NetCore2/XuGuTest/2XuGuTest.csproj new file mode 100644 index 000000000..b4f29bcbd --- /dev/null +++ b/Src/Asp.NetCore2/XuGuTest/2XuGuTest.csproj @@ -0,0 +1,19 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/Src/Asp.NetCore2/XuGuTest/BaseDataLogic.cs b/Src/Asp.NetCore2/XuGuTest/BaseDataLogic.cs new file mode 100644 index 000000000..65c95250d --- /dev/null +++ b/Src/Asp.NetCore2/XuGuTest/BaseDataLogic.cs @@ -0,0 +1,216 @@ +using SqlSugar; +using Mapster; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Threading.Tasks; +using System.Diagnostics; +using SqlSugar.Xugu; + +namespace Data_logic +{ + /// + /// 业务逻辑基类 + /// + /// 与数据库中表的结构一致的模型类型 + public class BaseDataLogic where T : class, new() + { + /// + /// 主键个数 + /// + private int primarykeyCount = -1; + /// + /// 主键属性信息 + /// + private PropertyInfo primarykeyInfo = null; + /// + /// 构造函数 + /// + public BaseDataLogic() + { + //获取主键个数 + if (primarykeyCount == -1) + { + var list = db.EntityMaintenance.GetEntityInfo().Columns.Where(d => d.IsPrimarykey == true); + primarykeyCount = list.Count(); + primarykeyInfo = primarykeyCount == 1 ? list.FirstOrDefault().PropertyInfo : null; + } + //* + db.Aop.OnLogExecuting = (sql, pars) => + { + Debugger.Log(1, "SQL", sql); + }; + //*/ + } + /// + /// SqlSugar 操作对象,单例用SqlSugarClient,否则用SqlSugarClient + /// + protected static SqlSugarScope db = new SqlSugarScope(new ConnectionConfig() + { + ConnectionString = "IP=10.1.1.1;DB=SYSTEM;User=SYSDBA;PWD=SYSDBA;Port=5138;AUTO_COMMIT=on;CHAR_SET=UTF8",//CHAR_SET=GBK + DbType = DbType.Custom.UseXugu(), + IsAutoCloseConnection = true, + //ConfigureExternalServices = new ConfigureExternalServices() { SqlFuncServices = SqlFuncCustom.Methods } + }); + /// + /// 从数据库中生成模型类文件 + /// + /// 文件放置的位置 + /// 默认命名空间 + /// 是否生成所有表。是则包含所有T开头的表,否则只生成当前对象名称相同的表 + public void CreateModel(string path, string nameSpace = "Data.Model", bool allTable = false) + { + db.DbFirst.Where(c => allTable ? c.StartsWith("T") : typeof(T).Name == c) + .IsCreateAttribute().IsCreateDefaultValue() + .CreateClassFile(path, nameSpace); + } + /// + /// 添加一条数据 + /// + /// 视图模型类型 + /// 视图模型,仅包含模型中有的且值不为Null的字段 + /// 是否添加成功,已存在视为false + public async Task Add(TModel model) where TModel : class + { + if (db.Queryable().In(primarykeyInfo.GetValue(model.Adapt())).Any()) return false; + return await db.Insertable(model) + .IgnoreColumns(ignoreNullColumn: true) + .ExecuteReturnBigIdentityAsync().ContinueWith(t => + t.Result>0 + ); + } + /// + /// 根据主键或根据条件更新数据 + /// + /// 视图模型类型 + /// 视图模型,仅包含模型中有的且值不为Null的字段 + /// 查询条件,当条件为Null时为主键更新(T必须配置主键),否则为条件批量更新 + /// 更新是否成功,不存在视为false + /// 类型T未配置主键或有多个主键 + public async Task Update(TModel model, Expression> where = null) where TModel : class + { + if (where != null && this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键"); + var expression = db.Updateable(model); + if (where != null) expression = expression.Where(where); + return await expression + .IgnoreColumns(ignoreAllNullColumns: true) + .ExecuteCommandHasChangeAsync(); + } + /// + /// 根据主键插入或更新一条数据 + /// + /// 视图模型类型(必须配置主键) + /// 视图模型,仅包含模型中有的且值不为Null的字段 + /// 更新是否成功 + /// 类型T未配置主键或有多个主键 + public async Task AddOrUpdate(TModel model) where TModel : class, new() + { + if (this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键"); + + if (!await db.Queryable().In(primarykeyInfo.GetValue(model.Adapt())).AnyAsync()) return await Add(model); + else return await Update(model); + /* + var o = db.Storageable(model.Adapt()).ToStorage(); + o.AsInsertable.ExecuteCommand();//不存在插入 + o.AsUpdateable.ExecuteCommand();//存在更新 + + return await db.Storageable(model.Adapt()) + .ExecuteCommandAsync() + .ContinueWith(t => t.Result > 0); + */ + } + /// + /// 根据主键删除数据 + /// + /// 主键的类型 + /// 主键值 + /// 删除是否成功 + /// 类型T未配置主键或有多个主键 + public async Task Delete(TKey id) + { + if (this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键"); + //不存在时视为删除成功 + if (!await db.Queryable().In(id).AnyAsync()) return true; + return await db.Deleteable(id).ExecuteCommandHasChangeAsync(); + } + /// + /// 根据查询条件删除数据 + /// + /// 查询条件表达式 + /// 删除是否成功 + public async Task Delete(Expression> where) + { + //不存在时视为删除成功 + if (!await db.Queryable().Where(where).AnyAsync()) return true; + return await db.Deleteable(where).ExecuteCommandHasChangeAsync(); + } + /// + /// 根据单个主键获取一条数据 + /// + /// 要返回的模型类型 + /// 主键的类型 + /// 主键值 + /// 返回指定主键值的数据 + /// 类型T未配置主键或有多个主键 + public async Task Single(TKey id) + { + if (this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键"); + return await db.Queryable().InSingleAsync(id).ContinueWith(t => t.Result.Adapt()); + } + /// + /// 根据条件获取唯一数据 + /// + /// 要返回的模型类型 + /// 主键的类型 + /// 查询条件 + /// 返回符合指定条件的唯一数据,不唯一时将抛出异常 + public async Task Single(Expression> where) + { + return await db.Queryable().Where(where).Select().SingleAsync(); + } + /// + /// 获取符合条件的分页数据 + /// + /// 列表模型的类型 + /// 条件表达式 + /// 排序表达式 + /// 排序方向,默认顺序 + /// 页码,从1开始 + /// 每页条数,默认20 + /// 符合条件的分页数据列表,以及总条数 + public async Task<(List, int)> List(Expression> where = null + , Expression> order = null, OrderByType orderType = OrderByType.Asc + , int pageNum = 1, int pageSize = 20, bool noPager = false) + { + var expression = db.Queryable(); + if (where != null && where.ToString() != "it => True") expression = expression.Where(where); + if (order != null) expression = expression.OrderBy(order, orderType); + + var expressionTModel = expression.Select(); + if (noPager) return await expressionTModel.ToListAsync().ContinueWith(d => (d.Result, d.Result.Count)); + else return await ToPagedList(expressionTModel, pageNum, pageSize); + } + /// + /// 通用分页 + /// + /// 列表模型的类型 + /// 查询表达式 + /// 页码,从1开始 + /// 每页条数,默认20 + /// 返回查询表达式分页后的数据列表,以及总条数 + protected static async Task<(List, int)> ToPagedList(ISugarQueryable expression, int pageNum = 1, int pageSize = 20) + { + RefAsync totalCount = 0; + return await expression + .ToPageListAsync/*ToOffsetPageAsync//2012以上才支持*/(pageNum, pageSize, totalCount) + .ContinueWith(d => (d.Result, totalCount)); + } + /// + /// 获取动态where条件对象 + /// + /// 动态where条件对象 + public Expressionable CreateWhere() => Expressionable.Create(); + } +} \ No newline at end of file diff --git a/Src/Asp.NetCore2/XuGuTest/Program.cs b/Src/Asp.NetCore2/XuGuTest/Program.cs new file mode 100644 index 000000000..18ff14a05 --- /dev/null +++ b/Src/Asp.NetCore2/XuGuTest/Program.cs @@ -0,0 +1,56 @@ +using Data.Model; +using Data_logic; +using Microsoft.IdentityModel.Tokens; +using SqlSugar; +using SqlSugar.DbConvert; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Xml.Linq; +using XuguClient; + +namespace XuguTest +{ + internal class Program + { + static void Main(string[] args) + { + + Task.Run(async () => + { + var o = new UserService(); + //o.CreateModel(@"F:\!GZH\Models\南海气象数据支撑系统", allTable: true); + var task = o.GetList(); + var data = task.First(); + data.ID = task.Last().ID + 1; + //data.C_BINARY = File.ReadAllBytes(@"C:\Users\28679\Desktop\项目网址(新).docx"); + //data.C_DATE = DateTime.Now.AddDays(-10); + var r = await o.Add(data); + ////////////////////////var d1 = await o.Delete(o => o.C_BIGINT >=154 && o.C_BIGINT <=166); + ////////////////////////var d = await o.Delete(o=>o.ID>1); + + var u = await o.Single(t=>t.C_DATETIME > DateTime.Today); + u.C_DATETIME = DateTime.Now.AddDays(2); + var b = await o.Update(u); + Console.WriteLine("Hello World!"); + }).Wait(); + } + } + + public class UserService : BaseDataLogic + { + public UserService() { + + //db.CodeFirst.InitTables(typeof(T_USER)); + } + public List GetList() + { + return db.Queryable().Where(d=>d.C_DATETIME < DateTime.Now).ToPageList(1,1); + } + } + +} diff --git a/Src/Asp.NetCore2/XuGuTest/T_USER.cs b/Src/Asp.NetCore2/XuGuTest/T_USER.cs new file mode 100644 index 000000000..865f0f2ce --- /dev/null +++ b/Src/Asp.NetCore2/XuGuTest/T_USER.cs @@ -0,0 +1,329 @@ +using System; +using System.Data; +using System.Linq; +using System.Text; +using SqlSugar; +using SqlSugar.Xugu; +using XuguClient; + +namespace Data.Model +{ + /// + /// + /// + [SugarTable("T_USER",TableDescription ="测试表")] + public partial class T_USER + { + public T_USER() + { + + + } + /// + /// Desc:主键 + /// Default: + /// Nullable:False + /// + [SugarColumn(IsPrimaryKey = true,ColumnDescription ="主键")] + public int ID { get; set; } + + /// + /// Desc:数字类型 + /// Default: + /// Nullable:False + /// + [SugarColumn(IsIdentity = true)] + public long C_BIGINT { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public byte[] C_BINARY { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public object C_BLOB { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public bool? C_BOOLEAN { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public string C_VARCHAR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "Char")] + public string C_CHAR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "clob")] + public string C_CLOB { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "date")] + public DateTime? C_DATE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public DateTime? C_DATETIME { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(SqlParameterDbType = typeof(DateTimeOffsetConvert))] + public DateTimeOffset? C_DATETIME_WITH_TIME_ZONE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public decimal? C_DECIMAL { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public double? C_DOUBLE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public float? C_FLOAT { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public Guid? C_GUID { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public int? C_INT { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public int? C_INTEGER { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL YEAR")] + public string C_INTERVAL_YEAR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL YEAR TO MONTH")] + public string C_INTERVAL_YEAR_TO_MONTH { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL MONTH")] + public string C_INTERVAL_MONTH { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL DAY")] + public string C_INTERVAL_DAY { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL DAY TO HOUR")] + public string C_INTERVAL_DAY_TO_HOUR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL HOUR")] + public string C_INTERVAL_HOUR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL DAY TO MINUTE")] + public string C_INTERVAL_DAY_TO_MINUTE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL HOUR TO MINUTE")] + public string C_INTERVAL_HOUR_TO_MINUTE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL MINUTE")] + public string C_INTERVAL_MINUTE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL DAY TO SECOND")] + public string C_INTERVAL_DAY_TO_SECOND { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL HOUR TO SECOND")] + public string C_INTERVAL_HOUR_TO_SECOND { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL MINUTE TO SECOND")] + public string C_INTERVAL_MINUTE_TO_SECOND { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "INTERVAL SECOND")] + public string C_INTERVAL_SECOND { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "NCHAR")] + public string C_NCHAR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public decimal? C_NUMERIC { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "NVARCHAR")] + public string C_NVARCHAR { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "ROWID")] + public string C_ROWID { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public Version C_ROWVERSION { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public sbyte? C_TINYINT { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(SqlParameterDbType = typeof(DateTimeOffsetConvert), ColumnDataType = "TIME")] + public TimeSpan? C_TIME { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "TIMESTAMP")] + public DateTime? C_TIMESTAMP { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnDataType = "TIMESTAMP AUTO UPDATE")] + public DateTime? C_TIMESTAMP_AUTO_UPDATE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(SqlParameterDbType = typeof(DateTimeOffsetConvert), ColumnDataType = "TIME WITH TIME ZONE")] + public TimeSpan? C_TIME_WITH_TIME_ZONE { get; set; } + + } +}