diff --git a/src/.editorconfig b/src/.editorconfig index 38812cd3f..763ef2d0a 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -126,35 +126,8 @@ dotnet_style_qualification_for_property = false:silent dotnet_style_qualification_for_method = false:silent dotnet_style_qualification_for_event = false:silent - -dotnet_diagnostic.CA2208.severity = none -dotnet_diagnostic.CA2008.severity = none -dotnet_diagnostic.CA1812.severity = none -dotnet_diagnostic.CA1508.severity = none -dotnet_diagnostic.CA1512.severity = none -dotnet_diagnostic.CA1513.severity = none -dotnet_diagnostic.CA1810.severity = none -dotnet_diagnostic.CA1814.severity = none -dotnet_diagnostic.CA1815.severity = none -dotnet_diagnostic.CA1835.severity = none -dotnet_diagnostic.CA1819.severity = none -dotnet_diagnostic.CA1823.severity = none -dotnet_diagnostic.CA2002.severity = none -dotnet_diagnostic.CA5350.severity = none -dotnet_diagnostic.CA5351.severity = none -dotnet_diagnostic.CA5358.severity = none -dotnet_diagnostic.CA5384.severity = none -dotnet_diagnostic.CA5392.severity = none -dotnet_diagnostic.CA1805.severity = none -dotnet_diagnostic.CA1851.severity = none -dotnet_diagnostic.CA1510.severity = none -dotnet_diagnostic.CA5401.severity = none -dotnet_diagnostic.CA2022.severity = none -dotnet_diagnostic.CA1848.severity = none -dotnet_diagnostic.CA2000.severity = none -dotnet_diagnostic.CA5394.severity = none -dotnet_diagnostic.CA3003.severity = none -dotnet_diagnostic.CA1515.severity = none -dotnet_diagnostic.CA1849.severity = none +dotnet_diagnostic.RCS1146.severity = warning +dotnet_diagnostic.RCS1059.severity = none +dotnet_diagnostic.RCS1138.severity = suggestion dotnet_code_quality.CA1822.api_surface = private, internal \ No newline at end of file diff --git a/src/Admin/ThingsGateway.Admin.Application/Attributes/IgnoreRolePermissionAttribute.cs b/src/Admin/ThingsGateway.Admin.Application/Attributes/IgnoreRolePermissionAttribute.cs index 19045fbf1..922063946 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Attributes/IgnoreRolePermissionAttribute.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Attributes/IgnoreRolePermissionAttribute.cs @@ -13,14 +13,16 @@ namespace ThingsGateway.Admin.Application; /// /// 需要角色授权权限 /// -[AttributeUsage(AttributeTargets.Class)] +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public sealed class RolePermissionAttribute : Attribute { } + /// /// 忽略角色授权权限 /// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public sealed class IgnoreRolePermissionAttribute : Attribute { } diff --git a/src/Admin/ThingsGateway.Admin.Application/Const/CacheConst.cs b/src/Admin/ThingsGateway.Admin.Application/Const/CacheConst.cs index 16f3da5a6..5ccb5adee 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Const/CacheConst.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Const/CacheConst.cs @@ -11,7 +11,7 @@ namespace ThingsGateway.Admin.Application; [ThingsGateway.DependencyInjection.SuppressSniffer] -public class CacheConst +public static class CacheConst { /// /// Token表缓存Key diff --git a/src/Admin/ThingsGateway.Admin.Application/Const/HubConst.cs b/src/Admin/ThingsGateway.Admin.Application/Const/HubConst.cs index 569408420..51939736e 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Const/HubConst.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Const/HubConst.cs @@ -13,7 +13,7 @@ namespace ThingsGateway.Admin.Application; /// /// 通讯器常量 /// -public class HubConst +public static class HubConst { /// /// 系统HubUrl diff --git a/src/Admin/ThingsGateway.Admin.Application/Const/ResourceConst.cs b/src/Admin/ThingsGateway.Admin.Application/Const/ResourceConst.cs index 3152560fd..7fbddb814 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Const/ResourceConst.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Const/ResourceConst.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// 资源表常量 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class ResourceConst +public static class ResourceConst { /// /// 系统内置编码 diff --git a/src/Admin/ThingsGateway.Admin.Application/Const/RoleConst.cs b/src/Admin/ThingsGateway.Admin.Application/Const/RoleConst.cs index 2ac3c3601..66350dd97 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Const/RoleConst.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Const/RoleConst.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// 角色常量 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class RoleConst +public static class RoleConst { /// /// api角色 diff --git a/src/Admin/ThingsGateway.Admin.Application/Const/SqlSugarConst.cs b/src/Admin/ThingsGateway.Admin.Application/Const/SqlSugarConst.cs index 6ef6796f2..bca8c97a2 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Const/SqlSugarConst.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Const/SqlSugarConst.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// SqlSugar系统常量 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class SqlSugarConst +public static class SqlSugarConst { /// /// DB_Admin diff --git a/src/Admin/ThingsGateway.Admin.Application/Filter/RequestAuditAttribute.cs b/src/Admin/ThingsGateway.Admin.Application/Filter/RequestAuditAttribute.cs index 3a7bfabe5..ecbc4b706 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Filter/RequestAuditAttribute.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Filter/RequestAuditAttribute.cs @@ -1,14 +1,4 @@ -// ------------------------------------------------------------------------ -// 版权信息 -// 版权归百小僧及百签科技(广东)有限公司所有。 -// 所有权利保留。 -// 官方网站:https://baiqian.com -// -// 许可证信息 -// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 -// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 -// ------------------------------------------------------------------------ - + using ThingsGateway.DependencyInjection; namespace System; diff --git a/src/Admin/ThingsGateway.Admin.Application/Filter/SuppressRequestAuditAttribute.cs b/src/Admin/ThingsGateway.Admin.Application/Filter/SuppressRequestAuditAttribute.cs index 625b62c54..830c0b7df 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Filter/SuppressRequestAuditAttribute.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Filter/SuppressRequestAuditAttribute.cs @@ -1,14 +1,4 @@ -// ------------------------------------------------------------------------ -// 版权信息 -// 版权归百小僧及百签科技(广东)有限公司所有。 -// 所有权利保留。 -// 官方网站:https://baiqian.com -// -// 许可证信息 -// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 -// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 -// ------------------------------------------------------------------------ - + using ThingsGateway.DependencyInjection; namespace System; diff --git a/src/Admin/ThingsGateway.Admin.Application/Gitee/AdminOAuthHandler.cs b/src/Admin/ThingsGateway.Admin.Application/Gitee/AdminOAuthHandler.cs index acb17b6dc..058073171 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Gitee/AdminOAuthHandler.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Gitee/AdminOAuthHandler.cs @@ -261,4 +261,17 @@ public class AdminOAuthHandler( } /// 自定义 Token 异常 -public class OAuthTokenException(string message) : Exception(message); +public class OAuthTokenException : Exception +{ + public OAuthTokenException() : base() + { + } + + public OAuthTokenException(string? message, Exception? innerException) : base(message, innerException) + { + } + + public OAuthTokenException(string? message) : base(message) + { + } +} diff --git a/src/Admin/ThingsGateway.Admin.Application/Logging/LoggingConst.cs b/src/Admin/ThingsGateway.Admin.Application/Logging/LoggingConst.cs index 470676394..39a69087b 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Logging/LoggingConst.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Logging/LoggingConst.cs @@ -13,7 +13,7 @@ namespace ThingsGateway.Admin.Application; /// /// 日志常量 /// -public class LoggingConst +public static class LoggingConst { /// /// 分类 diff --git a/src/Admin/ThingsGateway.Admin.Application/Provider/BlazorAuthenticationHandler.cs b/src/Admin/ThingsGateway.Admin.Application/Provider/BlazorAuthenticationHandler.cs index ccba7d4a1..5e7b3df51 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Provider/BlazorAuthenticationHandler.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Provider/BlazorAuthenticationHandler.cs @@ -87,7 +87,7 @@ public class BlazorAuthenticationHandler : AppAuthorizeHandler var roles = await _sysRoleService.GetRoleListByUserIdAsync(userId).ConfigureAwait(false); //这里鉴别用户使能状态 - if (user == null || !user.Status) + if (user?.Status != true) { return false; } @@ -137,7 +137,7 @@ public class BlazorAuthenticationHandler : AppAuthorizeHandler else { //这里鉴别用户使能状态 - if (user == null || !user.Status) + if (user?.Status != true) { return false; } diff --git a/src/Admin/ThingsGateway.Admin.Application/Services/Resource/SysResourceService.cs b/src/Admin/ThingsGateway.Admin.Application/Services/Resource/SysResourceService.cs index 7fa9e6d5b..69bc7f3ea 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Services/Resource/SysResourceService.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Services/Resource/SysResourceService.cs @@ -334,7 +334,7 @@ internal sealed class SysResourceService : BaseService, ISysResourc flatList.Add(node); // 如果当前节点有子节点,则递归处理每个子节点 - if (node.Children != null && node.Children.Count > 0) + if (node.Children?.Count > 0) { foreach (var child in node.Children) { diff --git a/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj b/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj index 43f084540..9a3ed00e5 100644 --- a/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj +++ b/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/ClearTokenUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/ClearTokenUtil.cs index d7c6c03c4..da413987e 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/ClearTokenUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/ClearTokenUtil.cs @@ -13,7 +13,7 @@ using Microsoft.Extensions.DependencyInjection; namespace ThingsGateway.Admin.Application; [ThingsGateway.DependencyInjection.SuppressSniffer] -public class ClearTokenUtil +public static class ClearTokenUtil { private static IRelationService RelationService; private static ISysUserService SysUserService; diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/NoticeUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/NoticeUtil.cs index d3a586684..1a6be390c 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/NoticeUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/NoticeUtil.cs @@ -13,7 +13,7 @@ using Microsoft.Extensions.DependencyInjection; namespace ThingsGateway.Admin.Application; [ThingsGateway.DependencyInjection.SuppressSniffer] -public class NoticeUtil +public static class NoticeUtil { private static INoticeService NoticeService; diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/OpenApiUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/OpenApiUtil.cs index 7e7b6ba11..c880c59fd 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/OpenApiUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/OpenApiUtil.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class OpenApiUtil +public static class OpenApiUtil { /// /// 构建树节点,传入的列表已经是树结构 diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/OrgUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/OrgUtil.cs index 3461b7875..47e32c047 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/OrgUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/OrgUtil.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class OrgUtil +public static class OrgUtil { /// /// 构造选择项,ID/TITLE diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/PositionUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/PositionUtil.cs index 32c765d88..d136baa7e 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/PositionUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/PositionUtil.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class PositionUtil +public static class PositionUtil { /// diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/RoleUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/RoleUtil.cs index 35699ea48..62add004c 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/RoleUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/RoleUtil.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class RoleUtil +public static class RoleUtil { diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/UserUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/UserUtil.cs index 4a3998afd..35948a5da 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/UserUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/UserUtil.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class UserUtil +public static class UserUtil { /// diff --git a/src/Admin/ThingsGateway.Admin.Application/Util/VerificatInfoUtil.cs b/src/Admin/ThingsGateway.Admin.Application/Util/VerificatInfoUtil.cs index 894d5180e..9a78937cd 100644 --- a/src/Admin/ThingsGateway.Admin.Application/Util/VerificatInfoUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Application/Util/VerificatInfoUtil.cs @@ -14,7 +14,7 @@ using ThingsGateway.Extension.Generic; namespace ThingsGateway.Admin.Application; -public class VerificatInfoUtil +public static class VerificatInfoUtil { private static IVerificatInfoService VerificatInfoService { get; set; } static VerificatInfoUtil() diff --git a/src/Admin/ThingsGateway.Admin.Razor/Const/AdminOperConst.cs b/src/Admin/ThingsGateway.Admin.Razor/Const/AdminOperConst.cs index 992e741d8..5345d29ff 100644 --- a/src/Admin/ThingsGateway.Admin.Razor/Const/AdminOperConst.cs +++ b/src/Admin/ThingsGateway.Admin.Razor/Const/AdminOperConst.cs @@ -11,7 +11,7 @@ namespace ThingsGateway.Admin.Razor; [ThingsGateway.DependencyInjection.SuppressSniffer] -public class AdminOperConst +public static class AdminOperConst { public const string Add = "新增"; public const string Delete = "删除"; diff --git a/src/Admin/ThingsGateway.Admin.Razor/Pages/User/SysUserAvatarEdit.razor.cs b/src/Admin/ThingsGateway.Admin.Razor/Pages/User/SysUserAvatarEdit.razor.cs index 8d1a059cf..62a546a40 100644 --- a/src/Admin/ThingsGateway.Admin.Razor/Pages/User/SysUserAvatarEdit.razor.cs +++ b/src/Admin/ThingsGateway.Admin.Razor/Pages/User/SysUserAvatarEdit.razor.cs @@ -48,7 +48,7 @@ public partial class SysUserAvatarEdit : IDisposable private async Task OnAvatarUpload(UploadFile file) { - if (file != null && file.File != null) + if (file?.File != null) { var format = file.File.ContentType; ReadAvatarToken ??= new CancellationTokenSource(); diff --git a/src/Admin/ThingsGateway.Admin.Razor/Pages/UserCenter/UserInfoEditComponent.razor.cs b/src/Admin/ThingsGateway.Admin.Razor/Pages/UserCenter/UserInfoEditComponent.razor.cs index 3572b9f88..1843e7445 100644 --- a/src/Admin/ThingsGateway.Admin.Razor/Pages/UserCenter/UserInfoEditComponent.razor.cs +++ b/src/Admin/ThingsGateway.Admin.Razor/Pages/UserCenter/UserInfoEditComponent.razor.cs @@ -48,7 +48,7 @@ public partial class UserInfoEditComponent private async Task OnAvatarUpload(UploadFile file) { - if (file != null && file.File != null) + if (file?.File != null) { var format = file.File.ContentType; ReadAvatarToken ??= new CancellationTokenSource(); diff --git a/src/Admin/ThingsGateway.Admin.Razor/Util/ResourceUtil.cs b/src/Admin/ThingsGateway.Admin.Razor/Util/ResourceUtil.cs index 4b93e004a..c260688bb 100644 --- a/src/Admin/ThingsGateway.Admin.Razor/Util/ResourceUtil.cs +++ b/src/Admin/ThingsGateway.Admin.Razor/Util/ResourceUtil.cs @@ -16,7 +16,7 @@ namespace ThingsGateway.Admin.Razor; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class ResourceUtil +public static class ResourceUtil { /// diff --git a/src/Admin/ThingsGateway.AdminServer/GlobalUsings.cs b/src/Admin/ThingsGateway.AdminServer/GlobalUsings.cs index 29884ed1e..0a5641e42 100644 --- a/src/Admin/ThingsGateway.AdminServer/GlobalUsings.cs +++ b/src/Admin/ThingsGateway.AdminServer/GlobalUsings.cs @@ -1,12 +1 @@ -// ------------------------------------------------------------------------ -// 版权信息 -// 版权归百小僧及百签科技(广东)有限公司所有。 -// 所有权利保留。 -// 官方网站:https://baiqian.com -// -// 许可证信息 -// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 -// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 -// ------------------------------------------------------------------------ - -global using ThingsGateway.Admin.Application; +global using ThingsGateway.Admin.Application; diff --git a/src/Admin/ThingsGateway.SqlSugar/Attributes/IgnoreExcelAttribute.cs b/src/Admin/ThingsGateway.DB/Attributes/IgnoreExcelAttribute.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Attributes/IgnoreExcelAttribute.cs rename to src/Admin/ThingsGateway.DB/Attributes/IgnoreExcelAttribute.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Attributes/IgnoreSeedDataAttribute.cs b/src/Admin/ThingsGateway.DB/Attributes/IgnoreSeedDataAttribute.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Attributes/IgnoreSeedDataAttribute.cs rename to src/Admin/ThingsGateway.DB/Attributes/IgnoreSeedDataAttribute.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Const/ClaimConst.cs b/src/Admin/ThingsGateway.DB/Const/ClaimConst.cs similarity index 98% rename from src/Admin/ThingsGateway.SqlSugar/Const/ClaimConst.cs rename to src/Admin/ThingsGateway.DB/Const/ClaimConst.cs index 7b6db1c3c..0bc0dd62b 100644 --- a/src/Admin/ThingsGateway.SqlSugar/Const/ClaimConst.cs +++ b/src/Admin/ThingsGateway.DB/Const/ClaimConst.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Admin.Application; /// 授权用户常量 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class ClaimConst +public static class ClaimConst { /// /// 账号 diff --git a/src/Admin/ThingsGateway.SqlSugar/Entity/BaseEntity.cs b/src/Admin/ThingsGateway.DB/Entity/BaseEntity.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Entity/BaseEntity.cs rename to src/Admin/ThingsGateway.DB/Entity/BaseEntity.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Extensions/ExportExcelExtensions.cs b/src/Admin/ThingsGateway.DB/Extensions/ExportExcelExtensions.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Extensions/ExportExcelExtensions.cs rename to src/Admin/ThingsGateway.DB/Extensions/ExportExcelExtensions.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Extensions/FileExtensions.cs b/src/Admin/ThingsGateway.DB/Extensions/FileExtensions.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Extensions/FileExtensions.cs rename to src/Admin/ThingsGateway.DB/Extensions/FileExtensions.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Extensions/QueryPageOptionsExtensions.cs b/src/Admin/ThingsGateway.DB/Extensions/QueryPageOptionsExtensions.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Extensions/QueryPageOptionsExtensions.cs rename to src/Admin/ThingsGateway.DB/Extensions/QueryPageOptionsExtensions.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Extensions/SqlSugarExtensions.cs b/src/Admin/ThingsGateway.DB/Extensions/SqlSugarExtensions.cs similarity index 99% rename from src/Admin/ThingsGateway.SqlSugar/Extensions/SqlSugarExtensions.cs rename to src/Admin/ThingsGateway.DB/Extensions/SqlSugarExtensions.cs index a2b766cef..b12b1c0f9 100644 --- a/src/Admin/ThingsGateway.SqlSugar/Extensions/SqlSugarExtensions.cs +++ b/src/Admin/ThingsGateway.DB/Extensions/SqlSugarExtensions.cs @@ -225,7 +225,7 @@ public static class SqlSugarExtensions private static IEnumerable Sort(this IEnumerable list, BasePageInput basePageInput) { - if (basePageInput != null && basePageInput.SortField != null) + if (basePageInput?.SortField != null) { for (int i = 0; i < basePageInput.SortField.Count; i++) { diff --git a/src/Admin/ThingsGateway.DB/GlobalUsings.cs b/src/Admin/ThingsGateway.DB/GlobalUsings.cs new file mode 100644 index 000000000..ec2e58001 --- /dev/null +++ b/src/Admin/ThingsGateway.DB/GlobalUsings.cs @@ -0,0 +1,11 @@ +//------------------------------------------------------------------------------ +// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 +// 此代码版权(除特别声明外的代码)归作者本人Diego所有 +// 源代码使用协议遵循本仓库的开源协议及附加协议 +// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway +// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway +// 使用文档:https://thingsgateway.cn/ +// QQ群:605534569 +//------------------------------------------------------------------------------ + +global using ThingsGateway.NewLife.Extension; \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Services/AppService/ClaimsPrincipalService.cs b/src/Admin/ThingsGateway.DB/Services/AppService/ClaimsPrincipalService.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Services/AppService/ClaimsPrincipalService.cs rename to src/Admin/ThingsGateway.DB/Services/AppService/ClaimsPrincipalService.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Services/AppService/IClaimsPrincipalService.cs b/src/Admin/ThingsGateway.DB/Services/AppService/IClaimsPrincipalService.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Services/AppService/IClaimsPrincipalService.cs rename to src/Admin/ThingsGateway.DB/Services/AppService/IClaimsPrincipalService.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Services/SugarAopService/ISugarAopService.cs b/src/Admin/ThingsGateway.DB/Services/SugarAopService/ISugarAopService.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Services/SugarAopService/ISugarAopService.cs rename to src/Admin/ThingsGateway.DB/Services/SugarAopService/ISugarAopService.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Services/SugarAopService/SugarAopService.cs b/src/Admin/ThingsGateway.DB/Services/SugarAopService/SugarAopService.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Services/SugarAopService/SugarAopService.cs rename to src/Admin/ThingsGateway.DB/Services/SugarAopService/SugarAopService.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Services/SugarService/BaseService.cs b/src/Admin/ThingsGateway.DB/Services/SugarService/BaseService.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Services/SugarService/BaseService.cs rename to src/Admin/ThingsGateway.DB/Services/SugarService/BaseService.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/SqlSugar/CodeFirstUtils.cs b/src/Admin/ThingsGateway.DB/SqlSugar/CodeFirstUtils.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/SqlSugar/CodeFirstUtils.cs rename to src/Admin/ThingsGateway.DB/SqlSugar/CodeFirstUtils.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/SqlSugar/DbContext.cs b/src/Admin/ThingsGateway.DB/SqlSugar/DbContext.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/SqlSugar/DbContext.cs rename to src/Admin/ThingsGateway.DB/SqlSugar/DbContext.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/SqlSugar/ISqlSugarEntitySeedData.cs b/src/Admin/ThingsGateway.DB/SqlSugar/ISqlSugarEntitySeedData.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/SqlSugar/ISqlSugarEntitySeedData.cs rename to src/Admin/ThingsGateway.DB/SqlSugar/ISqlSugarEntitySeedData.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/SqlSugar/SeedDataUtil.cs b/src/Admin/ThingsGateway.DB/SqlSugar/SeedDataUtil.cs similarity index 99% rename from src/Admin/ThingsGateway.SqlSugar/SqlSugar/SeedDataUtil.cs rename to src/Admin/ThingsGateway.DB/SqlSugar/SeedDataUtil.cs index 45bfc1238..2a4e7affd 100644 --- a/src/Admin/ThingsGateway.SqlSugar/SqlSugar/SeedDataUtil.cs +++ b/src/Admin/ThingsGateway.DB/SqlSugar/SeedDataUtil.cs @@ -25,7 +25,7 @@ namespace ThingsGateway.Admin.Application; /// 种子数据工具类 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class SeedDataUtil +public static class SeedDataUtil { /// /// 获取List列表 diff --git a/src/Admin/ThingsGateway.SqlSugar/SqlSugar/SqlSugarOptions.cs b/src/Admin/ThingsGateway.DB/SqlSugar/SqlSugarOptions.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/SqlSugar/SqlSugarOptions.cs rename to src/Admin/ThingsGateway.DB/SqlSugar/SqlSugarOptions.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Startup.cs b/src/Admin/ThingsGateway.DB/Startup.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Startup.cs rename to src/Admin/ThingsGateway.DB/Startup.cs diff --git a/src/Admin/ThingsGateway.SqlSugar/Static/UserManager.cs b/src/Admin/ThingsGateway.DB/Static/UserManager.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Static/UserManager.cs rename to src/Admin/ThingsGateway.DB/Static/UserManager.cs diff --git a/src/Admin/ThingsGateway.DB/ThingsGateway.DB.csproj b/src/Admin/ThingsGateway.DB/ThingsGateway.DB.csproj new file mode 100644 index 000000000..8d68e82e9 --- /dev/null +++ b/src/Admin/ThingsGateway.DB/ThingsGateway.DB.csproj @@ -0,0 +1,33 @@ + + + + + + + True + + + net8.0;net9.0; + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Admin/ThingsGateway.SqlSugar/Util/CommonUtils.cs b/src/Admin/ThingsGateway.DB/Util/CommonUtils.cs similarity index 100% rename from src/Admin/ThingsGateway.SqlSugar/Util/CommonUtils.cs rename to src/Admin/ThingsGateway.DB/Util/CommonUtils.cs diff --git a/src/Admin/ThingsGateway.Furion/App/App.cs b/src/Admin/ThingsGateway.Furion/App/App.cs index 92ed0775b..f203af482 100644 --- a/src/Admin/ThingsGateway.Furion/App/App.cs +++ b/src/Admin/ThingsGateway.Furion/App/App.cs @@ -471,7 +471,7 @@ public static class App IEnumerable pathOfExternalAssemblies = Array.Empty(); // 加载 appsettings.json 配置的外部程序集 - if (Settings.ExternalAssemblies != null && Settings.ExternalAssemblies.Length > 0) + if (Settings.ExternalAssemblies?.Length > 0) { var externalDlls = new List(); foreach (var item in Settings.ExternalAssemblies) @@ -552,7 +552,7 @@ public static class App } // 处理排除的程序集 - if (Settings.ExcludeAssemblies != null && Settings.ExcludeAssemblies.Length > 0) + if (Settings.ExcludeAssemblies?.Length > 0) { scanAssemblies = scanAssemblies.Where(ass => !Settings.ExcludeAssemblies.Contains(ass.GetName().Name, StringComparer.OrdinalIgnoreCase)); } diff --git a/src/Admin/ThingsGateway.Furion/App/Extensions/ObjectExtensions.cs b/src/Admin/ThingsGateway.Furion/App/Extensions/ObjectExtensions.cs index 386fed9c7..9aa793338 100644 --- a/src/Admin/ThingsGateway.Furion/App/Extensions/ObjectExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/App/Extensions/ObjectExtensions.cs @@ -455,7 +455,7 @@ public static class ObjectExtensions foreach (var property in propertys) { var p = oldType.GetProperty(property.Name); - if (property.CanWrite && p != null && p.CanRead) + if (property.CanWrite && p?.CanRead == true) { property.SetValue(o, ChangeType(p.GetValue(obj, null), property.PropertyType), null); } @@ -647,7 +647,7 @@ public static class ObjectExtensions /// 实例,true 表示空集合,false 表示非空集合 internal static bool IsEmpty(this IEnumerable collection) { - return collection == null || !collection.Any(); + return collection?.Any() != true; } diff --git a/src/Admin/ThingsGateway.Furion/AspNetCore/ModelBinders/Binders/FromConvertBinderProvider.cs b/src/Admin/ThingsGateway.Furion/AspNetCore/ModelBinders/Binders/FromConvertBinderProvider.cs index da2dfc34b..409946fdb 100644 --- a/src/Admin/ThingsGateway.Furion/AspNetCore/ModelBinders/Binders/FromConvertBinderProvider.cs +++ b/src/Admin/ThingsGateway.Furion/AspNetCore/ModelBinders/Binders/FromConvertBinderProvider.cs @@ -54,8 +54,7 @@ public class FromConvertBinderProvider : IModelBinderProvider // 判断是否定义 [FromConvert] 特性 if (context.Metadata is DefaultModelMetadata actMetadata - && actMetadata.Attributes.ParameterAttributes != null - && actMetadata.Attributes.ParameterAttributes.Count > 0 + && actMetadata.Attributes.ParameterAttributes?.Count > 0 && actMetadata.Attributes.ParameterAttributes.Any(u => u.GetType() == typeof(FromConvertAttribute))) { return new FromConvertBinder(_modelBinderConverts); diff --git a/src/Admin/ThingsGateway.Furion/Authorization/Attributes/AppAuthorizeAttribute.cs b/src/Admin/ThingsGateway.Furion/Authorization/Attributes/AppAuthorizeAttribute.cs index 424263ef2..16ed6b241 100644 --- a/src/Admin/ThingsGateway.Furion/Authorization/Attributes/AppAuthorizeAttribute.cs +++ b/src/Admin/ThingsGateway.Furion/Authorization/Attributes/AppAuthorizeAttribute.cs @@ -25,7 +25,7 @@ public sealed class AppAuthorizeAttribute : AuthorizeAttribute /// 多个策略 public AppAuthorizeAttribute(params string[] policies) { - if (policies != null && policies.Length > 0) Policies = policies; + if (policies?.Length > 0) Policies = policies; } /// diff --git a/src/Admin/ThingsGateway.Furion/Components/Attributes/DependsOnAttribute.cs b/src/Admin/ThingsGateway.Furion/Components/Attributes/DependsOnAttribute.cs index 276ee3834..6bcaf135c 100644 --- a/src/Admin/ThingsGateway.Furion/Components/Attributes/DependsOnAttribute.cs +++ b/src/Admin/ThingsGateway.Furion/Components/Attributes/DependsOnAttribute.cs @@ -47,7 +47,7 @@ public sealed class DependsOnAttribute : Attribute var components = new List(); // 遍历所有依赖组件 - if (dependComponents != null && dependComponents.Length > 0) + if (dependComponents?.Length > 0) { foreach (var component in dependComponents) { @@ -102,7 +102,7 @@ public sealed class DependsOnAttribute : Attribute var components = new List(); // 遍历所有依赖组件 - if (value != null && value.Length > 0) + if (value?.Length > 0) { foreach (var component in value) { diff --git a/src/Admin/ThingsGateway.Furion/CorsAccessor/Internal/Penetrates.cs b/src/Admin/ThingsGateway.Furion/CorsAccessor/Internal/Penetrates.cs index 87376a99e..6f0615f68 100644 --- a/src/Admin/ThingsGateway.Furion/CorsAccessor/Internal/Penetrates.cs +++ b/src/Admin/ThingsGateway.Furion/CorsAccessor/Internal/Penetrates.cs @@ -65,7 +65,7 @@ internal static class Penetrates IEnumerable exposedHeaders = corsAccessorSettings.FixedClientToken == true ? _defaultExposedHeaders : Array.Empty(); - if (corsAccessorSettings.WithExposedHeaders != null && corsAccessorSettings.WithExposedHeaders.Length > 0) + if (corsAccessorSettings.WithExposedHeaders?.Length > 0) { exposedHeaders = exposedHeaders.Concat(corsAccessorSettings.WithExposedHeaders).Distinct(StringComparer.OrdinalIgnoreCase); } diff --git a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/AESEncryption.cs b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/AESEncryption.cs index e727df64c..32171adf0 100644 --- a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/AESEncryption.cs +++ b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/AESEncryption.cs @@ -19,7 +19,7 @@ namespace ThingsGateway.DataEncryption; /// AES 加解密 /// [SuppressSniffer] -public class AESEncryption +public static class AESEncryption { /// /// 加密 diff --git a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/DESEncryption.cs b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/DESEncryption.cs index ed34e864b..d65db4e11 100644 --- a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/DESEncryption.cs +++ b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/DESEncryption.cs @@ -20,7 +20,7 @@ namespace ThingsGateway.DataEncryption; /// DES 加解密 /// [SuppressSniffer] -public class DESEncryption +public static class DESEncryption { /// /// 加密 diff --git a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/KSortEncryption.cs b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/KSortEncryption.cs index 99d17c7eb..71f30ea38 100644 --- a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/KSortEncryption.cs +++ b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/KSortEncryption.cs @@ -18,7 +18,7 @@ namespace ThingsGateway.DataEncryption; /// KSort 加密(数据签名) /// [SuppressSniffer] -public class KSortEncryption +public static class KSortEncryption { private static DateTime _timeStampStartTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); diff --git a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/PBKDF2Encryption.cs b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/PBKDF2Encryption.cs index 38f007549..053a2af68 100644 --- a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/PBKDF2Encryption.cs +++ b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/PBKDF2Encryption.cs @@ -17,7 +17,7 @@ namespace ThingsGateway.DataEncryption; /// PBKDF2 加密 /// [SuppressSniffer] -public class PBKDF2Encryption +public static class PBKDF2Encryption { private const string SaltHashSeparator = ":"; diff --git a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/SHA1Encryption.cs b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/SHA1Encryption.cs index 9ef9a64f4..8037614f1 100644 --- a/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/SHA1Encryption.cs +++ b/src/Admin/ThingsGateway.Furion/DataEncryption/Encryptions/SHA1Encryption.cs @@ -18,7 +18,7 @@ namespace ThingsGateway.DataEncryption; /// SHA1 加密 /// [SuppressSniffer] -public class SHA1Encryption +public static class SHA1Encryption { /// /// SHA1 加密 diff --git a/src/Admin/ThingsGateway.Furion/DataValidation/Attributes/DataValidationAttribute.cs b/src/Admin/ThingsGateway.Furion/DataValidation/Attributes/DataValidationAttribute.cs index c5908fc6f..baa907344 100644 --- a/src/Admin/ThingsGateway.Furion/DataValidation/Attributes/DataValidationAttribute.cs +++ b/src/Admin/ThingsGateway.Furion/DataValidation/Attributes/DataValidationAttribute.cs @@ -18,6 +18,7 @@ namespace System.ComponentModel.DataAnnotations; /// 数据类型验证特性 /// [SuppressSniffer] +[AttributeUsage(AttributeTargets.All, AllowMultiple = false)] public sealed class DataValidationAttribute : ValidationAttribute { /// diff --git a/src/Admin/ThingsGateway.Furion/DependencyInjection/Extensions/DependencyInjectionServiceCollectionExtensions.cs b/src/Admin/ThingsGateway.Furion/DependencyInjection/Extensions/DependencyInjectionServiceCollectionExtensions.cs index f77ba114e..3029ddf0b 100644 --- a/src/Admin/ThingsGateway.Furion/DependencyInjection/Extensions/DependencyInjectionServiceCollectionExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/DependencyInjection/Extensions/DependencyInjectionServiceCollectionExtensions.cs @@ -215,7 +215,7 @@ public static class DependencyInjectionServiceCollectionExtensions private static void AddDispatchProxy(IServiceCollection services, Type dependencyType, Type type, Type proxyType, Type inter, bool hasTarget = true) { proxyType ??= GlobalServiceProxyType; - if (proxyType == null || (type != null && type.IsDefined(typeof(SuppressProxyAttribute), true))) return; + if (proxyType == null || (type?.IsDefined(typeof(SuppressProxyAttribute), true) == true)) return; var lifetime = TryGetServiceLifetime(dependencyType); diff --git a/src/Admin/ThingsGateway.Furion/DynamicApiController/Conventions/DynamicApiControllerApplicationModelConvention.cs b/src/Admin/ThingsGateway.Furion/DynamicApiController/Conventions/DynamicApiControllerApplicationModelConvention.cs index 58ca1f379..d1530f6b1 100644 --- a/src/Admin/ThingsGateway.Furion/DynamicApiController/Conventions/DynamicApiControllerApplicationModelConvention.cs +++ b/src/Admin/ThingsGateway.Furion/DynamicApiController/Conventions/DynamicApiControllerApplicationModelConvention.cs @@ -220,8 +220,7 @@ internal sealed class DynamicApiControllerApplicationModelConvention : IApplicat // 解决 Gitee 该 Issue:https://gitee.com/dotnetchina/Furion/issues/I59B74 if (CheckIsForceWithDefaultRoute(controllerApiDescriptionSettings) && !string.IsNullOrWhiteSpace(_dynamicApiControllerSettings.DefaultRoutePrefix) - && controller.Selectors[0] != null - && controller.Selectors[0].AttributeRouteModel != null + && controller.Selectors[0]?.AttributeRouteModel != null && !ForceWithDefaultPrefixRouteControllerTypes.Contains(controller.ControllerType)) { // 读取模块 diff --git a/src/Admin/ThingsGateway.Furion/DynamicApiController/Extensions/DynamicApiControllerServiceCollectionExtensions.cs b/src/Admin/ThingsGateway.Furion/DynamicApiController/Extensions/DynamicApiControllerServiceCollectionExtensions.cs index 32af1b237..8707a7197 100644 --- a/src/Admin/ThingsGateway.Furion/DynamicApiController/Extensions/DynamicApiControllerServiceCollectionExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/DynamicApiController/Extensions/DynamicApiControllerServiceCollectionExtensions.cs @@ -126,7 +126,7 @@ public static class DynamicApiControllerServiceCollectionExtensions { var partManager = mvcBuilder.PartManager; // 载入程序集部件 - if (partManager != null && assemblies != null && assemblies.Any()) + if (partManager != null && assemblies?.Any() == true) { foreach (var assembly in assemblies) { diff --git a/src/Admin/ThingsGateway.Furion/DynamicApiController/Runtimes/DynamicApiRuntimeChangeProvider.cs b/src/Admin/ThingsGateway.Furion/DynamicApiController/Runtimes/DynamicApiRuntimeChangeProvider.cs index 345b93033..9e358f749 100644 --- a/src/Admin/ThingsGateway.Furion/DynamicApiController/Runtimes/DynamicApiRuntimeChangeProvider.cs +++ b/src/Admin/ThingsGateway.Furion/DynamicApiController/Runtimes/DynamicApiRuntimeChangeProvider.cs @@ -48,7 +48,7 @@ internal sealed class DynamicApiRuntimeChangeProvider : IDynamicApiRuntimeChange /// 程序集 public void AddAssemblies(params Assembly[] assemblies) { - if (assemblies != null && assemblies.Length > 0) + if (assemblies?.Length > 0) { foreach (var assembly in assemblies) { @@ -63,7 +63,7 @@ internal sealed class DynamicApiRuntimeChangeProvider : IDynamicApiRuntimeChange /// 程序集 public void AddAssembliesWithNotifyChanges(params Assembly[] assemblies) { - if (assemblies != null && assemblies.Length > 0) + if (assemblies?.Length > 0) { AddAssemblies(assemblies); NotifyChanges(); @@ -76,7 +76,7 @@ internal sealed class DynamicApiRuntimeChangeProvider : IDynamicApiRuntimeChange /// 程序集名称 public void RemoveAssemblies(params string[] assemblyNames) { - if (assemblyNames != null && assemblyNames.Length > 0) + if (assemblyNames?.Length > 0) { foreach (var assemblyName in assemblyNames) { @@ -93,7 +93,7 @@ internal sealed class DynamicApiRuntimeChangeProvider : IDynamicApiRuntimeChange /// 程序集 public void RemoveAssemblies(params Assembly[] assemblies) { - if (assemblies != null && assemblies.Length > 0) + if (assemblies?.Length > 0) { RemoveAssemblies(assemblies.Select(ass => ass.GetName().Name).ToArray()); } @@ -105,7 +105,7 @@ internal sealed class DynamicApiRuntimeChangeProvider : IDynamicApiRuntimeChange /// 程序集名称 public void RemoveAssembliesWithNotifyChanges(params string[] assemblyNames) { - if (assemblyNames != null && assemblyNames.Length > 0) + if (assemblyNames?.Length > 0) { RemoveAssemblies(assemblyNames); NotifyChanges(); @@ -118,7 +118,7 @@ internal sealed class DynamicApiRuntimeChangeProvider : IDynamicApiRuntimeChange /// 程序集 public void RemoveAssembliesWithNotifyChanges(params Assembly[] assemblies) { - if (assemblies != null && assemblies.Length > 0) + if (assemblies?.Length > 0) { RemoveAssemblies(assemblies); NotifyChanges(); diff --git a/src/Admin/ThingsGateway.Furion/FriendlyException/Exceptions/AppFriendlyException.cs b/src/Admin/ThingsGateway.Furion/FriendlyException/Exceptions/AppFriendlyException.cs index 1a125058b..bb6b9a754 100644 --- a/src/Admin/ThingsGateway.Furion/FriendlyException/Exceptions/AppFriendlyException.cs +++ b/src/Admin/ThingsGateway.Furion/FriendlyException/Exceptions/AppFriendlyException.cs @@ -49,6 +49,14 @@ public class AppFriendlyException : Exception ErrorCode = OriginErrorCode = errorCode; } + public AppFriendlyException(string? message) : base(message) + { + } + + public AppFriendlyException(string? message, Exception? innerException) : base(message, innerException) + { + } + /// /// 错误码 /// diff --git a/src/Admin/ThingsGateway.Furion/FriendlyException/Retry.cs b/src/Admin/ThingsGateway.Furion/FriendlyException/Retry.cs index 706484d27..0903dd2b5 100644 --- a/src/Admin/ThingsGateway.Furion/FriendlyException/Retry.cs +++ b/src/Admin/ThingsGateway.Furion/FriendlyException/Retry.cs @@ -102,7 +102,7 @@ public sealed class Retry } // 如果填写了 exceptionTypes 且异常类型不在 exceptionTypes 之内,则终止重试 - if (exceptionTypes != null && exceptionTypes.Length > 0 && !exceptionTypes.Any(u => u.IsAssignableFrom(ex.GetType()))) + if (exceptionTypes?.Length > 0 && !exceptionTypes.Any(u => u.IsAssignableFrom(ex.GetType()))) { if (finalThrow) { diff --git a/src/Admin/ThingsGateway.Furion/Logging/Implantations/Monitors/LoggingMonitorAttribute.cs b/src/Admin/ThingsGateway.Furion/Logging/Implantations/Monitors/LoggingMonitorAttribute.cs index 4a80674d3..d6a673e4a 100644 --- a/src/Admin/ThingsGateway.Furion/Logging/Implantations/Monitors/LoggingMonitorAttribute.cs +++ b/src/Admin/ThingsGateway.Furion/Logging/Implantations/Monitors/LoggingMonitorAttribute.cs @@ -604,7 +604,7 @@ public sealed class LoggingMonitorAttribute : Attribute, IAsyncActionFilter, IAs private string TrySerializeObject(object obj, LoggingMonitorMethod monitorMethod, out bool succeed) { // 排除 IQueryable<> 泛型 - if (obj != null && obj.GetType().HasImplementedRawGeneric(typeof(IQueryable<>))) + if (obj?.GetType().HasImplementedRawGeneric(typeof(IQueryable<>)) == true) { succeed = true; return "{}"; @@ -961,8 +961,7 @@ public sealed class LoggingMonitorAttribute : Attribute, IAsyncActionFilter, IAs // token 信息 // 判断是否是授权访问 var isAuth = actionMethod.GetFoundAttribute(true) == null - && resultHttpContext.User != null - && resultHttpContext.User.Identity.IsAuthenticated; + && resultHttpContext.User?.Identity.IsAuthenticated == true; // 获取响应头信息 var accessToken = resultHttpContext.Response.Headers["access-token"].ToString(); var authorization = string.IsNullOrWhiteSpace(accessToken) diff --git a/src/Admin/ThingsGateway.Furion/Logging/Internal/StringLoggingPartSetters.cs b/src/Admin/ThingsGateway.Furion/Logging/Internal/StringLoggingPartSetters.cs index b35a2951c..c0558d01d 100644 --- a/src/Admin/ThingsGateway.Furion/Logging/Internal/StringLoggingPartSetters.cs +++ b/src/Admin/ThingsGateway.Furion/Logging/Internal/StringLoggingPartSetters.cs @@ -47,7 +47,7 @@ public sealed partial class StringLoggingPart /// public StringLoggingPart SetArgs(params object[] args) { - if (args != null && args.Length > 0) Args = args; + if (args?.Length > 0) Args = args; return this; } diff --git a/src/Admin/ThingsGateway.Furion/ObjectMapper/Extensions/ObjectMapperServiceCollectionExtensions.cs b/src/Admin/ThingsGateway.Furion/ObjectMapper/Extensions/ObjectMapperServiceCollectionExtensions.cs index 5c5323dd8..36893adc4 100644 --- a/src/Admin/ThingsGateway.Furion/ObjectMapper/Extensions/ObjectMapperServiceCollectionExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/ObjectMapper/Extensions/ObjectMapperServiceCollectionExtensions.cs @@ -47,7 +47,7 @@ public static class ObjectMapperServiceCollectionExtensions var config = TypeAdapterConfig.GlobalSettings; // 扫描所有继承 IRegister 接口的对象映射配置 - if (assemblies != null && assemblies.Length > 0) config.Scan(assemblies); + if (assemblies?.Length > 0) config.Scan(assemblies); // 配置支持依赖注入 services.AddSingleton(config); diff --git a/src/Admin/ThingsGateway.Furion/Schedule/Builders/SchedulerBuilder.cs b/src/Admin/ThingsGateway.Furion/Schedule/Builders/SchedulerBuilder.cs index 0ef606eb5..9a688409f 100644 --- a/src/Admin/ThingsGateway.Furion/Schedule/Builders/SchedulerBuilder.cs +++ b/src/Admin/ThingsGateway.Furion/Schedule/Builders/SchedulerBuilder.cs @@ -235,7 +235,7 @@ public sealed class SchedulerBuilder var schedulerBuilder = new SchedulerBuilder(jobBuilder); // 批量添加触发器 - if (triggerBuilders != null && triggerBuilders.Length > 0) + if (triggerBuilders?.Length > 0) { schedulerBuilder.TriggerBuilders.AddRange(triggerBuilders); } diff --git a/src/Admin/ThingsGateway.Furion/Schedule/Extensions/ScheduleExtensions.cs b/src/Admin/ThingsGateway.Furion/Schedule/Extensions/ScheduleExtensions.cs index 4ac714afb..92a0cfb9f 100644 --- a/src/Admin/ThingsGateway.Furion/Schedule/Extensions/ScheduleExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/Schedule/Extensions/ScheduleExtensions.cs @@ -192,7 +192,7 @@ public static class ScheduleExtensions var underScoreCasePropertyName = Penetrates.GetNaming(propertyName, NamingConventions.UnderScoreCase); // 处理忽略属性问题 - if (ignorePropertyNames != null && ignorePropertyNames.Length > 0) + if (ignorePropertyNames?.Length > 0) { if (ignorePropertyNames.Contains(propertyName, StringComparer.OrdinalIgnoreCase) || ignorePropertyNames.Contains(camelCasePropertyName, StringComparer.OrdinalIgnoreCase) diff --git a/src/Admin/ThingsGateway.Furion/Schedule/HostedServices/ScheduleHostedService.cs b/src/Admin/ThingsGateway.Furion/Schedule/HostedServices/ScheduleHostedService.cs index d40b4ef89..3831f824a 100644 --- a/src/Admin/ThingsGateway.Furion/Schedule/HostedServices/ScheduleHostedService.cs +++ b/src/Admin/ThingsGateway.Furion/Schedule/HostedServices/ScheduleHostedService.cs @@ -327,7 +327,7 @@ internal sealed class ScheduleHostedService : BackgroundService }; // 是否定义 FallbackAsync 方法 - var isDefinedFallbackAsyncMethod = jobHandler != null && jobHandler.GetType().GetMethod(nameof(IJob.FallbackAsync) + var isDefinedFallbackAsyncMethod = jobHandler?.GetType().GetMethod(nameof(IJob.FallbackAsync) , BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly , null , new[] { typeof(JobExecutedContext), typeof(CancellationToken) } diff --git a/src/Admin/ThingsGateway.Furion/Schedule/Http/HttpJob.cs b/src/Admin/ThingsGateway.Furion/Schedule/Http/HttpJob.cs index 38c70c701..ea1590ae0 100644 --- a/src/Admin/ThingsGateway.Furion/Schedule/Http/HttpJob.cs +++ b/src/Admin/ThingsGateway.Furion/Schedule/Http/HttpJob.cs @@ -101,7 +101,7 @@ public class HttpJob : IJob } // 添加请求头 - if (httpJobMessage.Headers != null && httpJobMessage.Headers.Count > 0) + if (httpJobMessage.Headers?.Count > 0) { foreach (var (name, value) in httpJobMessage.Headers) { diff --git a/src/Admin/ThingsGateway.Furion/SpecificationDocument/Builders/SpecificationDocumentBuilder.cs b/src/Admin/ThingsGateway.Furion/SpecificationDocument/Builders/SpecificationDocumentBuilder.cs index df10d78cf..c3cf35755 100644 --- a/src/Admin/ThingsGateway.Furion/SpecificationDocument/Builders/SpecificationDocumentBuilder.cs +++ b/src/Admin/ThingsGateway.Furion/SpecificationDocument/Builders/SpecificationDocumentBuilder.cs @@ -711,7 +711,7 @@ public static class SpecificationDocumentBuilder .Union( actions.SelectMany(u => GetActionGroups(u)) ) - .Where(u => u != null && u.Visible) + .Where(u => u?.Visible == true) // 分组后取最大排序 .GroupBy(u => u.Group) .Select(u => new GroupExtraInfo diff --git a/src/Admin/ThingsGateway.Furion/Templates/TP.cs b/src/Admin/ThingsGateway.Furion/Templates/TP.cs index c65c9ddf9..96ce12aa1 100644 --- a/src/Admin/ThingsGateway.Furion/Templates/TP.cs +++ b/src/Admin/ThingsGateway.Furion/Templates/TP.cs @@ -47,7 +47,7 @@ public static class TP } // 添加项 - if (items != null && items.Length > 0) + if (items?.Length > 0) { var propMaxLength = items.Where(u => _lazyRegex.Value.IsMatch(u)) .DefaultIfEmpty(string.Empty) diff --git a/src/Admin/ThingsGateway.Furion/TimeCrontab/Crontab.Internal.cs b/src/Admin/ThingsGateway.Furion/TimeCrontab/Crontab.Internal.cs index 9898ffddb..0ba062fd3 100644 --- a/src/Admin/ThingsGateway.Furion/TimeCrontab/Crontab.Internal.cs +++ b/src/Admin/ThingsGateway.Furion/TimeCrontab/Crontab.Internal.cs @@ -343,7 +343,7 @@ public partial class Crontab // 如果存在且唯一,则进入下一轮判断 // 接下来的判断是处理 SUN + L 的情况,如 SUNL == 0L == SUNDAY,它们都是合法的 Cron 值 - if (replaceVal != null && replaceVal.Count == 1) + if (replaceVal?.Count == 1) { var missingParser = ""; diff --git a/src/Admin/ThingsGateway.Furion/UnifyResult/UnifyContext.cs b/src/Admin/ThingsGateway.Furion/UnifyResult/UnifyContext.cs index 975a7af66..8a7f0d2aa 100644 --- a/src/Admin/ThingsGateway.Furion/UnifyResult/UnifyContext.cs +++ b/src/Admin/ThingsGateway.Furion/UnifyResult/UnifyContext.cs @@ -140,10 +140,10 @@ public static class UnifyContext if (unifyResultSettings == null) return; // 篡改响应状态码 - if (unifyResultSettings.AdaptStatusCodes != null && unifyResultSettings.AdaptStatusCodes.Length > 0) + if (unifyResultSettings.AdaptStatusCodes?.Length > 0) { var adaptStatusCode = unifyResultSettings.AdaptStatusCodes.FirstOrDefault(u => u[0] == statusCode); - if (adaptStatusCode != null && adaptStatusCode.Length > 0 && adaptStatusCode[0] > 0) + if (adaptStatusCode?.Length > 0 && adaptStatusCode[0] > 0) { context.Response.StatusCode = adaptStatusCode[1]; return; diff --git a/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/TypeExtensions.cs b/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/TypeExtensions.cs index d9ff4ac72..4a2ebc1ca 100644 --- a/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/TypeExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/TypeExtensions.cs @@ -139,8 +139,7 @@ internal static class TypeExtensions } // 类型限定名是否以 <> 开头且以 AnonymousType 结尾 - return type.FullName is not null - && type.FullName.StartsWith("<>") + return type.FullName?.StartsWith("<>") == true && type.FullName.Contains("AnonymousType"); } @@ -463,7 +462,7 @@ internal static class TypeExtensions var elementType = type.GetElementType(); // 检查元素类型是否是 KeyValuePair<,> 类型 - if (elementType is null || !elementType.IsKeyValuePair()) + if (elementType?.IsKeyValuePair() != true) { return false; } diff --git a/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/V5_ObjectExtensions.cs b/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/V5_ObjectExtensions.cs index a3cff3a2e..15a6117e9 100644 --- a/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/V5_ObjectExtensions.cs +++ b/src/Admin/ThingsGateway.Furion/V5_Experience/Core/Extensions/V5_ObjectExtensions.cs @@ -135,7 +135,7 @@ internal static class V5_ObjectExtensions var runtimeProperty = obj.GetType().GetRuntimeProperty("Count"); // 反射获取 Count 属性值 - if (runtimeProperty is not null && runtimeProperty.CanRead && runtimeProperty.PropertyType == typeof(int)) + if (runtimeProperty?.CanRead == true && runtimeProperty.PropertyType == typeof(int)) { count = (int)runtimeProperty.GetValue(obj)!; return true; @@ -332,7 +332,7 @@ internal static class V5_ObjectExtensions var property = current.GetType().GetProperty(part, bindingFlags); // 空检查 - if (property is null || !property.CanRead) + if (property?.CanRead != true) { return null; } diff --git a/src/Admin/ThingsGateway.Furion/V5_Experience/HttpRemote/Builders/HttpRequestBuilder.Methods.cs b/src/Admin/ThingsGateway.Furion/V5_Experience/HttpRemote/Builders/HttpRequestBuilder.Methods.cs index bb13838e9..529642fea 100644 --- a/src/Admin/ThingsGateway.Furion/V5_Experience/HttpRemote/Builders/HttpRequestBuilder.Methods.cs +++ b/src/Admin/ThingsGateway.Furion/V5_Experience/HttpRemote/Builders/HttpRequestBuilder.Methods.cs @@ -1591,7 +1591,7 @@ public sealed partial class HttpRequestBuilder public HttpRequestBuilder SetBaseAddress(Uri? baseAddress) { // 检查基地址是否是绝对路径地址 - if (baseAddress is not null && !baseAddress.IsAbsoluteUri) + if (baseAddress?.IsAbsoluteUri == false) { throw new ArgumentException("The base address must be absolute.", nameof(baseAddress)); } diff --git a/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Events.cs b/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Events.cs index a3639d1eb..5a2e1bade 100644 --- a/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Events.cs +++ b/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Events.cs @@ -136,7 +136,7 @@ public partial class Clay { handler(this, new ClayEventArgs(identifier, Contains(identifier))); } - catch (Exception) + catch { // ignored } diff --git a/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Exports.cs b/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Exports.cs index 90d5dc38c..eef58ab7f 100644 --- a/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Exports.cs +++ b/src/Admin/ThingsGateway.Furion/V5_Experience/Shapeless/Clay/Clay.Exports.cs @@ -177,15 +177,6 @@ public partial class Clay enumerableClay = this; } - /// - /// - /// dynamic 类型的 - /// - /// - /// - /// - /// - /// public void Deconstruct(out dynamic clay, out IEnumerable enumerableClay, out Clay rawClay) { clay = this; @@ -888,7 +879,7 @@ public partial class Clay foreach (var item in values) { // 检查值是否为空值或基本类型的值 - if (item is null || item.GetType().IsBasicType()) + if (item?.GetType().IsBasicType() != false) { throw new InvalidOperationException("Cannot extend a single object with null or basic type values."); } diff --git a/src/Admin/ThingsGateway.NewLife.X/Attributes/MinValueAttribute.cs b/src/Admin/ThingsGateway.NewLife.X/Attributes/MinValueAttribute.cs index 6040f62c7..c7717f1f8 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Attributes/MinValueAttribute.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Attributes/MinValueAttribute.cs @@ -12,9 +12,11 @@ using System.ComponentModel.DataAnnotations; namespace ThingsGateway; + /// /// 最小值校验 /// +[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public sealed class MinValueAttribute : ValidationAttribute { /// diff --git a/src/Admin/ThingsGateway.NewLife.X/Buffers/SpanReader.cs b/src/Admin/ThingsGateway.NewLife.X/Buffers/SpanReader.cs index 1e56db88a..17590de8d 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Buffers/SpanReader.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Buffers/SpanReader.cs @@ -244,7 +244,6 @@ public ref struct SpanReader while (true) { var bt = ReadByte(); - if (bt < 0) throw new Exception($"The data stream is out of range! The integer read is {rs: n0}"); b = (Byte)bt; // 必须转为Int32,否则可能溢出 diff --git a/src/Admin/ThingsGateway.NewLife.X/Caching/MemoryCache.cs b/src/Admin/ThingsGateway.NewLife.X/Caching/MemoryCache.cs index 81076244d..b8df8e09d 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Caching/MemoryCache.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Caching/MemoryCache.cs @@ -120,7 +120,7 @@ public class MemoryCache : Cache /// 是否包含缓存项 /// /// - public override Boolean ContainsKey(String key) => _cache.TryGetValue(key, out var item) && item != null && !item.Expired; + public override Boolean ContainsKey(String key) => _cache.TryGetValue(key, out var item) && item?.Expired == false; /// 添加缓存项,已存在时更新 /// 值类型 @@ -166,7 +166,7 @@ public class MemoryCache : Cache [return: MaybeNull] public override T Get(String key) { - if (!_cache.TryGetValue(key, out var item) || item == null || item.Expired) return default; + if (!_cache.TryGetValue(key, out var item) || item?.Expired != false) return default; return item.Visit(); } @@ -712,7 +712,7 @@ public class MemoryCache : Cache for (var i = 0; i < slist.Count && over > 0; i++) { var ss = slist.Values[i]; - if (ss != null && ss.Count > 0) + if (ss?.Count > 0) { foreach (var item in ss) { diff --git a/src/Admin/ThingsGateway.NewLife.X/Collections/ObjectPool.cs b/src/Admin/ThingsGateway.NewLife.X/Collections/ObjectPool.cs index 93d72b3ae..c71ac53ea 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Collections/ObjectPool.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Collections/ObjectPool.cs @@ -402,7 +402,7 @@ public class ObjectPool : DisposeBase, IPool where T : notnull /// public void WriteLog(String format, params Object?[] args) { - if (Log == null || !Log.Enable) return; + if (Log?.Enable != true) return; Log.Info(Name + "." + format, args); } diff --git a/src/Admin/ThingsGateway.NewLife.X/Common/FileUtil.cs b/src/Admin/ThingsGateway.NewLife.X/Common/FileUtil.cs index 0c499480e..b8dba675f 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Common/FileUtil.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Common/FileUtil.cs @@ -15,7 +15,7 @@ namespace ThingsGateway.NewLife; /// /// FileUtil /// -public class FileUtil +public static class FileUtil { /// /// 读取文件 diff --git a/src/Admin/ThingsGateway.NewLife.X/Common/MachineInfo.cs b/src/Admin/ThingsGateway.NewLife.X/Common/MachineInfo.cs index b1c47572b..fed41f0fc 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Common/MachineInfo.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Common/MachineInfo.cs @@ -633,7 +633,7 @@ public class MachineInfo if (!_excludes.Contains(nameof(Temperature))) { var temp = ReadWmic(@"/namespace:\\root\wmi path MSAcpi_ThermalZoneTemperature", "CurrentTemperature"); - if (temp != null && temp.Count > 0) + if (temp?.Count > 0) { if (temp.TryGetValue("CurrentTemperature", out var str) && !str.IsNullOrEmpty()) Temperature = (str.SplitAsInt().Average() - 2732) / 10.0; @@ -651,7 +651,7 @@ public class MachineInfo else if (!_excludes.Contains(nameof(Battery))) { var battery = ReadWmic("path win32_battery", "EstimatedChargeRemaining"); - if (battery != null && battery.Count > 0) + if (battery?.Count > 0) { if (battery.TryGetValue("EstimatedChargeRemaining", out var str) && !str.IsNullOrEmpty()) Battery = str.SplitAsInt().Average() / 100.0; @@ -937,7 +937,7 @@ public class MachineInfo foreach (var item in ss) { var ks = item?.Split('='); - if (ks != null && ks.Length >= 2) + if (ks?.Length >= 2) { var k = ks[0].Trim(); var v = ks[1].Trim().TrimInvisible(); @@ -1079,7 +1079,7 @@ public class MachineInfo if (root.IsNullOrEmpty()) return 0; var driveInfo = new DriveInfo(root); - if (driveInfo == null || !driveInfo.IsReady) return -1; + if (driveInfo?.IsReady != true) return -1; try { diff --git a/src/Admin/ThingsGateway.NewLife.X/Common/PinYin.cs b/src/Admin/ThingsGateway.NewLife.X/Common/PinYin.cs index 2602c5d42..0135da99d 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Common/PinYin.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Common/PinYin.cs @@ -6,7 +6,7 @@ namespace ThingsGateway.NewLife.Common; /// /// 文档 https://newlifex.com/core/pinyin /// -public class PinYin +public static class PinYin { #region 数组信息 private static readonly Int32[] pyValue = new[] { diff --git a/src/Admin/ThingsGateway.NewLife.X/Common/Runtime.cs b/src/Admin/ThingsGateway.NewLife.X/Common/Runtime.cs index f8f8b02c7..6b65be0f1 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Common/Runtime.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Common/Runtime.cs @@ -199,7 +199,7 @@ public static class Runtime if (processId != ProcessId) gc = false; var log = XTrace.Log; - if (log != null && log.Enable && log.Level <= LogLevel.Debug) + if (log?.Enable == true && log.Level <= LogLevel.Debug) { p ??= Process.GetCurrentProcess(); var gcm = GC.GetTotalMemory(false) / 1024; @@ -243,7 +243,7 @@ public static class Runtime } } - if (log != null && log.Enable && log.Level <= LogLevel.Debug) + if (log?.Enable == true && log.Level <= LogLevel.Debug) { p ??= Process.GetProcessById(processId); p.Refresh(); diff --git a/src/Admin/ThingsGateway.NewLife.X/Configuration/ConfigHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Configuration/ConfigHelper.cs index 90a21aece..f5d2ccbc7 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Configuration/ConfigHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Configuration/ConfigHelper.cs @@ -108,7 +108,7 @@ public static class ConfigHelper dic[cfg.Key] = cfg.Value; - if (cfg.Childs != null && cfg.Childs.Count > 0) + if (cfg.Childs?.Count > 0) dic[cfg.Key] = cfg.Childs; } diff --git a/src/Admin/ThingsGateway.NewLife.X/Configuration/IConfigSection.cs b/src/Admin/ThingsGateway.NewLife.X/Configuration/IConfigSection.cs index a4245d64f..582af4852 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Configuration/IConfigSection.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Configuration/IConfigSection.cs @@ -54,6 +54,6 @@ public class ConfigSection : IConfigSection /// 已重载。 /// - public override String ToString() => Childs != null && Childs.Count > 0 ? $"{Key}[{Childs.Count}]" : $"{Key}={Value}"; + public override String ToString() => Childs?.Count > 0 ? $"{Key}[{Childs.Count}]" : $"{Key}={Value}"; #endregion } \ No newline at end of file diff --git a/src/Admin/ThingsGateway.NewLife.X/Configuration/IniConfigProvider.cs b/src/Admin/ThingsGateway.NewLife.X/Configuration/IniConfigProvider.cs index a3c65f1db..d91cf392c 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Configuration/IniConfigProvider.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Configuration/IniConfigProvider.cs @@ -75,7 +75,7 @@ public class InIConfigProvider : FileConfigProvider var sb = new StringBuilder(); foreach (var item in section.Childs.ToArray()) { - if (item.Childs != null && item.Childs.Count > 0) + if (item.Childs?.Count > 0) { // 段前空一行 sb.AppendLine(); diff --git a/src/Admin/ThingsGateway.NewLife.X/Event/WeakAction.cs b/src/Admin/ThingsGateway.NewLife.X/Event/WeakAction.cs index 0a30f6b30..214dc1969 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Event/WeakAction.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Event/WeakAction.cs @@ -41,7 +41,7 @@ public class WeakAction var target = Target; if (target == null && Method.IsStatic) return true; - return target != null && target.IsAlive; + return target?.IsAlive == true; } } #endregion diff --git a/src/Admin/ThingsGateway.NewLife.X/Extension/DateExtensions.cs b/src/Admin/ThingsGateway.NewLife.X/Extension/DateExtensions.cs index 717361690..6bff46f59 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Extension/DateExtensions.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Extension/DateExtensions.cs @@ -65,7 +65,7 @@ public static class DateExtensions /// 开始时间 /// 结束时间 /// 时间差 - public static string GetDiffTime(this in DateTime beginTime, in DateTime endTime) + public static string GetDiffTime(this DateTime beginTime, DateTime endTime) { TimeSpan timeDifference = endTime - beginTime; if (timeDifference.TotalDays >= 1) @@ -88,7 +88,7 @@ public static class DateExtensions /// 开始时间 /// 结束时间 /// 时间差 - public static string GetDiffTime(this in DateTimeOffset beginTime, in DateTimeOffset endTime) + public static string GetDiffTime(this DateTimeOffset beginTime, DateTimeOffset endTime) { TimeSpan timeDifference = endTime - beginTime; if (timeDifference.TotalDays >= 1) @@ -108,7 +108,7 @@ public static class DateExtensions /// /// 返回yyyy-MM-ddTHH:mm:ss.fffffffzzz时间格式字符串 /// - public static string ToDefaultDateTimeFormat(this in DateTime dt, TimeSpan offset) + public static string ToDefaultDateTimeFormat(this DateTime dt, TimeSpan offset) { if (dt.Kind == DateTimeKind.Utc) return new DateTimeOffset(dt.ToLocalTime(), offset).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz"); @@ -129,7 +129,7 @@ public static class DateExtensions /// /// 返回yyyy-MM-ddTHH:mm:ss.fffffffzzz时间格式字符串 /// - public static string ToDefaultDateTimeFormat(this in DateTime dt) + public static string ToDefaultDateTimeFormat(this DateTime dt) { return dt.ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz"); } @@ -137,7 +137,7 @@ public static class DateExtensions /// /// 返回yyyy-MM-dd HH-mm-ss-fff zz时间格式字符串 /// - public static string ToFileDateTimeFormat(this in DateTime dt) + public static string ToFileDateTimeFormat(this DateTime dt) { return ToDefaultDateTimeFormat(dt).Replace(":", "-"); } @@ -145,7 +145,7 @@ public static class DateExtensions /// /// 返回yyyy-MM-dd HH-mm-ss-fff zz时间格式字符串 /// - public static string ToFileDateTimeFormat(this in DateTime dt, TimeSpan offset) + public static string ToFileDateTimeFormat(this DateTime dt, TimeSpan offset) { return ToDefaultDateTimeFormat(dt, offset).Replace(":", "-"); } diff --git a/src/Admin/ThingsGateway.NewLife.X/Extension/EndPointExtensions.cs b/src/Admin/ThingsGateway.NewLife.X/Extension/EndPointExtensions.cs index 45312254d..79e547577 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Extension/EndPointExtensions.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Extension/EndPointExtensions.cs @@ -6,31 +6,18 @@ namespace ThingsGateway.NewLife.Extension; /// 网络结点扩展 public static class EndPointExtensions { - /// - /// - /// - /// - /// public static String ToAddress(this EndPoint endpoint) { return ((IPEndPoint)endpoint).ToAddress(); } - /// - /// - /// - /// - /// + public static String ToAddress(this IPEndPoint endpoint) { return String.Format("{0}:{1}", endpoint.Address, endpoint.Port); } private static readonly String[] SplitColon = new String[] { ":" }; - /// - /// - /// - /// - /// + public static IPEndPoint ToEndPoint(this String address) { var array = address.Split(SplitColon, StringSplitOptions.RemoveEmptyEntries); @@ -44,11 +31,7 @@ public static class EndPointExtensions } private static readonly String[] SplitComma = new String[] { "," }; - /// - /// - /// - /// - /// + public static IEnumerable ToEndPoints(this String addresses) { var array = addresses.Split(SplitComma, StringSplitOptions.RemoveEmptyEntries); diff --git a/src/Admin/ThingsGateway.NewLife.X/Extension/ProcessHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Extension/ProcessHelper.cs index 763a05baa..9ff38c12a 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Extension/ProcessHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Extension/ProcessHelper.cs @@ -24,7 +24,7 @@ public static class ProcessHelper if (pname == "dotnet" || "*/dotnet".IsMatch(pname)) { var args = GetCommandLineArgs(process.Id); - if (args != null && args.Length >= 2 && args[0].Contains("dotnet")) + if (args?.Length >= 2 && args[0].Contains("dotnet")) { return Path.GetFileNameWithoutExtension(args[1]); } @@ -32,7 +32,7 @@ public static class ProcessHelper if (pname == "java" || "*/java".IsMatch(pname)) { var args = GetCommandLineArgs(process.Id); - if (args != null && args.Length >= 3 && args[0].Contains("java") && args[1] == "-jar") + if (args?.Length >= 3 && args[0].Contains("java") && args[1] == "-jar") { return Path.GetFileNameWithoutExtension(args[2]); } @@ -210,7 +210,7 @@ public static class ProcessHelper /// public static Process? SafetyKill(this Process process, Int32 msWait = 5_000, Int32 times = 50, Int32 interval = 200) { - if (process == null || process.GetHasExited()) return process; + if (process?.GetHasExited() != false) return process; //XTrace.WriteLine("安全,温柔一刀!PID={0}/{1}", process.Id, process.ProcessName); @@ -248,7 +248,7 @@ public static class ProcessHelper /// public static Process? ForceKill(this Process process, Int32 msWait = 5_000) { - if (process == null || process.GetHasExited()) return process; + if (process?.GetHasExited() != false) return process; //XTrace.WriteLine("强杀,大力出奇迹!PID={0}/{1}", process.Id, process.ProcessName); diff --git a/src/Admin/ThingsGateway.NewLife.X/Extension/StringHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Extension/StringHelper.cs index 6e44d7783..a46d41162 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Extension/StringHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Extension/StringHelper.cs @@ -137,7 +137,7 @@ public static class StringHelper public static IDictionary SplitAsDictionary(this String? value, String nameValueSeparator = "=", String separator = ";", Boolean trimQuotation = false) { var dic = new NullableDictionary(StringComparer.OrdinalIgnoreCase); - if (value == null || value.IsNullOrWhiteSpace()) return dic; + if (value?.IsNullOrWhiteSpace() != false) return dic; if (nameValueSeparator.IsNullOrEmpty()) nameValueSeparator = "="; //if (separator == null || separator.Length <= 0) separator = new String[] { ",", ";" }; @@ -515,7 +515,7 @@ public static class StringHelper p += after.Length; // 记录位置 - if (positions != null && positions.Length > 0) positions[0] = p; + if (positions?.Length > 0) positions[0] = p; } if (String.IsNullOrEmpty(before)) return str[p..]; @@ -524,7 +524,7 @@ public static class StringHelper if (f < 0) return String.Empty; // 记录位置 - if (positions != null && positions.Length > 1) positions[1] = f; + if (positions?.Length > 1) positions[1] = f; if (p >= 0) return str[p..f]; @@ -770,7 +770,7 @@ public static class StringHelper { var rs = new List>(); - if (list == null || !list.Any()) return rs; + if (list?.Any() != true) return rs; if (keys.IsNullOrWhiteSpace()) return rs; if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -825,7 +825,7 @@ public static class StringHelper { var rs = new List>(); - if (list == null || !list.Any()) return rs; + if (list?.Any() != true) return rs; if (keys.IsNullOrWhiteSpace()) return rs; if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); diff --git a/src/Admin/ThingsGateway.NewLife.X/IO/ExcelReader.cs b/src/Admin/ThingsGateway.NewLife.X/IO/ExcelReader.cs index a770a1daf..ddeb12cb5 100644 --- a/src/Admin/ThingsGateway.NewLife.X/IO/ExcelReader.cs +++ b/src/Admin/ThingsGateway.NewLife.X/IO/ExcelReader.cs @@ -110,7 +110,7 @@ public class ExcelReader : DisposeBase // 加快样式判断速度 var styles = _styles; - if (styles != null && styles.Length == 0) styles = null; + if (styles?.Length == 0) styles = null; foreach (var row in data.Elements()) { @@ -139,7 +139,7 @@ public class ExcelReader : DisposeBase // t=DataType, s=SharedString, b=Boolean, n=Number, d=Date var t = col.Attribute("t"); - if (t != null && t.Value == "s") + if (t?.Value == "s") { val = _sharedStrings?[val.ToInt()]; } @@ -153,7 +153,7 @@ public class ExcelReader : DisposeBase if (si < styles.Length) { var st = styles[si]; - if (st != null && st.StartsWith("yy")) + if (st?.StartsWith("yy") == true) { if (val.Contains('.')) { diff --git a/src/Admin/ThingsGateway.NewLife.X/IO/FileSource.cs b/src/Admin/ThingsGateway.NewLife.X/IO/FileSource.cs index bc8b92bd8..1e2c49800 100644 --- a/src/Admin/ThingsGateway.NewLife.X/IO/FileSource.cs +++ b/src/Admin/ThingsGateway.NewLife.X/IO/FileSource.cs @@ -122,7 +122,7 @@ namespace ThingsGateway.NewLife.IO var name = String.Empty; if (asm == null) asm = Assembly.GetCallingAssembly(); var ss = asm.GetManifestResourceNames(); - if (ss != null && ss.Length > 0) + if (ss?.Length > 0) { //找到资源名 name = ss.FirstOrDefault(e => e == filename); diff --git a/src/Admin/ThingsGateway.NewLife.X/IO/IOHelper.cs b/src/Admin/ThingsGateway.NewLife.X/IO/IOHelper.cs index 4691932af..389ab6363 100644 --- a/src/Admin/ThingsGateway.NewLife.X/IO/IOHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/IO/IOHelper.cs @@ -155,7 +155,7 @@ public static class IOHelper /// public static Stream Write(this Stream des, params Byte[] src) { - if (src != null && src.Length > 0) des.Write(src, 0, src.Length); + if (src?.Length > 0) des.Write(src, 0, src.Length); return des; } @@ -343,7 +343,7 @@ public static class IOHelper // 可能数据流前面有编码字节序列,需要先去掉 var idx = 0; var preamble = encoding.GetPreamble(); - if (preamble != null && preamble.Length > 0) + if (preamble?.Length > 0) { if (buf.Take(preamble.Length).SequenceEqual(preamble)) idx = preamble.Length; } @@ -368,7 +368,7 @@ public static class IOHelper // 可能数据流前面有编码字节序列,需要先去掉 var idx = 0; var preamble = encoding.GetPreamble(); - if (preamble != null && preamble.Length > 0 && buf.Length >= offset + preamble.Length) + if (preamble?.Length > 0 && buf.Length >= offset + preamble.Length) { if (buf.Skip(offset).Take(preamble.Length).SequenceEqual(preamble)) idx = preamble.Length; } diff --git a/src/Admin/ThingsGateway.NewLife.X/IO/PathHelper.cs b/src/Admin/ThingsGateway.NewLife.X/IO/PathHelper.cs index b4fd4bf7a..026e0b559 100644 --- a/src/Admin/ThingsGateway.NewLife.X/IO/PathHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/IO/PathHelper.cs @@ -278,7 +278,7 @@ public static class PathHelper public static Boolean CopyToIfNewer(this FileInfo fi, String destFileName) { // 源文件必须存在 - if (fi == null || !fi.Exists) return false; + if (fi?.Exists != true) return false; var dest = destFileName.AsFile(); // 目标文件必须存在且源文件较新 @@ -425,7 +425,7 @@ public static class PathHelper /// public static IEnumerable GetAllFiles(this DirectoryInfo di, String? exts = null, Boolean allSub = false) { - if (di == null || !di.Exists) yield break; + if (di?.Exists != true) yield break; if (String.IsNullOrEmpty(exts)) exts = "*"; var opt = allSub ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; @@ -525,7 +525,7 @@ public static class PathHelper Console.WriteLine("\t{1}\t{0}", name, item.CombinePath(name).AsFile().LastWriteTime.ToFullString()); Console.ResetColor(); }); - if (rs != null && rs.Length > 0) list.AddRange(rs); + if (rs?.Length > 0) list.AddRange(rs); } catch (Exception ex) { Console.WriteLine(" " + ex.Message); } } diff --git a/src/Admin/ThingsGateway.NewLife.X/Logger/Logger.cs b/src/Admin/ThingsGateway.NewLife.X/Logger/Logger.cs index 069f326cc..362bbeafc 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Logger/Logger.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Logger/Logger.cs @@ -62,7 +62,7 @@ public abstract class Logger : ILog protected virtual String Format(String format, Object?[]? args) { //处理时间的格式化 - if (args != null && args.Length > 0) + if (args?.Length > 0) { // 特殊处理异常 if (args.Length == 1 && args[0] is Exception ex && (format.IsNullOrEmpty() || format == "{0}")) diff --git a/src/Admin/ThingsGateway.NewLife.X/Logger/TextFileLog.cs b/src/Admin/ThingsGateway.NewLife.X/Logger/TextFileLog.cs index 0acf2500d..4ec1e22bd 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Logger/TextFileLog.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Logger/TextFileLog.cs @@ -229,7 +229,7 @@ public class TextFileLog : Logger, IDisposable try { var dels = di.GetFiles("*.del"); - if (dels != null && dels.Length > 0) + if (dels?.Length > 0) { foreach (var item in dels) { @@ -304,7 +304,7 @@ public class TextFileLog : Logger, IDisposable var e = WriteLogEventArgs.Current.Set(level); // 特殊处理异常对象 - if (args != null && args.Length == 1 && args[0] is Exception ex && (format.IsNullOrEmpty() || format == "{0}")) + if (args?.Length == 1 && args[0] is Exception ex && (format.IsNullOrEmpty() || format == "{0}")) e = e.Set(null, ex); else e = e.Set(Format(format, args), null); diff --git a/src/Admin/ThingsGateway.NewLife.X/Net/IDnsResolver.cs b/src/Admin/ThingsGateway.NewLife.X/Net/IDnsResolver.cs index 7bcc594f8..ac807d32d 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Net/IDnsResolver.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Net/IDnsResolver.cs @@ -54,7 +54,7 @@ public class DnsResolver : IDnsResolver if (!task.Wait(5000)) throw new TaskCanceledException(); var addrs = task.ConfigureAwait(false).GetAwaiter().GetResult(); #endif - if (addrs != null && addrs.Length > 0) + if (addrs?.Length > 0) { // 更新缓存数据 @@ -76,9 +76,9 @@ public class DnsResolver : IDnsResolver } } } - catch (Exception ex) + catch (Exception) { - if (throwError) throw ex; + if (throwError) throw; } return item; diff --git a/src/Admin/ThingsGateway.NewLife.X/Net/NetHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Net/NetHelper.cs index 544ad81f6..283e15b90 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Net/NetHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Net/NetHelper.cs @@ -180,7 +180,7 @@ public static class NetHelper { // 如果不是任意地址,直接返回 var addr = address; - if (addr == null || !addr.IsAny()) return addr; + if (addr?.IsAny() != true) return addr; // 如果是本地环回地址,返回环回地址 if (IPAddress.IsLoopback(remote)) return addr.IsIPv4() ? IPAddress.Loopback : IPAddress.IPv6Loopback; @@ -300,7 +300,7 @@ public static class NetHelper } } #else - if (item != null && item.DhcpServerAddresses.Count > 0) + if (item?.DhcpServerAddresses.Count > 0) { foreach (var elm in item.DhcpServerAddresses) { @@ -321,7 +321,7 @@ public static class NetHelper var list = new List(); foreach (var item in GetActiveInterfaces()) { - if (item != null && item.DnsAddresses.Count > 0) + if (item?.DnsAddresses.Count > 0) { foreach (var elm in item.DnsAddresses) { @@ -341,7 +341,7 @@ public static class NetHelper var list = new List(); foreach (var item in GetActiveInterfaces()) { - if (item != null && item.GatewayAddresses.Count > 0) + if (item?.GatewayAddresses.Count > 0) { foreach (var elm in item.GatewayAddresses) { @@ -365,7 +365,7 @@ public static class NetHelper if (item.NetworkInterfaceType is NetworkInterfaceType.Loopback or NetworkInterfaceType.Tunnel or NetworkInterfaceType.Unknown) continue; var ipp = item.GetIPProperties(); - if (ipp != null && ipp.UnicastAddresses.Count > 0) + if (ipp?.UnicastAddresses.Count > 0) { var gw = 0; @@ -446,7 +446,7 @@ public static class NetHelper var list = new List(); foreach (var item in GetActiveInterfaces()) { - if (item != null && item.MulticastAddresses.Count > 0) + if (item?.MulticastAddresses.Count > 0) { foreach (var elm in item.MulticastAddresses) { @@ -480,7 +480,7 @@ public static class NetHelper if (addrs.Length > 0 && addrs.All(e => IPAddress.IsLoopback(e))) continue; var mac = item.GetPhysicalAddress()?.GetAddressBytes(); - if (mac != null && mac.Length == 6) yield return mac; + if (mac?.Length == 6) yield return mac; } } @@ -508,7 +508,7 @@ public static class NetHelper if (addrs.Length == 0) continue; var mac = item.GetPhysicalAddress()?.GetAddressBytes(); - if (mac != null && mac.Length == 6) return mac; + if (mac?.Length == 6) return mac; } return null; @@ -604,7 +604,7 @@ public static class NetHelper buf = item.GetPhysicalAddress()?.GetAddressBytes(); } - if (buf != null && buf.Length == 6) return buf; + if (buf?.Length == 6) return buf; } } diff --git a/src/Admin/ThingsGateway.NewLife.X/Net/NetUri.cs b/src/Admin/ThingsGateway.NewLife.X/Net/NetUri.cs index 615784509..0d58f78cf 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Net/NetUri.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Net/NetUri.cs @@ -67,7 +67,7 @@ public class NetUri { var ep = _EndPoint; ep ??= _EndPoint = new IPEndPoint(IPAddress.Any, 0); - if ((ep.Address == null || ep.Address.IsAny()) && !Host.IsNullOrEmpty()) ep.Address = ParseAddress(Host)?.FirstOrDefault() ?? IPAddress.Any; + if ((ep.Address?.IsAny() != false) && !Host.IsNullOrEmpty()) ep.Address = ParseAddress(Host)?.FirstOrDefault() ?? IPAddress.Any; return ep; } diff --git a/src/Admin/ThingsGateway.NewLife.X/Net/TcpConnectionInformation2.cs b/src/Admin/ThingsGateway.NewLife.X/Net/TcpConnectionInformation2.cs index daa6ab60f..e42b2a06e 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Net/TcpConnectionInformation2.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Net/TcpConnectionInformation2.cs @@ -179,10 +179,10 @@ public class TcpConnectionInformation2 : TcpConnectionInformation // 各个进程底下的/net/tcp,实际上是所有进程的连接 var rs = ParseTcpsFromFile(processId > 0 ? $"/proc/{processId}/net/tcp" : "/proc/net/tcp"); - if (rs != null && rs.Count > 0) list.AddRange(rs); + if (rs?.Count > 0) list.AddRange(rs); var rs2 = ParseTcpsFromFile(processId > 0 ? $"/proc/{processId}/net/tcp6" : "/proc/net/tcp6"); - if (rs2 != null && rs2.Count > 0) list.AddRange(rs2); + if (rs2?.Count > 0) list.AddRange(rs2); //XTrace.WriteLine("tcps: {0} nodes: {1}", list.Count, nodes?.Length); // 过滤指定进程的连接 diff --git a/src/Admin/ThingsGateway.NewLife.X/Reflection/AssemblyX.cs b/src/Admin/ThingsGateway.NewLife.X/Reflection/AssemblyX.cs index c9628db56..7b90efc82 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Reflection/AssemblyX.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Reflection/AssemblyX.cs @@ -84,7 +84,7 @@ public class AssemblyX { try { - return Asm == null || Asm.IsDynamic ? null : Asm.Location; + return Asm?.IsDynamic != false ? null : Asm.Location; } catch { return null; } } @@ -187,7 +187,7 @@ public class AssemblyX if (item == null) continue; var ts2 = item.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - if (ts2 != null && ts2.Length > 0) + if (ts2?.Length > 0) { // 从下一个元素开始插入,让内嵌类紧挨着主类 //Int32 k = i + 1; @@ -332,7 +332,7 @@ public class AssemblyX { foreach (var item in types) { - if (item != null && !item.IsInterface && !item.IsAbstract && !item.IsGenericType && item != baseType && item.As(baseType)) list.Add(item); + if (item?.IsInterface == false && !item.IsAbstract && !item.IsGenericType && item != baseType && item.As(baseType)) list.Add(item); } } @@ -360,7 +360,7 @@ public class AssemblyX foreach (var item in GetAssemblies()) { signs = item.Asm.GetName().GetPublicKey(); - if (hasNotSign && signs != null && signs.Length > 0) continue; + if (hasNotSign && signs?.Length > 0) continue; //// 如果excludeGlobalTypes为true,则指检查来自非GAC引用的程序集 //if (excludeGlobalTypes && item.Asm.GlobalAssemblyCache) continue; @@ -389,7 +389,7 @@ public class AssemblyX if (item.IsSystemAssembly || !IsReferencedFrom(item.Asm, baseAssemblyName)) continue; var ts = item.FindPlugins(baseType); - if (ts != null && ts.Count > 0) + if (ts?.Count > 0) { // 真实加载 if (XTrace.Debug) diff --git a/src/Admin/ThingsGateway.NewLife.X/Reflection/AttributeX.cs b/src/Admin/ThingsGateway.NewLife.X/Reflection/AttributeX.cs index 62af3412b..c19cd43e0 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Reflection/AttributeX.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Reflection/AttributeX.cs @@ -36,7 +36,7 @@ public static class AttributeX public static String? GetDisplayName(this MemberInfo member, Boolean inherit = true) { var att = member.GetCustomAttribute(inherit); - if (att != null && !att.DisplayName.IsNullOrWhiteSpace()) return att.DisplayName; + if (att?.DisplayName.IsNullOrWhiteSpace() == false) return att.DisplayName; return null; } @@ -48,7 +48,7 @@ public static class AttributeX public static String? GetDescription(this MemberInfo member, Boolean inherit = true) { var att2 = member.GetCustomAttribute(inherit); - if (att2 != null && !att2.Description.IsNullOrWhiteSpace()) return att2.Description; + if (att2?.Description.IsNullOrWhiteSpace() == false) return att2.Description; return null; } @@ -72,7 +72,7 @@ public static class AttributeX if (typeof(TAttribute) != item.Constructor.DeclaringType) continue; var args = item.ConstructorArguments; - if (args != null && args.Count > 0) return (TResult?)args[0].Value; + if (args?.Count > 0) return (TResult?)args[0].Value; } } catch { } @@ -93,14 +93,14 @@ public static class AttributeX try { var list = CustomAttributeData.GetCustomAttributes(target); - if (list != null && list.Count > 0) + if (list?.Count > 0) { foreach (var item in list) { if (typeof(TAttribute).FullName != item.Constructor.DeclaringType?.FullName) continue; var args = item.ConstructorArguments; - if (args != null && args.Count > 0) return (TResult?)args[0].Value; + if (args?.Count > 0) return (TResult?)args[0].Value; } } if (inherit && target is Type type && type.BaseType != null) diff --git a/src/Admin/ThingsGateway.NewLife.X/Reflection/IReflect.cs b/src/Admin/ThingsGateway.NewLife.X/Reflection/IReflect.cs index 592c299de..78c364f37 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Reflection/IReflect.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Reflection/IReflect.cs @@ -295,7 +295,7 @@ public class DefaultReflect : IReflect while (type2 != null && type2 != typeof(Object)) { var fs = type2.GetMember(name, ignoreCase ? bfic : bf); - if (fs != null && fs.Length > 0) + if (fs?.Length > 0) { // 得到多个的时候,优先返回精确匹配 if (ignoreCase && fs.Length > 1) @@ -566,7 +566,7 @@ public class DefaultReflect : IReflect foreach (var pi in targetType.GetProperties(true)) { if (!pi.CanWrite) continue; - if (excludes != null && excludes.Contains(pi.Name)) continue; + if (excludes?.Contains(pi.Name) == true) continue; if (sourceProperties.TryGetValue(pi.Name, out var pi2) && pi2.CanRead) SetValue(target, pi, GetValue(source, pi2)); @@ -579,7 +579,7 @@ public class DefaultReflect : IReflect foreach (var pi in sourceProperties.Values) { if (!pi.CanRead) continue; - if (excludes != null && excludes.Contains(pi.Name)) continue; + if (excludes?.Contains(pi.Name) == true) continue; dic[pi.Name] = GetValue(source, pi); } diff --git a/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs b/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs index 8fbdd2bfc..1146cac0a 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs @@ -489,12 +489,12 @@ public static class Reflect /// 是否泛型列表 /// /// - public static Boolean IsList(this Type type) => type != null && type.IsGenericType && type.As(typeof(IList<>)); + public static Boolean IsList(this Type type) => type?.IsGenericType == true && type.As(typeof(IList<>)); /// 是否泛型字典 /// /// - public static Boolean IsDictionary(this Type type) => type != null && type.IsGenericType && type.As(typeof(IDictionary<,>)); + public static Boolean IsDictionary(this Type type) => type?.IsGenericType == true && type.As(typeof(IDictionary<,>)); #endregion #region 插件 diff --git a/src/Admin/ThingsGateway.NewLife.X/Reflection/ScriptEngine.cs b/src/Admin/ThingsGateway.NewLife.X/Reflection/ScriptEngine.cs index dacf9e5bc..43327f604 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Reflection/ScriptEngine.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Reflection/ScriptEngine.cs @@ -305,7 +305,7 @@ public class ScriptEngine if (FinalCode == null) GenerateCode(); var rs = Compile(FinalCode, null); - if (rs.Errors == null || !rs.Errors.HasErrors) + if (rs.Errors?.HasErrors != true) { // 加载外部程序集 foreach (var item in ReferencedAssemblies) diff --git a/src/Admin/ThingsGateway.NewLife.X/Security/Asn1.cs b/src/Admin/ThingsGateway.NewLife.X/Security/Asn1.cs index b3a7f1b96..43f2000cd 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Security/Asn1.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Security/Asn1.cs @@ -55,7 +55,7 @@ public class Asn1 foreach (var item in arr) { var ds = item.GetOids(); - if (ds != null && ds.Length > 0) list.AddRange(ds); + if (ds?.Length > 0) list.AddRange(ds); } } diff --git a/src/Admin/ThingsGateway.NewLife.X/Security/Certificate.cs b/src/Admin/ThingsGateway.NewLife.X/Security/Certificate.cs index 48466b85d..972cb5ccd 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Security/Certificate.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Security/Certificate.cs @@ -7,7 +7,7 @@ namespace ThingsGateway.NewLife.Security { /// 证书 /// http://blogs.msdn.com/b/dcook/archive/2008/11/25/creating-a-self-signed-certificate-in-c.aspx - public class Certificate + public static class Certificate { /// 建立自签名证书 /// @@ -52,7 +52,7 @@ namespace ThingsGateway.NewLife.Security } finally { - if (password != null) password.Dispose(); + password?.Dispose(); } } diff --git a/src/Admin/ThingsGateway.NewLife.X/Security/DSAHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Security/DSAHelper.cs index c15ab8dd8..6b13cc23c 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Security/DSAHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Security/DSAHelper.cs @@ -62,7 +62,7 @@ public static class DSAHelper var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); - if (xmlDoc.DocumentElement == null || !xmlDoc.DocumentElement.Name.Equals("DSAKeyValue")) + if (xmlDoc.DocumentElement?.Name.Equals("DSAKeyValue") != true) { throw new Exception("Invalid XML DSA key."); } diff --git a/src/Admin/ThingsGateway.NewLife.X/Security/RSAHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Security/RSAHelper.cs index 6db742a00..6ab81fd53 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Security/RSAHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Security/RSAHelper.cs @@ -56,7 +56,7 @@ public static class RSAHelper ms.WriteArray(p.Modulus); ms.WriteArray(p.Exponent); - if (p.D != null && p.D.Length > 0) + if (p.D?.Length > 0) { if (p.D == null || p.P == null || p.Q == null || p.DP == null || p.DQ == null || p.InverseQ == null) throw new ArgumentNullException(nameof(p)); diff --git a/src/Admin/ThingsGateway.NewLife.X/Security/SecurityHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Security/SecurityHelper.cs index 986e9d473..cdde89d5f 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Security/SecurityHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Security/SecurityHelper.cs @@ -141,9 +141,9 @@ public static class SecurityHelper { if (data == null || data.Length <= 0) throw new ArgumentNullException(nameof(data)); - if (pass != null && pass.Length > 0) + if (pass?.Length > 0) { - if (sa.LegalKeySizes != null && sa.LegalKeySizes.Length > 0) + if (sa.LegalKeySizes?.Length > 0) sa.Key = Pad(pass, sa.LegalKeySizes[0]); else sa.Key = pass; @@ -206,9 +206,9 @@ public static class SecurityHelper { if (data == null || data.Length <= 0) throw new ArgumentNullException(nameof(data)); - if (pass != null && pass.Length > 0) + if (pass?.Length > 0) { - if (sa.LegalKeySizes != null && sa.LegalKeySizes.Length > 0) + if (sa.LegalKeySizes?.Length > 0) sa.Key = Pad(pass, sa.LegalKeySizes[0]); else sa.Key = pass; diff --git a/src/Admin/ThingsGateway.NewLife.X/Serialization/Binary/Binary.cs b/src/Admin/ThingsGateway.NewLife.X/Serialization/Binary/Binary.cs index e2fac634b..f0d3c5b85 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Serialization/Binary/Binary.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Serialization/Binary/Binary.cs @@ -118,7 +118,7 @@ public class Binary : FormatterBase, IBinary type = value.GetType(); // 一般类型为空是顶级调用 - if (Hosts.Count == 0 && Log != null && Log.Enable) WriteLog("BinaryWrite {0} {1}", type.Name, value); + if (Hosts.Count == 0 && Log?.Enable == true) WriteLog("BinaryWrite {0} {1}", type.Name, value); } // 优先 IAccessor 接口 @@ -236,7 +236,7 @@ public class Binary : FormatterBase, IBinary /// public virtual Boolean TryRead(Type type, ref Object? value) { - if (Hosts.Count == 0 && Log != null && Log.Enable) WriteLog("BinaryRead {0} {1}", type.Name, value); + if (Hosts.Count == 0 && Log?.Enable == true) WriteLog("BinaryRead {0} {1}", type.Name, value); // 优先 IAccessor 接口 if (value is IAccessor acc) diff --git a/src/Admin/ThingsGateway.NewLife.X/Serialization/DataMemberResolver.cs b/src/Admin/ThingsGateway.NewLife.X/Serialization/DataMemberResolver.cs index b39fda228..2ba3adecf 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Serialization/DataMemberResolver.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Serialization/DataMemberResolver.cs @@ -50,7 +50,7 @@ public class DataMemberResolver : DefaultJsonTypeInfoResolver else { var attr = provider.GetCustomAttributes(typeof(DataMemberAttribute), false)?.FirstOrDefault() as DataMemberAttribute; - if (attr != null && !attr.Name.IsNullOrEmpty()) + if (attr?.Name.IsNullOrEmpty() == false) propertyInfo.Name = attr.Name; } } diff --git a/src/Admin/ThingsGateway.NewLife.X/Serialization/SerialHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Serialization/SerialHelper.cs index e07cfee60..ed658f04e 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Serialization/SerialHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Serialization/SerialHelper.cs @@ -22,12 +22,12 @@ public static class SerialHelper if (name.IsNullOrEmpty()) { var att = pi.GetCustomAttribute(); - if (att != null && !att.Name.IsNullOrEmpty()) name = att.Name; + if (att?.Name.IsNullOrEmpty() == false) name = att.Name; } if (name.IsNullOrEmpty()) { var att = pi.GetCustomAttribute(); - if (att != null && !att.ElementName.IsNullOrEmpty()) name = att.ElementName; + if (att?.ElementName.IsNullOrEmpty() == false) name = att.ElementName; } if (name.IsNullOrEmpty()) name = pi.Name; diff --git a/src/Admin/ThingsGateway.NewLife.X/Serialization/Xml/Xml.cs b/src/Admin/ThingsGateway.NewLife.X/Serialization/Xml/Xml.cs index 425b3a217..7de4e54f9 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Serialization/Xml/Xml.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Serialization/Xml/Xml.cs @@ -118,7 +118,7 @@ public class Xml : FormatterBase, IXml CurrentName = name; // 一般类型为空是顶级调用 - if (Hosts.Count == 0 && Log != null && Log.Enable) WriteLog("XmlWrite {0} {1}", name ?? type.Name, value); + if (Hosts.Count == 0 && Log?.Enable == true) WriteLog("XmlWrite {0} {1}", name ?? type.Name, value); // 要先写入根 Depth++; @@ -254,7 +254,7 @@ public class Xml : FormatterBase, IXml // 移动到第一个元素 while (reader.NodeType != XmlNodeType.Element) { if (!reader.Read()) return false; } - if (Hosts.Count == 0 && Log != null && Log.Enable) WriteLog("XmlRead {0} {1}", type.Name, value); + if (Hosts.Count == 0 && Log?.Enable == true) WriteLog("XmlRead {0} {1}", type.Name, value); // 要先写入根 Depth++; diff --git a/src/Admin/ThingsGateway.NewLife.X/Stub/ScriptIgnoreAttribute.cs b/src/Admin/ThingsGateway.NewLife.X/Stub/ScriptIgnoreAttribute.cs index c11c0c627..a97a11135 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Stub/ScriptIgnoreAttribute.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Stub/ScriptIgnoreAttribute.cs @@ -1,5 +1,6 @@ namespace System.Web.Script.Serialization { /// 忽略Json序列化 + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public sealed class ScriptIgnoreAttribute : Attribute { } } \ No newline at end of file diff --git a/src/Admin/ThingsGateway.NewLife.X/Threading/TimerScheduler.cs b/src/Admin/ThingsGateway.NewLife.X/Threading/TimerScheduler.cs index f8772a049..db6ad4c93 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Threading/TimerScheduler.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Threading/TimerScheduler.cs @@ -129,7 +129,7 @@ public class TimerScheduler : ILogFeature if (e != null) { var swh = e.SafeWaitHandle; - if (swh != null && !swh.IsClosed) e.Set(); + if (swh?.IsClosed == false) e.Set(); } } diff --git a/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs b/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs index c26128c00..2022648c7 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs @@ -36,7 +36,7 @@ public class TimerX : ITimer, IDisposable /// 获取/设置 用户数据 public Object? State { - get => _state != null && _state.IsAlive ? _state.Target : null; + get => _state?.IsAlive == true ? _state.Target : null; set { if (_state == null) @@ -105,7 +105,7 @@ public class TimerX : ITimer, IDisposable _nextTick = Runtime.TickCount64; //_baseTime = DateTime.Now.AddMilliseconds(-_nextTick); - Scheduler = (scheduler == null || scheduler.IsNullOrEmpty()) ? TimerScheduler.Default : TimerScheduler.Create(scheduler); + Scheduler = (scheduler?.IsNullOrEmpty() != false) ? TimerScheduler.Default : TimerScheduler.Create(scheduler); //Scheduler.Add(this); _baseTime = Scheduler.GetNow().AddMilliseconds(-_nextTick); @@ -384,7 +384,7 @@ public class TimerX : ITimer, IDisposable public Boolean Change(TimeSpan dueTime, TimeSpan period) { if (Absolutely) return false; - if (Crons != null && Crons.Length > 0) return false; + if (Crons?.Length > 0) return false; if (period.TotalMilliseconds <= 0) { diff --git a/src/Admin/ThingsGateway.NewLife.X/Web/Link.cs b/src/Admin/ThingsGateway.NewLife.X/Web/Link.cs index 9e03eb8c2..49d18eb6c 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Web/Link.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Web/Link.cs @@ -48,7 +48,7 @@ public class Link public static Link[] Parse(String html, String? baseUrl = null, Func? filter = null) { // baseurl必须是/结尾 - if (baseUrl != null && !baseUrl.EndsWith('/')) baseUrl += "/"; + if (baseUrl?.EndsWith('/') == false) baseUrl += "/"; if (baseUrl.StartsWithIgnoreCase("ftp://")) return ParseFTP(html, baseUrl, filter); // 分析所有链接 @@ -218,7 +218,7 @@ public class Link if (Time.Year < 2000) { var fi = file.AsFile(); - if (fi != null && fi.Exists) Time = fi.LastWriteTime; + if (fi?.Exists == true) Time = fi.LastWriteTime; } return this; diff --git a/src/Admin/ThingsGateway.NewLife.X/Xml/SerializableDictionary.cs b/src/Admin/ThingsGateway.NewLife.X/Xml/SerializableDictionary.cs index 5eff3de35..0417d22e8 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Xml/SerializableDictionary.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Xml/SerializableDictionary.cs @@ -11,11 +11,8 @@ namespace ThingsGateway.NewLife.Xml [Serializable] public class SerializableDictionary : Dictionary, IXmlSerializable { - /// public SerializableDictionary() : base() { } - /// - /// public SerializableDictionary(IDictionary dictionary) : base(dictionary) { } #region IXmlSerializable 成员 diff --git a/src/Admin/ThingsGateway.NewLife.X/Xml/XmlConfig.cs b/src/Admin/ThingsGateway.NewLife.X/Xml/XmlConfig.cs index 15533693a..ca7e9de1c 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Xml/XmlConfig.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Xml/XmlConfig.cs @@ -113,7 +113,7 @@ public class XmlConfig : DisposeBase where TConfig : XmlConfig { // 获取XmlConfigFileAttribute特性,那里会指定配置文件名称 var att = typeof(TConfig).GetCustomAttribute(true); - if (att == null || att.FileName.IsNullOrWhiteSpace()) + if (att?.FileName.IsNullOrWhiteSpace() != false) { // 这里不能着急,派生类可能通过静态构造函数指定配置文件路径 //throw new XException("编码错误!请为配置类{0}设置{1}特性,指定配置文件!", typeof(TConfig), typeof(XmlConfigFileAttribute).Name); diff --git a/src/Admin/ThingsGateway.NewLife.X/Xml/XmlHelper.cs b/src/Admin/ThingsGateway.NewLife.X/Xml/XmlHelper.cs index 8e6fa6ac4..a45b66d1c 100644 --- a/src/Admin/ThingsGateway.NewLife.X/Xml/XmlHelper.cs +++ b/src/Admin/ThingsGateway.NewLife.X/Xml/XmlHelper.cs @@ -278,7 +278,7 @@ public static class XmlHelper var dic = new Dictionary(); - if (root.ChildNodes != null && root.ChildNodes.Count > 0) + if (root.ChildNodes?.Count > 0) { foreach (var item in root.ChildNodes) { @@ -311,7 +311,7 @@ public static class XmlHelper var root = doc.CreateElement(rootName); doc.AppendChild(root); - if (dic != null && dic.Count > 0) + if (dic?.Count > 0) { foreach (var item in dic) { diff --git a/src/Admin/ThingsGateway.Razor/Common/RandomHelper.cs b/src/Admin/ThingsGateway.Razor/Common/RandomHelper.cs index fb2dd3fba..52575c0c7 100644 --- a/src/Admin/ThingsGateway.Razor/Common/RandomHelper.cs +++ b/src/Admin/ThingsGateway.Razor/Common/RandomHelper.cs @@ -17,7 +17,7 @@ using System.Text; /// 随机数 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class RandomHelper +public static class RandomHelper { /// /// 生成随机纯字母随机数 diff --git a/src/Admin/ThingsGateway.Razor/Const/WebsiteConst.cs b/src/Admin/ThingsGateway.Razor/Const/WebsiteConst.cs index 19de9687c..50327aeb2 100644 --- a/src/Admin/ThingsGateway.Razor/Const/WebsiteConst.cs +++ b/src/Admin/ThingsGateway.Razor/Const/WebsiteConst.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Razor; /// 网站常量 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class WebsiteConst +public static class WebsiteConst { /// /// 默认的资源项目名称 diff --git a/src/Admin/ThingsGateway.Razor/Extensions/ObjectExtensions.cs b/src/Admin/ThingsGateway.Razor/Extensions/ObjectExtensions.cs index feb6ecee2..7199bda53 100644 --- a/src/Admin/ThingsGateway.Razor/Extensions/ObjectExtensions.cs +++ b/src/Admin/ThingsGateway.Razor/Extensions/ObjectExtensions.cs @@ -8,9 +8,6 @@ // QQ群:605534569 //------------------------------------------------------------------------------ -// 版权归百小僧及百签科技(广东)有限公司所有。 - - using System.Collections.Concurrent; using System.ComponentModel; using System.Reflection; @@ -282,7 +279,7 @@ public static class ObjectExtensions foreach (var property in propertys) { var p = oldType.GetProperty(property.Name); - if (property.CanWrite && p != null && p.CanRead) + if (property.CanWrite && p?.CanRead == true) { property.SetValue(o, ChangeType(p.GetValue(obj, null), property.PropertyType), null); } @@ -494,7 +491,7 @@ public static class ObjectExtensions /// 实例,true 表示空集合,false 表示非空集合 internal static bool IsEmpty(this IEnumerable collection) { - return collection == null || !collection.Any(); + return collection?.Any() != true; } /// diff --git a/src/Admin/ThingsGateway.Razor/Util/LocalizerUtil.cs b/src/Admin/ThingsGateway.Razor/Util/LocalizerUtil.cs index d4ff30c15..09c04b875 100644 --- a/src/Admin/ThingsGateway.Razor/Util/LocalizerUtil.cs +++ b/src/Admin/ThingsGateway.Razor/Util/LocalizerUtil.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Razor; /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class LocalizerUtil +public static class LocalizerUtil { #region 是否启用 diff --git a/src/Admin/ThingsGateway.SqlSugar/.txt b/src/Admin/ThingsGateway.SqlSugar/.txt new file mode 100644 index 000000000..cf33ff233 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/.txt @@ -0,0 +1,3 @@ +https://gitee.com/dotnetchina/SqlSugar/commit/98ed5e8a756bae6c245838df5ab4e19bf900d0af + +修改大部分CA规则,后期优化减少字符串操作 \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/QuestDb/CsvHelperEnumToIntConverter.cs b/src/Admin/ThingsGateway.SqlSugar/QuestDb/CsvHelperEnumToIntConverter.cs new file mode 100644 index 000000000..9d8f559c8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/QuestDb/CsvHelperEnumToIntConverter.cs @@ -0,0 +1,31 @@ +using CsvHelper; +using CsvHelper.Configuration; +using CsvHelper.TypeConversion; + +namespace SqlSugar +{ + public class CsvHelperEnumToIntConverter : ITypeConverter + { + public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData) + { + if (value == null) + { + return "null"; + } + else if (value is Enum enumValue) + { + return (Convert.ToInt32(enumValue)).ToString(); + } + throw new NotSupportedException(); + } + + public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData) + { + if (int.TryParse(text, out int intValue)) + { + return text; + } + throw new NotSupportedException(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbPageSizeBulkCopy.cs b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbPageSizeBulkCopy.cs new file mode 100644 index 000000000..ef379c279 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbPageSizeBulkCopy.cs @@ -0,0 +1,33 @@ +namespace SqlSugar +{ + public class QuestDbPageSizeBulkCopy + { + private QuestDbRestAPI questDbRestAPI; + private int pageSize; + private ISqlSugarClient db; + public QuestDbPageSizeBulkCopy(QuestDbRestAPI questDbRestAPI, int pageSize, ISqlSugarClient db) + { + this.questDbRestAPI = questDbRestAPI; + this.pageSize = pageSize; + this.db = db; + } + public int BulkCopy(List insertDatas, string dateFormat = "yyyy/M/d H:mm:ss") where T : class, new() + { + int result = 0; + db.Utilities.PageEach(insertDatas, pageSize, pageItems => + { + result += questDbRestAPI.BulkCopyAsync(pageItems, dateFormat).GetAwaiter().GetResult(); + }); + return result; + } + public async Task BulkCopyAsync(List insertDatas, string dateFormat = "yyyy/M/d H:mm:ss") where T : class, new() + { + int result = 0; + await db.Utilities.PageEachAsync(insertDatas, pageSize, async pageItems => + { + result += await questDbRestAPI.BulkCopyAsync(pageItems, dateFormat).ConfigureAwait(false); + }).ConfigureAwait(false); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbRestAPHelper.cs b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbRestAPHelper.cs new file mode 100644 index 000000000..7268b8826 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbRestAPHelper.cs @@ -0,0 +1,56 @@ +using System.Data.Common; +using System.Text; + +namespace SqlSugar +{ + internal static class QuestDbRestAPHelper + { + + /// + /// 绑定RestAPI需要的信息 + /// + /// + /// + /// + /// + public static void SetRestApiInfo(DbConnectionStringBuilder builder, ref string host, ref string username, ref string password) + { + if (builder.TryGetValue("Host", out object hostValue)) + { + host = Convert.ToString(hostValue); + } + if (builder.TryGetValue("Username", out object usernameValue)) + { + username = Convert.ToString(usernameValue); + } + if (builder.TryGetValue("Password", out object passwordValue)) + { + password = Convert.ToString(passwordValue); + } + } + + /// + /// 逐行读取,包含空行 + /// + /// + /// + public static List SplitByLine(string text) + { + List lines = new List(); + byte[] array = Encoding.UTF8.GetBytes(text); + using (MemoryStream stream = new MemoryStream(array)) + { + using (var sr = new StreamReader(stream)) + { + string line = sr.ReadLine(); + while (line != null) + { + lines.Add(line); + line = sr.ReadLine(); + } + } + } + return lines; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbRestAPI.cs b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbRestAPI.cs new file mode 100644 index 000000000..c01e994c3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbRestAPI.cs @@ -0,0 +1,240 @@ +using CsvHelper; +using CsvHelper.Configuration; +using CsvHelper.TypeConversion; + +using Newtonsoft.Json; + +using System.Collections; +using System.Data.Common; +using System.Globalization; +using System.Net.Http.Headers; +using System.Text; +using System.Web; +namespace SqlSugar +{ + /// + /// QuestDb RestAPI + /// + public class QuestDbRestAPI + { + internal string url = string.Empty; + internal string authorization = string.Empty; + internal static Random random = new Random(); + //can be modified + ISqlSugarClient db; + public QuestDbRestAPI(ISqlSugarClient db) + { + + var builder = new DbConnectionStringBuilder(); + builder.ConnectionString = db.CurrentConnectionConfig.ConnectionString; + this.db = db; + string host = String.Empty; + string username = String.Empty; + string password = String.Empty; + QuestDbRestAPHelper.SetRestApiInfo(builder, ref host, ref username, ref password); + BindHost(host, username, password); + } + /// + /// 执行SQL异步 + /// + /// + /// + public async Task ExecuteCommandAsync(string sql) + { + //HTTP GET 执行SQL + var result = string.Empty; + var url = $"{this.url}/exec?query={HttpUtility.UrlEncode(sql)}"; + if (!string.IsNullOrWhiteSpace(authorization)) + client.DefaultRequestHeaders.Add("Authorization", authorization); + var httpResponseMessage = await client.GetAsync(url).ConfigureAwait(false); + result = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); + return result; + } + /// + /// 执行SQL + /// + /// + /// + public string ExecuteCommand(string sql) + { + return ExecuteCommandAsync(sql).GetAwaiter().GetResult(); + } + + public async Task BulkCopyAsync(T insertData, string dateFormat = "yyyy/M/d H:mm:ss") where T : class, new() + { + if (db.CurrentConnectionConfig.MoreSettings == null) + db.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings(); + db.CurrentConnectionConfig.MoreSettings.DisableNvarchar = true; + var sql = db.Insertable(insertData).ToSqlString(); + var result = await ExecuteCommandAsync(sql).ConfigureAwait(false); + return result.Contains("OK", StringComparison.OrdinalIgnoreCase) ? 1 : 0; + } + + public int BulkCopy(T insertData, string dateFormat = "yyyy/M/d H:mm:ss") where T : class, new() + { + return BulkCopyAsync(insertData, dateFormat).GetAwaiter().GetResult(); + } + + public QuestDbPageSizeBulkCopy PageSize(int pageSize) + { + QuestDbPageSizeBulkCopy result = new QuestDbPageSizeBulkCopy(this, pageSize, db); + return result; + } + private static readonly HttpClient client = new HttpClient(); + /// + /// 批量快速插入异步 + /// + /// + /// + /// 导入时,时间格式 默认:yyyy/M/d H:mm:ss + /// + public async Task BulkCopyAsync(List insertList, string dateFormat = "yyyy/M/d H:mm:ss") where T : class, new() + { + var result = 0; + var fileName = $"{Guid.NewGuid()}.csv"; + var filePath = Path.Combine(AppContext.BaseDirectory, fileName); + try + { + var boundary = "---------------" + DateTime.Now.Ticks.ToString("x"); + var list = new List(); + var name = db.EntityMaintenance.GetEntityInfo().DbTableName; + + var key = "QuestDbBulkCopy" + typeof(T).FullName + typeof(T).GetHashCode(); + var columns = new ReflectionInoCacheService().GetOrCreate(key, () => + db.CopyNew().DbMaintenance.GetColumnInfosByTableName(name)); + columns.ForEach(d => + { + if (d.DataType == "TIMESTAMP") + { + list.Add(new Hashtable() + { + { "name", d.DbColumnName }, + { "type", d.DataType }, + { "pattern", dateFormat} + }); + } + else + { + list.Add(new Hashtable() + { + { "name", d.DbColumnName }, + { "type", d.DataType } + }); + } + }); + var schema = JsonConvert.SerializeObject(list); + //写入CSV文件 + using (var writer = new StreamWriter(filePath)) + using (var csv = new CsvWriter(writer, CultureInfo.CurrentCulture)) + { + var options = new TypeConverterOptions { Formats = new[] { GetDefaultFormat() } }; + csv.Context.TypeConverterOptionsCache.AddOptions(options); + CsvCreating(csv); + await csv.WriteRecordsAsync(insertList).ConfigureAwait(false); + } + + using var httpContent = new MultipartFormDataContent(boundary); + using var fileStream = File.OpenRead(filePath); + if (!string.IsNullOrWhiteSpace(this.authorization)) + client.DefaultRequestHeaders.Add("Authorization", this.authorization); + httpContent.Add(new StringContent(schema), "schema"); + var streamContent = new StreamContent(fileStream); + streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); + httpContent.Add(streamContent, "data", Path.GetFileName(filePath)); + + //boundary带双引号 可能导致服务器错误情况 + httpContent.Headers.Remove("Content-Type"); + httpContent.Headers.TryAddWithoutValidation("Content-Type", + "multipart/form-data; boundary=" + boundary); + var httpResponseMessage = + await Post(client, name, httpContent).ConfigureAwait(false); + var readAsStringAsync = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); + var splitByLine = QuestDbRestAPHelper.SplitByLine(readAsStringAsync); + foreach (var s in splitByLine) + { + if (s.Contains("Rows")) + { + var strings = s.Split('|'); + if (strings[1].Trim() == "Rows imported") + { + result = Convert.ToInt32(strings[2].Trim()); + } + } + } + } + catch (Exception) + { + throw; + } + finally + { + try + { + File.Delete(filePath); + } + catch + { + // ignored + } + } + return result; + } + + private void CsvCreating(CsvWriter csv) where T : class, new() + { + var entityColumns = db.EntityMaintenance.GetEntityInfo().Columns; + if (entityColumns.Any(it => it.IsIgnore || it.UnderType?.IsEnum == true)) + { + var customMap = new DefaultClassMap(); + foreach (var item in entityColumns.Where(it => !it.IsIgnore)) + { + var memberMap = customMap.Map(typeof(T), item.PropertyInfo).Name(item.PropertyName); + if (item.UnderType?.IsEnum == true + && item.SqlParameterDbType == null + && db.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true) + { + memberMap.TypeConverter(); + } + } + csv.Context.RegisterClassMap(customMap); + } + } + + private static string GetDefaultFormat() + { + return "yyyy-MM-ddTHH:mm:ss.fffffff"; + } + + private Task Post(HttpClient client, string name, MultipartFormDataContent httpContent) + { + return client.PostAsync($"{this.url}/imp?name={name}", httpContent); + } + + /// + /// 批量快速插入 + /// + /// + /// + /// 导入时,时间格式 默认:yyyy/M/d H:mm:ss + /// + public int BulkCopy(List insertList, string dateFormat = "yyyy/M/d H:mm:ss") where T : class, new() + { + return BulkCopyAsync(insertList, dateFormat).GetAwaiter().GetResult(); + } + private void BindHost(string host, string username, string password) + { + url = host; + if (url.EndsWith('/')) + url = url.Remove(url.Length - 1); + + if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + url = $"http://{url}"; + //生成TOKEN + if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password)) + { + var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); + authorization = $"Basic {base64}"; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbSqlSugarClientExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbSqlSugarClientExtensions.cs new file mode 100644 index 000000000..2bb67b9e3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/QuestDb/QuestDbSqlSugarClientExtensions.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public static class QuestDbSqlSugarClientExtensions + { + public static QuestDbRestAPI RestApi(this ISqlSugarClient db) + { + return new QuestDbRestAPI(db); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AdoProvider/AdoAccessory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AdoProvider/AdoAccessory.cs new file mode 100644 index 000000000..dfa038b54 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AdoProvider/AdoAccessory.cs @@ -0,0 +1,82 @@ +using System.Data; +using System.Reflection; +namespace SqlSugar +{ + public partial class AdoAccessory + { + protected IDbBind _DbBind; + protected IDbFirst _DbFirst; + protected ICodeFirst _CodeFirst; + protected IDbMaintenance _DbMaintenance; + protected IDbConnection _DbConnection; + + protected virtual SugarParameter[] GetParameters(object parameters, PropertyInfo[] propertyInfo, string sqlParameterKeyWord) + { + List result = new List(); + if (parameters != null) + { + var entityType = parameters.GetType(); + var isDictionary = entityType.IsIn(UtilConstants.DicArraySO, UtilConstants.DicArraySS); + if (isDictionary) + DictionaryToParameters(parameters, sqlParameterKeyWord, result, entityType); + else if (parameters is List) + { + result = (parameters as List); + } + else if (parameters is SugarParameter[]) + { + result = (parameters as SugarParameter[]).ToList(); + } + else + { + Check.Exception(!entityType.IsAnonymousType(), "The parameter format is wrong. \nUse new{{xx=xx, xx2=xx2}} or \nDictionary or \nSugarParameter [] "); + ProperyToParameter(parameters, propertyInfo, sqlParameterKeyWord, result, entityType); + } + } + return result.ToArray(); + } + protected void ProperyToParameter(object parameters, PropertyInfo[] propertyInfo, string sqlParameterKeyWord, List listParams, Type entityType) + { + PropertyInfo[] properties = null; + if (propertyInfo != null) + properties = propertyInfo; + else + properties = entityType.GetProperties(); + + foreach (PropertyInfo properyty in properties) + { + var value = properyty.GetValue(parameters, null); + if (properyty.PropertyType.IsEnum()) + value = Convert.ToInt64(value); + if (value?.Equals(DateTime.MinValue) != false) value = DBNull.Value; + if (properyty.Name.Contains("hierarchyid", StringComparison.CurrentCultureIgnoreCase)) + { + var parameter = new SugarParameter(sqlParameterKeyWord + properyty.Name, SqlDbType.Udt); + parameter.UdtTypeName = "HIERARCHYID"; + parameter.Value = value; + listParams.Add(parameter); + } + else + { + var parameter = new SugarParameter(sqlParameterKeyWord + properyty.Name, value); + listParams.Add(parameter); + } + } + } + protected void DictionaryToParameters(object parameters, string sqlParameterKeyWord, List listParams, Type entityType) + { + if (entityType == UtilConstants.DicArraySO) + { + var dictionaryParameters = (Dictionary)parameters; + var sugarParameters = dictionaryParameters.Select(it => new SugarParameter(sqlParameterKeyWord + it.Key, it.Value)); + listParams.AddRange(sugarParameters); + } + else + { + var dictionaryParameters = (Dictionary)parameters; + var sugarParameters = dictionaryParameters.Select(it => new SugarParameter(sqlParameterKeyWord + it.Key, it.Value)); + listParams.AddRange(sugarParameters); ; + } + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AdoProvider/AdoProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AdoProvider/AdoProvider.cs new file mode 100644 index 000000000..6cd59311d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AdoProvider/AdoProvider.cs @@ -0,0 +1,1836 @@ +using System.Collections; +using System.Data; +using System.Data.Common; +using System.Reflection; +using System.Text.RegularExpressions; +namespace SqlSugar +{ + /// + /// ** description:ActiveX Data Objects + /// ** author:sunkaixuan + /// ** date:2017/1/2 + /// ** email:610262374@qq.com + /// + public abstract partial class AdoProvider : AdoAccessory, IAdo + { + #region Constructor + public AdoProvider() + { + this.IsEnableLogEvent = false; + this.CommandType = CommandType.Text; + this.IsClearParameters = true; + this.CommandTimeOut = 300; + } + #endregion + + #region Properties + public virtual bool IsNoSql { get; set; } + internal bool IsOpenAsync { get; set; } + protected List OutputParameters { get; set; } + public virtual string SqlParameterKeyWord { get { return "@"; } } + public IDbTransaction Transaction { get; set; } + public virtual SqlSugarProvider Context { get; set; } + internal CommandType OldCommandType { get; set; } + internal bool OldClearParameters { get; set; } + public IDataParameterCollection DataReaderParameters { get; set; } + public TimeSpan SqlExecutionTime { get { return AfterTime - BeforeTime; } } + public TimeSpan ConnectionExecutionTime { get { return CheckConnectionAfterTime - CheckConnectionBeforeTime; } } + public TimeSpan GetDataExecutionTime { get { return GetDataAfterTime - GetDataBeforeTime; } } + /// + /// Add, delete and modify: the number of affected items; + /// + public int SqlExecuteCount { get; protected set; } = 0; + public SugarActionType SqlExecuteType { get => this.Context.SugarActionType; } + public StackTraceInfo SqlStackTrace { get { return UtilMethods.GetStackTrace(); } } + public bool IsDisableMasterSlaveSeparation { get; set; } + internal DateTime BeforeTime = DateTime.MinValue; + internal DateTime AfterTime = DateTime.MinValue; + internal DateTime GetDataBeforeTime = DateTime.MinValue; + internal DateTime GetDataAfterTime = DateTime.MinValue; + internal DateTime CheckConnectionBeforeTime = DateTime.MinValue; + internal DateTime CheckConnectionAfterTime = DateTime.MinValue; + public virtual IDbBind DbBind + { + get + { + if (base._DbBind == null) + { + IDbBind bind = InstanceFactory.GetDbBind(this.Context.CurrentConnectionConfig); + base._DbBind = bind; + bind.Context = this.Context; + } + return base._DbBind; + } + } + public virtual int CommandTimeOut { get; set; } + public virtual CommandType CommandType { get; set; } + public virtual bool IsEnableLogEvent { get; set; } + public virtual bool IsClearParameters { get; set; } + public virtual Action LogEventStarting => this.Context.CurrentConnectionConfig.AopEvents?.OnLogExecuting; + public virtual Action LogEventCompleted => this.Context.CurrentConnectionConfig.AopEvents?.OnLogExecuted; + public virtual Action CheckConnectionExecuting => this.Context.CurrentConnectionConfig.AopEvents?.CheckConnectionExecuting; + public virtual Action CheckConnectionExecuted => this.Context.CurrentConnectionConfig.AopEvents?.CheckConnectionExecuted; + public virtual Action OnGetDataReadering => this.Context.CurrentConnectionConfig.AopEvents?.OnGetDataReadering; + public virtual Action OnGetDataReadered => this.Context.CurrentConnectionConfig.AopEvents?.OnGetDataReadered; + public virtual Func> ProcessingEventStartingSQL => this.Context.CurrentConnectionConfig.AopEvents?.OnExecutingChangeSql; + protected virtual Func FormatSql { get; set; } + public virtual Action ErrorEvent => this.Context.CurrentConnectionConfig.AopEvents?.OnError; + public virtual Action DiffLogEvent => this.Context.CurrentConnectionConfig.AopEvents?.OnDiffLogEvent; + public virtual List SlaveConnections { get; set; } + public virtual IDbConnection MasterConnection { get; set; } + public virtual string MasterConnectionString { get; set; } + public virtual CancellationToken? CancellationToken { get; set; } + #endregion + + #region Connection + public virtual bool IsValidConnection() + { + try + { + if (this.IsAnyTran()) + { + return true; + } + using (OpenAlways()) + { + return true; + } + } + catch (Exception) + { + return false; + } + } + public virtual bool IsValidConnectionNoClose() + { + try + { + this.Open(); + return true; + } + catch (Exception) + { + return false; + } + } + public virtual void Open() + { + CheckConnection(); + } + public virtual async Task OpenAsync() + { + await CheckConnectionAsync().ConfigureAwait(false); + } + public SugarConnection OpenAlways() + { + SugarConnection result = new SugarConnection(); + result.IsAutoClose = this.Context.CurrentConnectionConfig.IsAutoCloseConnection; + result.conn = this.Connection; + result.Context = this.Context; + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false; + this.Open(); + return result; + } + public virtual void Close() + { + if (this.Transaction != null) + { + this.Transaction = null; + } + if (this.Connection != null && this.Connection.State == ConnectionState.Open) + { + this.Connection.Close(); + } + if (this.IsMasterSlaveSeparation && this.SlaveConnections.HasValue()) + { + foreach (var slaveConnection in this.SlaveConnections) + { + if (slaveConnection != null && slaveConnection.State == ConnectionState.Open) + { + slaveConnection.Close(); + } + } + } + } + public virtual void Dispose() + { + if (this.Transaction != null) + { + this.Transaction.Rollback(); + this.Transaction = null; + } + //if (this.Connection != null && this.Connection.State != ConnectionState.Open) + //{ + // this.Connection.Close(); + //} + this.Connection?.Dispose(); + this.Connection = null; + + if (this.IsMasterSlaveSeparation) + { + if (this.SlaveConnections != null) + { + foreach (var slaveConnection in this.SlaveConnections) + { + if (slaveConnection != null && slaveConnection.State == ConnectionState.Open) + { + slaveConnection.Dispose(); + } + } + } + } + } + public virtual void CheckConnection() + { + this.CheckConnectionBefore(this.Connection); + if (this.Connection.State != ConnectionState.Open) + { + try + { + this.Connection.Open(); + } + catch (Exception ex) + { + if (this.Context.CurrentConnectionConfig?.DbType == DbType.SqlServer && ex.Message?.Contains("provider: SSL") == true) + { + Check.ExceptionEasy(true, ex.Message, "SSL出错,因为升级了驱动,字符串增加Encrypt=True;TrustServerCertificate=True;即可。详细错误:" + ex.Message); + } + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message + $"DbType=\"{this.Context.CurrentConnectionConfig.DbType}\";ConfigId=\"{this.Context.CurrentConnectionConfig.ConfigId}\""); + } + } + this.CheckConnectionAfter(this.Connection); + } + + public virtual async Task CheckConnectionAsync() + { + this.CheckConnectionBefore(this.Connection); + if (this.Connection.State != ConnectionState.Open) + { + try + { + await (Connection as DbConnection).OpenAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message + $"DbType=\"{this.Context.CurrentConnectionConfig.DbType}\";ConfigId=\"{this.Context.CurrentConnectionConfig.ConfigId}\""); + } + } + this.CheckConnectionAfter(this.Connection); + } + public virtual void CheckConnectionBefore(IDbConnection Connection) + { + this.CheckConnectionBeforeTime = DateTime.Now; + if (this.IsEnableLogEvent) + { + Action action = CheckConnectionExecuting; + if (action != null) + { + action(Connection); + } + } + } + public virtual void CheckConnectionAfter(IDbConnection Connection) + { + this.CheckConnectionAfterTime = DateTime.Now; + if (this.IsEnableLogEvent) + { + Action action = CheckConnectionExecuted; + if (action != null) + { + action(Connection, this.ConnectionExecutionTime); + } + } + } + #endregion + + #region Transaction + public virtual bool IsAnyTran() + { + return this.Transaction != null; + } + public virtual bool IsNoTran() + { + return this.Transaction == null; + } + public virtual void BeginTran() + { + CheckConnection(); + if (this.Transaction == null) + this.Transaction = this.Connection.BeginTransaction(); + } + public virtual async Task BeginTranAsync() + { + await CheckConnectionAsync().ConfigureAwait(false); + if (this.Transaction == null) + this.Transaction = await (Connection as DbConnection).BeginTransactionAsync().ConfigureAwait(false); + } + public virtual void BeginTran(IsolationLevel iso) + { + CheckConnection(); + if (this.Transaction == null) + this.Transaction = this.Connection.BeginTransaction(iso); + } + public virtual async Task BeginTranAsync(IsolationLevel iso) + { + await CheckConnectionAsync().ConfigureAwait(false); + if (this.Transaction == null) + this.Transaction = await (Connection as DbConnection).BeginTransactionAsync(iso).ConfigureAwait(false); + } + public virtual void RollbackTran() + { + if (this.Transaction != null) + { + this.Transaction.Rollback(); + this.Transaction = null; + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) this.Close(); + } + } + + public virtual async Task RollbackTranAsync() + { + if (this.Transaction != null) + { + await (Transaction as DbTransaction).RollbackAsync().ConfigureAwait(false); + this.Transaction = null; + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) await CloseAsync().ConfigureAwait(false); + } + } + public virtual void CommitTran() + { + if (this.Transaction != null) + { + this.Transaction.Commit(); + this.Transaction = null; + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) this.Close(); + } + } + public virtual async Task CommitTranAsync() + { + if (this.Transaction != null) + { + await (Transaction as DbTransaction).CommitAsync().ConfigureAwait(false); + this.Transaction = null; + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) await CloseAsync().ConfigureAwait(false); + } + } + #endregion + + #region abstract + public abstract IDataParameter[] ToIDbDataParameter(params SugarParameter[] pars); + public abstract void SetCommandToAdapter(IDataAdapter adapter, DbCommand command); + public abstract IDataAdapter GetAdapter(); + public abstract DbCommand GetCommand(string sql, SugarParameter[] pars); + public abstract IDbConnection Connection { get; set; } + public abstract void BeginTran(string transactionName);//Only SqlServer + public abstract void BeginTran(IsolationLevel iso, string transactionName);//Only SqlServer + #endregion + + #region Use + public SqlSugarTransactionAdo UseTran() + { + return new SqlSugarTransactionAdo(this.Context); + } + public DbResult UseTran(Action action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + this.BeginTran(); + if (action != null) + action(); + this.CommitTran(); + result.Data = result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + this.RollbackTran(); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public async Task> UseTranAsync(Func action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + await BeginTranAsync().ConfigureAwait(false); + if (action != null) + await action().ConfigureAwait(false); + await CommitTranAsync().ConfigureAwait(false); + result.Data = result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + await RollbackTranAsync().ConfigureAwait(false); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public DbResult UseTran(Func action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + this.BeginTran(); + if (action != null) + result.Data = action(); + this.CommitTran(); + result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + this.RollbackTran(); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public async Task> UseTranAsync(Func> action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + this.BeginTran(); + if (action != null) + result.Data = await action().ConfigureAwait(false); + this.CommitTran(); + result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + this.RollbackTran(); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public IAdo UseStoredProcedure() + { + this.OldCommandType = this.CommandType; + this.OldClearParameters = this.IsClearParameters; + this.CommandType = CommandType.StoredProcedure; + this.IsClearParameters = false; + return this; + } + #endregion + + #region Core + public virtual int ExecuteCommandWithGo(string sql, params SugarParameter[] parameters) + { + if (string.IsNullOrEmpty(sql)) + return 0; + if (!sql.Contains("go", StringComparison.CurrentCultureIgnoreCase)) + { + return ExecuteCommand(sql); + } + System.Collections.ArrayList al = new System.Collections.ArrayList(); + System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"^(\s*)go(\s*)$", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.ExplicitCapture); + al.AddRange(reg.Split(sql)); + int count = 0; + foreach (string item in al) + { + if (item.HasValue()) + { + count += ExecuteCommand(item, parameters); + } + } + return count; + } + public virtual int ExecuteCommand(string sql, params SugarParameter[] parameters) + { + try + { + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return this.Context.CurrentConnectionConfig.SqlMiddle.ExecuteCommand(sql, parameters); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + IDbCommand sqlCommand = GetCommand(sql, parameters); + int count = sqlCommand.ExecuteNonQuery(); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + // 影响条数 + this.SqlExecuteCount = count; + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return count; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) this.Close(); + SetConnectionEnd(sql); + } + } + public virtual IDataReader GetDataReader(string sql, params SugarParameter[] parameters) + { + try + { + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return this.Context.CurrentConnectionConfig.SqlMiddle.GetDataReader(sql, parameters); + SetConnectionStart(sql); + var isSp = this.CommandType == CommandType.StoredProcedure; + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + IDbCommand sqlCommand = GetCommand(sql, parameters); + IDataReader sqlDataReader = sqlCommand.ExecuteReader(this.IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default); + if (isSp) + DataReaderParameters = sqlCommand.Parameters; + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + SetConnectionEnd(sql); + if (SugarCompatible.IsFramework || this.Context.CurrentConnectionConfig.DbType != DbType.Sqlite) + sqlCommand.Dispose(); + return sqlDataReader; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + } + public virtual DataSet GetDataSetAll(string sql, params SugarParameter[] parameters) + { + try + { + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return this.Context.CurrentConnectionConfig.SqlMiddle.GetDataSetAll(sql, parameters); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + IDataAdapter dataAdapter = this.GetAdapter(); + DbCommand sqlCommand = GetCommand(sql, parameters); + this.SetCommandToAdapter(dataAdapter, sqlCommand); + DataSet ds = new DataSet(); + dataAdapter.Fill(ds); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return ds; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) this.Close(); + SetConnectionEnd(sql); + } + } + public virtual object GetScalar(string sql, params SugarParameter[] parameters) + { + try + { + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return this.Context.CurrentConnectionConfig.SqlMiddle.GetScalar(sql, parameters); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + IDbCommand sqlCommand = GetCommand(sql, parameters); + object scalar = sqlCommand.ExecuteScalar(); + //scalar = (scalar == null ? 0 : scalar); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return scalar; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) this.Close(); + SetConnectionEnd(sql); + } + } + + public virtual async Task ExecuteCommandAsync(string sql, params SugarParameter[] parameters) + { + try + { + Async(); + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return await Context.CurrentConnectionConfig.SqlMiddle.ExecuteCommandAsync(sql, parameters).ConfigureAwait(false); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + var sqlCommand = IsOpenAsync ? await GetCommandAsync(sql, parameters).ConfigureAwait(false) : GetCommand(sql, parameters); + int count; + if (this.CancellationToken == null) + count = await sqlCommand.ExecuteNonQueryAsync().ConfigureAwait(false); + else + count = await sqlCommand.ExecuteNonQueryAsync(CancellationToken.Value).ConfigureAwait(false); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + this.SqlExecuteCount = count; + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return count; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) this.Close(); + SetConnectionEnd(sql); + } + } + public virtual async Task GetDataReaderAsync(string sql, params SugarParameter[] parameters) + { + try + { + Async(); + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return await Context.CurrentConnectionConfig.SqlMiddle.GetDataReaderAsync(sql, parameters).ConfigureAwait(false); + SetConnectionStart(sql); + var isSp = this.CommandType == CommandType.StoredProcedure; + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + var sqlCommand = IsOpenAsync ? await GetCommandAsync(sql, parameters).ConfigureAwait(false) : GetCommand(sql, parameters); + DbDataReader sqlDataReader; + if (this.CancellationToken == null) + sqlDataReader = await sqlCommand.ExecuteReaderAsync(IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default).ConfigureAwait(false); + else + sqlDataReader = await sqlCommand.ExecuteReaderAsync(IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default, CancellationToken.Value).ConfigureAwait(false); + if (isSp) + DataReaderParameters = sqlCommand.Parameters; + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + SetConnectionEnd(sql); + if (SugarCompatible.IsFramework || this.Context.CurrentConnectionConfig.DbType != DbType.Sqlite) + sqlCommand.Dispose(); + return sqlDataReader; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + } + public virtual async Task GetScalarAsync(string sql, params SugarParameter[] parameters) + { + try + { + Async(); + InitParameters(ref sql, parameters); + if (IsFormat(parameters)) + sql = FormatSql(sql); + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return await Context.CurrentConnectionConfig.SqlMiddle.GetScalarAsync(sql, parameters).ConfigureAwait(false); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + var sqlCommand = IsOpenAsync ? await GetCommandAsync(sql, parameters).ConfigureAwait(false) : GetCommand(sql, parameters); + object scalar; + if (CancellationToken == null) + scalar = await sqlCommand.ExecuteScalarAsync().ConfigureAwait(false); + else + scalar = await sqlCommand.ExecuteScalarAsync(CancellationToken.Value).ConfigureAwait(false); + //scalar = (scalar == null ? 0 : scalar); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return scalar; + } + catch (Exception ex) + { + SugarCatch(ex, sql, parameters); + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) this.Close(); + SetConnectionEnd(sql); + } + } + public virtual Task GetDataSetAllAsync(string sql, params SugarParameter[] parameters) + { + Async(); + + //False asynchrony . No Support DataSet + if (CancellationToken == null) + { + return Task.Run(() => + { + return GetDataSetAll(sql, parameters); + }); + } + else + { + return Task.Run(() => + { + return GetDataSetAll(sql, parameters); + }, this.CancellationToken.Value); + } + } + #endregion + + #region Methods + + public virtual string GetString(string sql, object parameters) + { + return GetString(sql, this.GetParameters(parameters)); + } + public virtual string GetString(string sql, params SugarParameter[] parameters) + { + return Convert.ToString(GetScalar(sql, parameters)); + } + public virtual string GetString(string sql, List parameters) + { + if (parameters == null) + { + return GetString(sql); + } + else + { + return GetString(sql, parameters.ToArray()); + } + } + + + public virtual Task GetStringAsync(string sql, object parameters) + { + return GetStringAsync(sql, this.GetParameters(parameters)); + } + public virtual async Task GetStringAsync(string sql, params SugarParameter[] parameters) + { + return Convert.ToString(await GetScalarAsync(sql, parameters).ConfigureAwait(false)); + } + public virtual Task GetStringAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetStringAsync(sql); + } + else + { + return GetStringAsync(sql, parameters.ToArray()); + } + } + + + + public virtual long GetLong(string sql, object parameters = null) + { + return Convert.ToInt64(GetScalar(sql, GetParameters(parameters))); + } + public virtual async Task GetLongAsync(string sql, object parameters = null) + { + return Convert.ToInt64(await GetScalarAsync(sql, GetParameters(parameters)).ConfigureAwait(false)); + } + + + public virtual int GetInt(string sql, object parameters) + { + return GetInt(sql, this.GetParameters(parameters)); + } + public virtual int GetInt(string sql, List parameters) + { + if (parameters == null) + { + return GetInt(sql); + } + else + { + return GetInt(sql, parameters.ToArray()); + } + } + public virtual int GetInt(string sql, params SugarParameter[] parameters) + { + return GetScalar(sql, parameters).ObjToInt(); + } + + public virtual Task GetIntAsync(string sql, object parameters) + { + return GetIntAsync(sql, this.GetParameters(parameters)); + } + public virtual Task GetIntAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetIntAsync(sql); + } + else + { + return GetIntAsync(sql, parameters.ToArray()); + } + } + public virtual async Task GetIntAsync(string sql, params SugarParameter[] parameters) + { + var list = await GetScalarAsync(sql, parameters).ConfigureAwait(false); + return list.ObjToInt(); + } + + public virtual Double GetDouble(string sql, object parameters) + { + return GetDouble(sql, this.GetParameters(parameters)); + } + public virtual Double GetDouble(string sql, params SugarParameter[] parameters) + { + return GetScalar(sql, parameters).ObjToMoney(); + } + public virtual Double GetDouble(string sql, List parameters) + { + if (parameters == null) + { + return GetDouble(sql); + } + else + { + return GetDouble(sql, parameters.ToArray()); + } + } + + public virtual Task GetDoubleAsync(string sql, object parameters) + { + return GetDoubleAsync(sql, this.GetParameters(parameters)); + } + public virtual async Task GetDoubleAsync(string sql, params SugarParameter[] parameters) + { + var result = await GetScalarAsync(sql, parameters).ConfigureAwait(false); + return result.ObjToMoney(); + } + public virtual Task GetDoubleAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetDoubleAsync(sql); + } + else + { + return GetDoubleAsync(sql, parameters.ToArray()); + } + } + + + public virtual decimal GetDecimal(string sql, object parameters) + { + return GetDecimal(sql, this.GetParameters(parameters)); + } + public virtual decimal GetDecimal(string sql, params SugarParameter[] parameters) + { + return GetScalar(sql, parameters).ObjToDecimal(); + } + public virtual decimal GetDecimal(string sql, List parameters) + { + if (parameters == null) + { + return GetDecimal(sql); + } + else + { + return GetDecimal(sql, parameters.ToArray()); + } + } + + + public virtual Task GetDecimalAsync(string sql, object parameters) + { + return GetDecimalAsync(sql, this.GetParameters(parameters)); + } + public virtual async Task GetDecimalAsync(string sql, params SugarParameter[] parameters) + { + var result = await GetScalarAsync(sql, parameters).ConfigureAwait(false); + return result.ObjToDecimal(); + } + public virtual Task GetDecimalAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetDecimalAsync(sql); + } + else + { + return GetDecimalAsync(sql, parameters.ToArray()); + } + } + + + + public virtual DateTime GetDateTime(string sql, object parameters) + { + return GetDateTime(sql, this.GetParameters(parameters)); + } + public virtual DateTime GetDateTime(string sql, params SugarParameter[] parameters) + { + return GetScalar(sql, parameters).ObjToDate(); + } + public virtual DateTime GetDateTime(string sql, List parameters) + { + if (parameters == null) + { + return GetDateTime(sql); + } + else + { + return GetDateTime(sql, parameters.ToArray()); + } + } + + + + + public virtual Task GetDateTimeAsync(string sql, object parameters) + { + return GetDateTimeAsync(sql, this.GetParameters(parameters)); + } + public virtual async Task GetDateTimeAsync(string sql, params SugarParameter[] parameters) + { + var list = await GetScalarAsync(sql, parameters).ConfigureAwait(false); + return list.ObjToDate(); + } + public virtual Task GetDateTimeAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetDateTimeAsync(sql); + } + else + { + return GetDateTimeAsync(sql, parameters.ToArray()); + } + } + + + public virtual List SqlQuery(string sql, object parameters = null) + { + var sugarParameters = this.GetParameters(parameters); + return SqlQuery(sql, sugarParameters); + } + public virtual List SqlQuery(string sql, params SugarParameter[] parameters) + { + var result = SqlQuery(sql, parameters); + return result.Item1; + } + public List MasterSqlQuery(string sql, object parameters = null) + { + var oldValue = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var result = this.Context.Ado.SqlQuery(sql, parameters); + this.Context.Ado.IsDisableMasterSlaveSeparation = oldValue; + return result; + } + public async Task> MasterSqlQueryAasync(string sql, object parameters = null) + { + var oldValue = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var result = await Context.Ado.SqlQueryAsync(sql, parameters).ConfigureAwait(false); + this.Context.Ado.IsDisableMasterSlaveSeparation = oldValue; + return result; + } + public virtual List SqlQuery(string sql, List parameters) + { + if (parameters != null) + { + return SqlQuery(sql, parameters.ToArray()); + } + else + { + return SqlQuery(sql); + } + } + public Tuple, List> SqlQuery(string sql, object parameters = null) + { + var result = SqlQuery(sql, parameters); + return new Tuple, List>(result.Item1, result.Item2); + } + public Tuple, List, List> SqlQuery(string sql, object parameters = null) + { + var result = SqlQuery(sql, parameters); + return new Tuple, List, List>(result.Item1, result.Item2, result.Item3); + } + public Tuple, List, List, List> SqlQuery(string sql, object parameters = null) + { + var result = SqlQuery(sql, parameters); + return new Tuple, List, List, List>(result.Item1, result.Item2, result.Item3, result.Item4); + } + public Tuple, List, List, List, List> SqlQuery(string sql, object parameters = null) + { + var result = SqlQuery(sql, parameters); + return new Tuple, List, List, List, List>(result.Item1, result.Item2, result.Item3, result.Item4, result.Item5); + } + public Tuple, List, List, List, List, List> SqlQuery(string sql, object parameters = null) + { + var result = SqlQuery(sql, parameters); + return new Tuple, List, List, List, List, List>(result.Item1, result.Item2, result.Item3, result.Item4, result.Item5, result.Item6); + } + public Tuple, List, List, List, List, List, List> SqlQuery(string sql, object parameters = null) + { + var parsmeterArray = this.GetParameters(parameters); + this.Context.InitMappingInfo(); + var builder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + builder.SqlQueryBuilder.sql.Append(sql); + if (parsmeterArray != null && parsmeterArray.Length != 0) + builder.SqlQueryBuilder.Parameters.AddRange(parsmeterArray); + string sqlString = builder.SqlQueryBuilder.ToSqlString(); + SugarParameter[] Parameters = builder.SqlQueryBuilder.Parameters.ToArray(); + this.GetDataBefore(sqlString, Parameters); + using (var dataReader = this.GetDataReader(sqlString, Parameters)) + { + DbDataReader DbReader = (DbDataReader)dataReader; + List result = new List(); + if (DbReader.HasRows) + { + result = GetData(typeof(T), dataReader); + } + else + { + dataReader.Read(); + } + List result2 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result2 = GetData(typeof(T2), dataReader); + } + List result3 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result3 = GetData(typeof(T3), dataReader); + } + List result4 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result4 = GetData(typeof(T4), dataReader); + } + List result5 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result5 = GetData(typeof(T5), dataReader); + } + List result6 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result6 = GetData(typeof(T6), dataReader); + } + List result7 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result7 = GetData(typeof(T7), dataReader); + } + builder.SqlQueryBuilder.Clear(); + if (this.Context.Ado.DataReaderParameters != null) + { + foreach (IDataParameter item in this.Context.Ado.DataReaderParameters) + { + var parameter = parsmeterArray.FirstOrDefault(it => item.ParameterName.Substring(1) == it.ParameterName.Substring(1)); + if (parameter != null) + { + parameter.Value = item.Value; + } + } + this.Context.Ado.DataReaderParameters = null; + } + this.GetDataAfter(sqlString, Parameters); + return Tuple.Create, List, List, List, List, List, List>(result, result2, result3, result4, result5, result6, result7); + } + } + + public Task> SqlQueryAsync(string sql, object parameters, CancellationToken token) + { + this.CancellationToken = token; + return SqlQueryAsync(sql, parameters); + } + + public virtual Task> SqlQueryAsync(string sql, object parameters = null) + { + var sugarParameters = this.GetParameters(parameters); + return SqlQueryAsync(sql, sugarParameters); + } + public virtual async Task> SqlQueryAsync(string sql, params SugarParameter[] parameters) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return result.Item1; + } + public virtual Task> SqlQueryAsync(string sql, List parameters) + { + if (parameters != null) + { + return SqlQueryAsync(sql, parameters.ToArray()); + } + else + { + return SqlQueryAsync(sql); + } + } + public async Task, List>> SqlQueryAsync(string sql, object parameters = null) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return new Tuple, List>(result.Item1, result.Item2); + } + public async Task, List, List>> SqlQueryAsync(string sql, object parameters = null) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return new Tuple, List, List>(result.Item1, result.Item2, result.Item3); + } + public async Task, List, List, List>> SqlQueryAsync(string sql, object parameters = null) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return new Tuple, List, List, List>(result.Item1, result.Item2, result.Item3, result.Item4); + } + public async Task, List, List, List, List>> SqlQueryAsync(string sql, object parameters = null) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return new Tuple, List, List, List, List>(result.Item1, result.Item2, result.Item3, result.Item4, result.Item5); + } + public async Task, List, List, List, List, List>> SqlQueryAsync(string sql, object parameters = null) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return new Tuple, List, List, List, List, List>(result.Item1, result.Item2, result.Item3, result.Item4, result.Item5, result.Item6); + } + public async Task, List, List, List, List, List, List>> SqlQueryAsync(string sql, object parameters = null) + { + var parsmeterArray = this.GetParameters(parameters); + this.Context.InitMappingInfo(); + var builder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + builder.SqlQueryBuilder.sql.Append(sql); + if (parsmeterArray != null && parsmeterArray.Length != 0) + builder.SqlQueryBuilder.Parameters.AddRange(parsmeterArray); + string sqlString = builder.SqlQueryBuilder.ToSqlString(); + SugarParameter[] Parameters = builder.SqlQueryBuilder.Parameters.ToArray(); + this.GetDataBefore(sqlString, Parameters); + using (var dataReader = await GetDataReaderAsync(sqlString, Parameters).ConfigureAwait(false)) + { + DbDataReader DbReader = (DbDataReader)dataReader; + List result = new List(); + if (DbReader.HasRows) + { + result = await GetDataAsync(typeof(T), dataReader).ConfigureAwait(false); + } + List result2 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result2 = await GetDataAsync(typeof(T2), dataReader).ConfigureAwait(false); + } + List result3 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result3 = await GetDataAsync(typeof(T3), dataReader).ConfigureAwait(false); + } + List result4 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result4 = await GetDataAsync(typeof(T4), dataReader).ConfigureAwait(false); + } + List result5 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result5 = await GetDataAsync(typeof(T5), dataReader).ConfigureAwait(false); + } + List result6 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result6 = await GetDataAsync(typeof(T6), dataReader).ConfigureAwait(false); + } + List result7 = null; + if (NextResult(dataReader)) + { + this.Context.InitMappingInfo(); + result7 = await GetDataAsync(typeof(T7), dataReader).ConfigureAwait(false); + } + builder.SqlQueryBuilder.Clear(); + if (this.Context.Ado.DataReaderParameters != null) + { + foreach (IDataParameter item in this.Context.Ado.DataReaderParameters) + { + var parameter = parsmeterArray.FirstOrDefault(it => item.ParameterName.Substring(1) == it.ParameterName.Substring(1)); + if (parameter != null) + { + parameter.Value = item.Value; + } + } + this.Context.Ado.DataReaderParameters = null; + } + this.GetDataAfter(sqlString, Parameters); + return Tuple.Create, List, List, List, List, List, List>(result, result2, result3, result4, result5, result6, result7); + } + } + + public virtual T SqlQuerySingle(string sql, object parameters = null) + { + var result = SqlQuery(sql, parameters); + return result == null ? default(T) : result.FirstOrDefault(); + } + public virtual T SqlQuerySingle(string sql, params SugarParameter[] parameters) + { + var result = SqlQuery(sql, parameters); + return result == null ? default(T) : result.FirstOrDefault(); + } + public virtual T SqlQuerySingle(string sql, List parameters) + { + var result = SqlQuery(sql, parameters); + return result == null ? default(T) : result.FirstOrDefault(); + } + + + public virtual async Task SqlQuerySingleAsync(string sql, object parameters = null) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return result == null ? default(T) : result.FirstOrDefault(); + } + public virtual async Task SqlQuerySingleAsync(string sql, params SugarParameter[] parameters) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return result == null ? default(T) : result.FirstOrDefault(); + } + public virtual async Task SqlQuerySingleAsync(string sql, List parameters) + { + var result = await SqlQueryAsync(sql, parameters).ConfigureAwait(false); + return result == null ? default(T) : result.FirstOrDefault(); + } + + + + public virtual DataTable GetDataTable(string sql, params SugarParameter[] parameters) + { + var ds = GetDataSetAll(sql, parameters); + if (ds.Tables.Count != 0 && ds.Tables.Count > 0) return ds.Tables[0]; + return new DataTable(); + } + public virtual DataTable GetDataTable(string sql, object parameters) + { + return GetDataTable(sql, this.GetParameters(parameters)); + } + public virtual DataTable GetDataTable(string sql, List parameters) + { + if (parameters == null) + { + return GetDataTable(sql); + } + else + { + return GetDataTable(sql, parameters.ToArray()); + } + } + + + public virtual async Task GetDataTableAsync(string sql, params SugarParameter[] parameters) + { + var ds = await GetDataSetAllAsync(sql, parameters).ConfigureAwait(false); + if (ds.Tables.Count != 0 && ds.Tables.Count > 0) return ds.Tables[0]; + return new DataTable(); + } + public virtual Task GetDataTableAsync(string sql, object parameters) + { + return GetDataTableAsync(sql, this.GetParameters(parameters)); + } + public virtual Task GetDataTableAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetDataTableAsync(sql); + } + else + { + return GetDataTableAsync(sql, parameters.ToArray()); + } + } + + + public virtual DataSet GetDataSetAll(string sql, object parameters) + { + return GetDataSetAll(sql, this.GetParameters(parameters)); + } + public virtual DataSet GetDataSetAll(string sql, List parameters) + { + if (parameters == null) + { + return GetDataSetAll(sql); + } + else + { + return GetDataSetAll(sql, parameters.ToArray()); + } + } + + public virtual Task GetDataSetAllAsync(string sql, object parameters) + { + return GetDataSetAllAsync(sql, this.GetParameters(parameters)); + } + public virtual Task GetDataSetAllAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetDataSetAllAsync(sql); + } + else + { + return GetDataSetAllAsync(sql, parameters.ToArray()); + } + } + + + + + public virtual IDataReader GetDataReader(string sql, object parameters) + { + return GetDataReader(sql, this.GetParameters(parameters)); + } + public virtual IDataReader GetDataReader(string sql, List parameters) + { + if (parameters == null) + { + return GetDataReader(sql); + } + else + { + return GetDataReader(sql, parameters.ToArray()); + } + } + public virtual Task GetDataReaderAsync(string sql, object parameters) + { + return GetDataReaderAsync(sql, this.GetParameters(parameters)); + } + public virtual Task GetDataReaderAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetDataReaderAsync(sql); + } + else + { + return GetDataReaderAsync(sql, parameters.ToArray()); + } + } + public virtual object GetScalar(string sql, object parameters) + { + return GetScalar(sql, this.GetParameters(parameters)); + } + public virtual object GetScalar(string sql, List parameters) + { + if (parameters == null) + { + return GetScalar(sql); + } + else + { + return GetScalar(sql, parameters.ToArray()); + } + } + public virtual Task GetScalarAsync(string sql, object parameters) + { + return GetScalarAsync(sql, this.GetParameters(parameters)); + } + public virtual Task GetScalarAsync(string sql, List parameters) + { + if (parameters == null) + { + return GetScalarAsync(sql); + } + else + { + return GetScalarAsync(sql, parameters.ToArray()); + } + } + public virtual int ExecuteCommand(string sql, object parameters) + { + return ExecuteCommand(sql, GetParameters(parameters)); + } + public virtual int ExecuteCommand(string sql, List parameters) + { + if (parameters == null) + { + return ExecuteCommand(sql); + } + else + { + return ExecuteCommand(sql, parameters.ToArray()); + } + } + public Task ExecuteCommandAsync(string sql, object parameters, CancellationToken cancellationToken) + { + this.CancellationToken = CancellationToken; + return ExecuteCommandAsync(sql, parameters); + } + public virtual Task ExecuteCommandAsync(string sql, object parameters) + { + return ExecuteCommandAsync(sql, GetParameters(parameters)); + } + public virtual Task ExecuteCommandAsync(string sql, List parameters) + { + if (parameters == null) + { + return ExecuteCommandAsync(sql); + } + else + { + return ExecuteCommandAsync(sql, parameters.ToArray()); + } + } + #endregion + + #region Helper + public virtual async Task GetCommandAsync(string sql, SugarParameter[] parameters) + { + await Task.FromResult(0).ConfigureAwait(false); + throw new NotImplementedException(); + } + public async Task CloseAsync() + { + if (this.Transaction != null) + { + this.Transaction = null; + } + if (this.Connection != null && this.Connection.State == ConnectionState.Open) + { + await (Connection as DbConnection).CloseAsync().ConfigureAwait(false); + } + if (this.IsMasterSlaveSeparation && this.SlaveConnections.HasValue()) + { + foreach (var slaveConnection in this.SlaveConnections) + { + if (slaveConnection != null && slaveConnection.State == ConnectionState.Open) + { + await (slaveConnection as DbConnection).CloseAsync().ConfigureAwait(false); + } + } + } + } + + protected virtual void SugarCatch(Exception ex, string sql, SugarParameter[] parameters) + { + if (sql?.Contains("{year}{month}{day}") == true) + { + Check.ExceptionEasy("need .SplitTable() message:" + ex.Message, "当前代码是否缺少 .SplitTable() ,可以看文档 [分表] , 详细错误:" + ex.Message); + } + } + public virtual void RemoveCancellationToken() + { + this.CancellationToken = null; + } + protected void Async() + { + if (this.Context.Root != null && this.Context.Root.AsyncId == null) + { + this.Context.Root.AsyncId = Guid.NewGuid(); ; + } + } + private static bool NextResult(IDataReader dataReader) + { + try + { + return dataReader.NextResult(); + } + catch + { + return false; + } + } + + protected void ExecuteProcessingSQL(ref string sql, ref SugarParameter[] parameters) + { + var result = this.ProcessingEventStartingSQL(sql, parameters); + sql = result.Key; + parameters = result.Value; + } + public virtual void ExecuteBefore(string sql, SugarParameter[] parameters) + { + //if (this.Context.CurrentConnectionConfig.Debugger != null && this.Context.CurrentConnectionConfig.Debugger.EnableThreadSecurityValidation == true) + //{ + + // var contextId = this.Context.ContextID.ToString(); + // var processId = Thread.CurrentThread.ManagedThreadId.ToString(); + // var cache = new ReflectionInoCacheService(); + // if (!cache.ContainsKey(contextId)) + // { + // cache.Add(contextId, processId); + // } + // else + // { + // var cacheValue = cache.Get(contextId); + // if (processId != cacheValue) + // { + // throw new SqlSugarException(this.Context, ErrorMessage.GetThrowMessage("Detection of SqlSugarClient cross-threading usage,a thread needs a new one", "检测到声名的SqlSugarClient跨线程使用,请检查是否静态、是否单例、或者IOC配置错误引起的,保证一个线程new出一个对象 ,具本Sql:") + sql, parameters); + // } + // } + //} + this.BeforeTime = DateTime.Now; + if (this.IsEnableLogEvent) + { + Action action = LogEventStarting; + if (action != null) + { + if (parameters == null || parameters.Length == 0) + { + action(sql, Array.Empty()); + } + else + { + action(sql, parameters); + } + } + } + } + public virtual void ExecuteAfter(string sql, SugarParameter[] parameters) + { + this.AfterTime = DateTime.Now; + var hasParameter = parameters.HasValue(); + if (hasParameter) + { + foreach (var outputParameter in parameters.Where(it => it.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue))) + { + var gobalOutputParamter = this.OutputParameters.FirstOrDefault(it => it.ParameterName == outputParameter.ParameterName); + if (gobalOutputParamter == null) + {//Oracle bug + gobalOutputParamter = this.OutputParameters.FirstOrDefault(it => it.ParameterName == outputParameter.ParameterName.TrimStart(outputParameter.ParameterName.First())); + } + outputParameter.Value = gobalOutputParamter.Value; + this.OutputParameters.Remove(gobalOutputParamter); + } + } + if (this.IsEnableLogEvent) + { + Action action = LogEventCompleted; + if (action != null) + { + if (parameters == null || parameters.Length == 0) + { + action(sql, Array.Empty()); + } + else + { + action(sql, parameters); + } + } + } + if (this.OldCommandType != 0) + { + this.CommandType = this.OldCommandType; + this.IsClearParameters = this.OldClearParameters; + this.OldCommandType = 0; + this.OldClearParameters = false; + } + } + public virtual void GetDataBefore(string sql, SugarParameter[] parameters) + { + this.GetDataBeforeTime = DateTime.Now; + if (this.IsEnableLogEvent) + { + Action action = OnGetDataReadering; + if (action != null) + { + if (parameters == null || parameters.Length == 0) + { + action(sql, Array.Empty()); + } + else + { + action(sql, parameters); + } + } + } + } + public virtual void GetDataAfter(string sql, SugarParameter[] parameters) + { + this.GetDataAfterTime = DateTime.Now; + if (this.IsEnableLogEvent) + { + Action action = OnGetDataReadered; + if (action != null) + { + if (parameters == null || parameters.Length == 0) + { + action(sql, Array.Empty(), GetDataExecutionTime); + } + else + { + action(sql, parameters, GetDataExecutionTime); + } + } + } + } + public virtual SugarParameter[] GetParameters(object parameters, PropertyInfo[] propertyInfo = null) + { + if (parameters == null) return null; + return base.GetParameters(parameters, propertyInfo, this.SqlParameterKeyWord); + } + protected bool IsAutoClose() + { + return this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null; + } + protected bool IsMasterSlaveSeparation + { + get + { + return this.Context.CurrentConnectionConfig.SlaveConnectionConfigs.HasValue() && this.IsDisableMasterSlaveSeparation == false; + } + } + protected void SetConnectionStart(string sql) + { + if (this.Transaction == null && this.IsMasterSlaveSeparation && IsRead(sql)) + { + if (this.MasterConnection == null) + { + this.MasterConnection = this.Connection; + this.MasterConnectionString = this.MasterConnection.ConnectionString; + } + var saves = this.Context.CurrentConnectionConfig.SlaveConnectionConfigs.Where(it => it.HitRate > 0).ToList(); + var currentIndex = UtilRandom.GetRandomIndex(saves.ToDictionary(it => saves.IndexOf(it), it => it.HitRate)); + var currentSaveConnection = saves[currentIndex]; + this.Connection = null; + this.Context.CurrentConnectionConfig.ConnectionString = currentSaveConnection.ConnectionString; + this.Connection = this.Connection; + if (this.SlaveConnections.IsNullOrEmpty() || !this.SlaveConnections.Any(it => EqualsConnectionString(it.ConnectionString, this.Connection.ConnectionString))) + { + if (this.SlaveConnections == null) this.SlaveConnections = new List(); + this.SlaveConnections.Add(this.Connection); + } + } + else if (this.Transaction == null && this.IsMasterSlaveSeparation && this.MasterConnection == null) + { + this.MasterConnection = this.Connection; + this.MasterConnectionString = this.MasterConnection.ConnectionString; + } + } + + private bool EqualsConnectionString(string connectionString1, string connectionString2) + { + var connectionString1Array = connectionString1.Split(';'); + var connectionString2Array = connectionString2.Split(';'); + var result = connectionString1Array.Except(connectionString2Array); + return !result.Any(); + } + private bool IsFormat(SugarParameter[] parameters) + { + return FormatSql != null && parameters?.Length > 0; + } + + protected void SetConnectionEnd(string sql) + { + if (this.IsMasterSlaveSeparation && IsRead(sql) && this.Transaction == null) + { + this.Connection = this.MasterConnection; + this.Context.CurrentConnectionConfig.ConnectionString = this.MasterConnectionString; + } + this.Context.SugarActionType = SugarActionType.UnKnown; + } + + private bool IsRead(string sql) + { + var sqlLower = sql.ToLower(); + var result = Regex.IsMatch(sqlLower, "[ ]*select[ ]") && !Regex.IsMatch(sqlLower, "[ ]*insert[ ]|[ ]*update[ ]|[ ]*delete[ ]"); + return result; + } + + protected void ExecuteErrorEvent(string sql, SugarParameter[] parameters, Exception ex) + { + this.AfterTime = DateTime.Now; + ErrorEvent(new SqlSugarException(this.Context, ex, sql, parameters)); + } + protected void InitParameters(ref string sql, SugarParameter[] parameters) + { + this.SqlExecuteCount = 0; + this.BeforeTime = DateTime.MinValue; + this.AfterTime = DateTime.MinValue; + if (parameters.HasValue()) + { + foreach (var item in parameters) + { + if (item.Value != null) + { + var type = item.Value.GetType(); + if ((type != UtilConstants.ByteArrayType && type.IsArray && item.IsArray == false) || type.FullName.IsCollectionsList() || type.IsIterator()) + { + var newValues = new List(); + foreach (var inValute in item.Value as IEnumerable) + { + newValues.Add(inValute.ObjToString()); + } + if (newValues.IsNullOrEmpty()) + { + newValues.Add("-1"); + } + if (item.ParameterName.Substring(0, 1) == ":") + { + sql = sql.Replace(string.Concat("@", item.ParameterName.AsSpan(1)), newValues.ToArray().ToJoinSqlInVals()); + } + if (item.ParameterName.Substring(0, 1) != this.SqlParameterKeyWord && sql.ObjToString().Contains(this.SqlParameterKeyWord + item.ParameterName)) + { + sql = sql.Replace(this.SqlParameterKeyWord + item.ParameterName, newValues.ToArray().ToJoinSqlInVals()); + } + else if (item.Value != null && UtilMethods.IsNumberArray(item.Value.GetType())) + { + if (newValues.Any(it => string.IsNullOrEmpty(it))) + { + newValues.RemoveAll(r => string.IsNullOrEmpty(r)); + newValues.Add("null"); + } + sql = sql.Replace(item.ParameterName, string.Join(",", newValues)); + } + else + { + sql = sql.Replace(item.ParameterName, newValues.ToArray().ToJoinSqlInVals()); + } + item.Value = DBNull.Value; + } + } + if (item.ParameterName?.Contains(' ') == true) + { + var oldName = item.ParameterName; + item.ParameterName = item.ParameterName.Replace(" ", ""); + sql = sql.Replace(oldName, item.ParameterName); + } + } + } + } + + + + private List GetData(Type entityType, IDataReader dataReader) + { + List result; + if (entityType == UtilConstants.DynamicType) + { + result = this.Context.Utilities.DataReaderToExpandoObjectListNoUsing(dataReader) as List; + } + else if (entityType == UtilConstants.ObjType) + { + result = this.Context.Utilities.DataReaderToExpandoObjectListNoUsing(dataReader).Select(it => ((TResult)(object)it)).ToList(); + } + else if (entityType.IsAnonymousType() || StaticConfig.EnableAot) + { + if (StaticConfig.EnableAot && entityType == UtilConstants.StringType) + { + result = this.Context.Ado.DbBind.DataReaderToListNoUsing(entityType, dataReader); + } + else + { + result = this.Context.Utilities.DataReaderToListNoUsing(dataReader); + } + } + else + { + result = this.Context.Ado.DbBind.DataReaderToListNoUsing(entityType, dataReader); + } + return result; + } + private async Task> GetDataAsync(Type entityType, IDataReader dataReader) + { + List result; + if (entityType == UtilConstants.DynamicType) + { + result = await Context.Utilities.DataReaderToExpandoObjectListAsyncNoUsing(dataReader).ConfigureAwait(false) as List; + } + else if (entityType == UtilConstants.ObjType) + { + var list = await Context.Utilities.DataReaderToExpandoObjectListAsyncNoUsing(dataReader).ConfigureAwait(false); + result = list.Select(it => ((TResult)(object)it)).ToList(); + } + else if (entityType.IsAnonymousType() || StaticConfig.EnableAot) + { + if (StaticConfig.EnableAot && entityType == UtilConstants.StringType) + { + result = await Context.Ado.DbBind.DataReaderToListNoUsingAsync(entityType, dataReader).ConfigureAwait(false); + } + else + { + result = await Context.Utilities.DataReaderToListAsyncNoUsing(dataReader).ConfigureAwait(false); + } + } + else + { + result = await Context.Ado.DbBind.DataReaderToListNoUsingAsync(entityType, dataReader).ConfigureAwait(false); + } + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AopProvider/AopProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AopProvider/AopProvider.cs new file mode 100644 index 000000000..358026d4b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/AopProvider/AopProvider.cs @@ -0,0 +1,27 @@ +using System.Data; + +namespace SqlSugar +{ + public class AopProvider + { + private AopProvider() { } + public AopProvider(SqlSugarProvider context) + { + this.Context = context; + this.Context.Ado.IsEnableLogEvent = true; + } + private SqlSugarProvider Context { get; set; } + public Action OnDiffLogEvent { set { this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent = value; } } + public Action OnError { set { this.Context.CurrentConnectionConfig.AopEvents.OnError = value; } } + public Action OnLogExecuting { set { this.Context.CurrentConnectionConfig.AopEvents.OnLogExecuting = value; } } + public Action OnLogExecuted { set { this.Context.CurrentConnectionConfig.AopEvents.OnLogExecuted = value; } } + public Func> OnExecutingChangeSql { set { this.Context.CurrentConnectionConfig.AopEvents.OnExecutingChangeSql = value; } } + public virtual Action DataExecuting { set { this.Context.CurrentConnectionConfig.AopEvents.DataExecuting = value; } } + public Action DataChangesExecuted { set { this.Context.CurrentConnectionConfig.AopEvents.DataChangesExecuted = value; } } + public virtual Action DataExecuted { set { this.Context.CurrentConnectionConfig.AopEvents.DataExecuted = value; } } + public Action CheckConnectionExecuting { set { this.Context.CurrentConnectionConfig.AopEvents.CheckConnectionExecuting = value; } } + public Action CheckConnectionExecuted { set { this.Context.CurrentConnectionConfig.AopEvents.CheckConnectionExecuted = value; } } + public Action OnGetDataReadering { set { this.Context.CurrentConnectionConfig.AopEvents.OnGetDataReadering = value; } } + public Action OnGetDataReadered { set { this.Context.CurrentConnectionConfig.AopEvents.OnGetDataReadered = value; } } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CacheProvider/CacheProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CacheProvider/CacheProvider.cs new file mode 100644 index 000000000..0613ab0e6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CacheProvider/CacheProvider.cs @@ -0,0 +1,37 @@ +namespace SqlSugar +{ + public class SugarCacheProvider + { + public ICacheService Servie { get; set; } + + public void RemoveDataCache(string likeString) + { + if (Servie == null) return; + CacheSchemeMain.RemoveCacheByLike(Servie, likeString); + } + + public List GetAllKey() + { + if (Servie == null) return new List(); + return Servie.GetAllKey()?.ToList(); + } + + public void Add(string key, object value) + { + if (Servie == null) return; + Servie.Add(key, value, 60 * 60 * 24 * 100); + } + + public void Add(string key, object value, int seconds) + { + if (Servie == null) return; + Servie.Add(key, value, seconds); + } + + public T Get(string key) + { + if (Servie == null) return default(T); + return Servie.Get(key); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs new file mode 100644 index 000000000..2b6ec138d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs @@ -0,0 +1,758 @@ +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class CodeFirstProvider : ICodeFirst + { + #region Properties + internal static object LockObject = new object(); + public virtual SqlSugarProvider Context { get; set; } + protected bool IsBackupTable { get; set; } + protected int MaxBackupDataRows { get; set; } + protected virtual int DefultLength { get; set; } + protected Dictionary MappingTables = new Dictionary(); + public CodeFirstProvider() + { + if (DefultLength == 0) + { + DefultLength = 255; + } + } + #endregion + + #region Public methods + public SplitCodeFirstProvider SplitTables() + { + var result = new SplitCodeFirstProvider(); + result.Context = this.Context; + result.DefaultLength = this.DefultLength; + return result; + } + + public virtual ICodeFirst BackupTable(int maxBackupDataRows = int.MaxValue) + { + this.IsBackupTable = true; + this.MaxBackupDataRows = maxBackupDataRows; + return this; + } + + public virtual ICodeFirst SetStringDefaultLength(int length) + { + DefultLength = length; + return this; + } + public void InitTablesWithAttr(params Type[] entityTypes) + { + foreach (var item in entityTypes) + { + var attr = item.GetCustomAttribute(); + if (attr == null || this.Context?.Root == null) + { + this.Context.CodeFirst.InitTables(item); + } + else + { + var newDb = this.Context.Root.GetConnectionWithAttr(item); + newDb.CodeFirst.InitTables(item); + } + } + } + public virtual void InitTables(Type entityType) + { + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute != null) + { + var mappingInfo = this.Context.MappingTables.FirstOrDefault(it => it.EntityName == entityType.Name); + if (mappingInfo == null) + { + UtilMethods.StartCustomSplitTable(this.Context, entityType); + this.Context.CodeFirst.SplitTables().InitTables(entityType); + this.Context.MappingTables.RemoveAll(it => it.EntityName == entityType.Name); + UtilMethods.EndCustomSplitTable(this.Context, entityType); + return; + } + } + //Prevent concurrent requests if used in your program + lock (CodeFirstProvider.LockObject) + { + MappingTableList oldTableList = CopyMappingTalbe(); + //this.Context.Utilities.RemoveCacheAll(); + var entityInfo = this.Context.GetEntityNoCacheInitMappingInfo(entityType); + if (!this.Context.DbMaintenance.IsAnySystemTablePermissions()) + { + Check.Exception(true, "Dbfirst and Codefirst requires system table permissions"); + } + + if (this.Context.Ado.Transaction == null) + { + var executeResult = Context.Ado.UseTran(() => + { + Execute(entityType, entityInfo); + }); + Check.Exception(!executeResult.IsSuccess, executeResult.ErrorMessage); + } + else + { + Execute(entityType, entityInfo); + } + + RestMappingTables(oldTableList); + } + + } + + public void InitTables() + { + InitTables(typeof(T)); + } + public void InitTables() + { + InitTables(typeof(T), typeof(T2)); + } + public void InitTables() + { + InitTables(typeof(T), typeof(T2), typeof(T3)); + } + public void InitTables() + { + InitTables(typeof(T), typeof(T2), typeof(T3), typeof(T4)); + } + public void InitTables() + { + InitTables(typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5)); + } + public virtual void InitTables(params Type[] entityTypes) + { + if (entityTypes.HasValue()) + { + foreach (var item in entityTypes) + { + try + { + InitTables(item); + } + catch (Exception ex) + { + + throw new Exception(item.Name + " 创建失败,请认真检查 1、属性需要get set 2、特殊类型需要加Ignore 具体错误内容: " + ex.Message); + } + } + } + } + public ICodeFirst As(Type type, string newTableName) + { + if (!MappingTables.TryAdd(type, newTableName)) + { + MappingTables[type] = newTableName; + } + return this; + } + public ICodeFirst As(string newTableName) + { + return As(typeof(T), newTableName); + } + + public virtual void InitTables(string entitiesNamespace) + { + var types = Assembly.Load(entitiesNamespace).GetTypes(); + InitTables(types); + } + public virtual void InitTables(params string[] entitiesNamespaces) + { + if (entitiesNamespaces.HasValue()) + { + foreach (var item in entitiesNamespaces) + { + InitTables(item); + } + } + } + public TableDifferenceProvider GetDifferenceTables() + { + var type = typeof(T); + return GetDifferenceTables(type); + } + + public TableDifferenceProvider GetDifferenceTables(params Type[] types) + { + TableDifferenceProvider result = new TableDifferenceProvider(); + foreach (var type in types) + { + GetDifferenceTables(result, type); + } + return result; + } + #endregion + + #region Core Logic + private void GetDifferenceTables(TableDifferenceProvider result, Type type) + { + var tempTableName = "TempDiff" + DateTime.Now.ToString("yyMMssHHmmssfff"); + var oldTableName = this.Context.EntityMaintenance.GetEntityInfo(type).DbTableName; + var db = new SqlSugarProvider(UtilMethods.CopyConfig(this.Context.CurrentConnectionConfig)); + db.CurrentConnectionConfig.ConfigureExternalServices = UtilMethods.IsNullReturnNew(db.CurrentConnectionConfig.ConfigureExternalServices); + db.CurrentConnectionConfig.ConfigureExternalServices.EntityNameService += (x, p) => + { + p.IsDisabledUpdateAll = true;//Disabled update + }; + db.MappingTables = new MappingTableList(); + db.MappingTables.Add(type.Name, tempTableName); + try + { + + var codeFirst = db.CodeFirst; + codeFirst.SetStringDefaultLength(this.DefultLength); + codeFirst.InitTables(type); + var tables = db.DbMaintenance.GetTableInfoList(false); + var oldTableInfo = tables.FirstOrDefault(it => it.Name.EqualCase(oldTableName)); + var newTableInfo = tables.FirstOrDefault(it => it.Name.EqualCase(oldTableName)); + var oldTable = db.DbMaintenance.GetColumnInfosByTableName(oldTableName, false); + var tempTable = db.DbMaintenance.GetColumnInfosByTableName(tempTableName, false); + if (oldTableInfo == null) + { + oldTableInfo = new DbTableInfo() { Name = "还未创建:" + oldTableName }; + newTableInfo = new DbTableInfo() { Name = "还未创建:" + oldTableName }; + } + result.tableInfos.Add(new DiffTableInfo() + { + OldTableInfo = oldTableInfo, + NewTableInfo = newTableInfo, + OldColumnInfos = oldTable, + NewColumnInfos = tempTable + }); + } + catch (Exception) + { + throw; + } + finally + { + db.DbMaintenance.DropTable(tempTableName); + } + } + protected virtual void Execute(Type entityType, EntityInfo entityInfo) + { + //var entityInfo = this.Context.EntityMaintenance.GetEntityInfoNoCache(entityType); + if (entityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + entityInfo.Columns.Add(new EntityColumnInfo() { PropertyInfo = typeof(DiscriminatorObject).GetProperty(nameof(DiscriminatorObject.FieldName)), IsOnlyIgnoreUpdate = true, DbColumnName = name, UnderType = typeof(string), PropertyName = name, Length = 50 }); + } + } + if (this.MappingTables.TryGetValue(entityType, out string? v)) + { + entityInfo.DbTableName = v; + this.Context.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName); + } + if (this.DefultLength > 0) + { + foreach (var item in entityInfo.Columns) + { + if (item.PropertyInfo.PropertyType == UtilConstants.StringType && item.DataType.IsNullOrEmpty() && item.Length == 0) + { + item.Length = DefultLength; + } + if (item.DataType?.Contains(',') == true && !Regex.IsMatch(item.DataType, @"\d\,\d")) + { + var types = item.DataType.Split(',').Select(it => it.ToLower()).ToHashSet(); + var mapingTypes = this.Context.Ado.DbBind.MappingTypes.Select(it => it.Key.ToLower()).ToHashSet(); + var mappingType = types.FirstOrDefault(it => mapingTypes.Contains(it)); + if (mappingType != null) + { + item.DataType = mappingType; + } + if (item.DataType == "varcharmax") + { + item.DataType = "nvarchar(max)"; + } + } + } + } + var tableName = GetTableName(entityInfo); + this.Context.MappingTables.Add(entityInfo.EntityName, tableName); + entityInfo.DbTableName = tableName; + entityInfo.Columns.ForEach(it => + { + it.DbTableName = tableName; + if (it.UnderType?.Name == "DateOnly" && it.DataType == null) + { + it.DataType = "Date"; + } + if (it.UnderType?.Name == "TimeOnly" && it.DataType == null) + { + it.DataType = "Time"; + } + }); + var isAny = this.Context.DbMaintenance.IsAnyTable(tableName, false); + if (isAny && entityInfo.IsDisabledUpdateAll) + { + return; + } + if (isAny) + ExistLogic(entityInfo); + else + NoExistLogic(entityInfo); + + this.Context.DbMaintenance.AddRemark(entityInfo); + this.Context.DbMaintenance.AddIndex(entityInfo); + CreateIndex(entityInfo); + this.Context.DbMaintenance.AddDefaultValue(entityInfo); + } + + private void CreateIndex(EntityInfo entityInfo) + { + if (entityInfo.Indexs.HasValue()) + { + foreach (var item in entityInfo.Indexs) + { + if (entityInfo.Type.GetCustomAttribute() != null) + { + if (item.IndexName?.Contains("{split_table}") == true) + { + item.IndexName = item.IndexName.Replace("{split_table}", entityInfo.DbTableName); + } + else + { + item.IndexName = item.IndexName + entityInfo.DbTableName; + } + } + if (this.Context.CurrentConnectionConfig.IndexSuffix.HasValue()) + { + item.IndexName = (this.Context.CurrentConnectionConfig.IndexSuffix + item.IndexName); + } + var include = ""; + if (item.IndexName != null) + { + var database = "{db}"; + if (item.IndexName.Contains(database)) + { + item.IndexName = item.IndexName.Replace(database, this.Context.Ado.Connection.Database); + } + var table = "{table}"; + if (item.IndexName.Contains(table)) + { + item.IndexName = item.IndexName.Replace(table, entityInfo.DbTableName); + } + if (item.IndexName.Contains("{include:", StringComparison.CurrentCultureIgnoreCase)) + { + include = Regex.Match(item.IndexName, @"\{include\:.+$").Value; + item.IndexName = item.IndexName.Replace(include, ""); + } + if (item.IndexName.Contains('.') && item.IndexName.Contains('[')) + { + item.IndexName = item.IndexName.Replace(".", "_"); + item.IndexName = item.IndexName.Replace("[", "").Replace("]", ""); + } + } + if (!this.Context.DbMaintenance.IsAnyIndex(item.IndexName)) + { + var querybulder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + querybulder.Context = this.Context; + var fileds = item.IndexFields + .Select(it => + { + var dbColumn = entityInfo.Columns.FirstOrDefault(z => z.PropertyName == it.Key); + if (dbColumn == null && entityInfo.Discrimator == null) + { + Check.ExceptionEasy($"{entityInfo.EntityName} no SugarIndex[ {it.Key} ] found", $"类{entityInfo.EntityName} 索引特性没找到列 :{it.Key}"); + } + return new KeyValuePair(dbColumn.DbColumnName, it.Value); + }) + .Select(it => querybulder.GetTranslationColumnName(it.Key) + " " + it.Value).ToArray(); + this.Context.DbMaintenance.CreateIndex(entityInfo.DbTableName, fileds, item.IndexName + include, item.IsUnique); + } + } + } + } + + public virtual void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + } + } + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + public virtual void ExistLogic(EntityInfo entityInfo) + { + if (entityInfo.Columns.HasValue() && entityInfo.IsDisabledUpdateAll == false) + { + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Multiple primary keys do not support modifications"); + + var tableName = GetTableName(entityInfo); + var dbColumns = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName, false); + ConvertColumns(dbColumns); + var entityColumns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + var dropColumns = dbColumns + .Where(dc => !entityColumns.Any(ec => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(dc => !entityColumns.Any(ec => dc.DbColumnName.Equals(ec.DbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .ToList(); + var addColumns = entityColumns + .Where(ec => ec.OldDbColumnName.IsNullOrEmpty() || !dbColumns.Any(dc => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(ec => !dbColumns.Any(dc => ec.DbColumnName.Equals(dc.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + var alterColumns = entityColumns + .Where(it => it.IsDisabledAlterColumn == false) + .Where(ec => !dbColumns.Any(dc => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(ec => + dbColumns.Any(dc => dc.DbColumnName.EqualCase(ec.DbColumnName) + && ((ec.Length != dc.Length && !UtilMethods.GetUnderType(ec.PropertyInfo).IsEnum() && UtilMethods.GetUnderType(ec.PropertyInfo).IsIn(UtilConstants.StringType)) || + ec.IsNullable != dc.IsNullable || + IsNoSamePrecision(ec, dc) || + IsNoSamgeType(ec, dc)))).ToList(); + + alterColumns.RemoveAll(entityColumnInfo => + { + var bigStringArray = StaticConfig.CodeFirst_BigString.Replace("varcharmax", "nvarchar(max)").Split(','); + var dbColumnInfo = dbColumns.FirstOrDefault(dc => dc.DbColumnName.EqualCase(entityColumnInfo.DbColumnName)); + var isMaxString = (dbColumnInfo?.Length == -1 && dbColumnInfo?.DataType?.EqualCase("nvarchar") == true); + var isRemove = + dbColumnInfo != null + && bigStringArray.Contains(entityColumnInfo.DataType) + && isMaxString; + return isRemove; + }); + var renameColumns = entityColumns + .Where(it => !string.IsNullOrEmpty(it.OldDbColumnName)) + .Where(entityColumn => dbColumns.Any(dbColumn => entityColumn.OldDbColumnName.Equals(dbColumn.DbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .ToList(); + + + var isMultiplePrimaryKey = dbColumns.Where(it => it.IsPrimarykey).Count() > 1 || entityColumns.Where(it => it.IsPrimarykey).Count() > 1; + + + var isChange = false; + foreach (var item in addColumns) + { + this.Context.DbMaintenance.AddColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + isChange = true; + } + if (entityInfo.IsDisabledDelete == false) + { + foreach (var item in dropColumns) + { + this.Context.DbMaintenance.DropColumn(tableName, item.DbColumnName); + isChange = true; + } + } + foreach (var item in alterColumns) + { + + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + var entityColumnItem = entityColumns.FirstOrDefault(y => y.DbColumnName == item.DbColumnName); + if (entityColumnItem != null && !string.IsNullOrEmpty(entityColumnItem.DataType)) + { + continue; + } + } + + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + isChange = true; + } + foreach (var item in renameColumns) + { + this.Context.DbMaintenance.RenameColumn(tableName, item.OldDbColumnName, item.DbColumnName); + isChange = true; + } + var isAddPrimaryKey = false; + foreach (var item in entityColumns) + { + var dbColumn = dbColumns.FirstOrDefault(dc => dc.DbColumnName.Equals(item.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (dbColumn == null) continue; + bool pkDiff, idEntityDiff; + KeyAction(item, dbColumn, out pkDiff, out idEntityDiff); + if (dbColumn != null && pkDiff && !idEntityDiff && isMultiplePrimaryKey == false) + { + var isAdd = item.IsPrimarykey; + if (isAdd) + { + isAddPrimaryKey = true; + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + else + { + this.Context.DbMaintenance.DropConstraint(tableName, string.Format("PK_{0}_{1}", tableName, item.DbColumnName)); + } + } + else if ((pkDiff || idEntityDiff) && isMultiplePrimaryKey == false) + { + ChangeKey(entityInfo, tableName, item); + } + } + if (isAddPrimaryKey == false && entityColumns.Count(it => it.IsPrimarykey) == 1 && !dbColumns.Any(it => it.IsPrimarykey)) + { + var addPk = entityColumns.First(it => it.IsPrimarykey); + this.Context.DbMaintenance.AddPrimaryKey(tableName, addPk.DbColumnName); + } + if (isMultiplePrimaryKey) + { + var oldPkNames = dbColumns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName.ToLower()).OrderBy(it => it).ToList(); + var newPkNames = entityColumns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName.ToLower()).OrderBy(it => it).ToList(); + if (oldPkNames.Count == 0 && newPkNames.Count > 1) + { + try + { + this.Context.DbMaintenance.AddPrimaryKeys(tableName, newPkNames.ToArray()); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.GetThrowMessage("The current database does not support changing multiple primary keys. " + ex.Message, "当前数据库不支持修改多主键," + ex.Message)); + throw; + } + } + else if (!Enumerable.SequenceEqual(oldPkNames, newPkNames)) + { + Check.Exception(true, ErrorMessage.GetThrowMessage("Modification of multiple primary key tables is not supported. Delete tables while creating", "不支持修改多主键表,请删除表在创建")); + } + + } + if (isChange && IsBackupTable) + { + this.Context.DbMaintenance.BackupTable(tableName, tableName + DateTime.Now.ToString("yyyyMMddHHmmss"), MaxBackupDataRows); + } + ExistLogicEnd(entityColumns); + } + } + + private bool IsNoSamePrecision(EntityColumnInfo ec, DbColumnInfo dc) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.EnableCodeFirstUpdatePrecision == true) + { + return ec.DecimalDigits != dc.DecimalDigits && ec.UnderType.IsIn(UtilConstants.DobType, UtilConstants.DecType); + } + return false; + } + + protected virtual void KeyAction(EntityColumnInfo item, DbColumnInfo dbColumn, out bool pkDiff, out bool idEntityDiff) + { + pkDiff = item.IsPrimarykey != dbColumn.IsPrimarykey; + idEntityDiff = item.IsIdentity != dbColumn.IsIdentity; + } + + protected virtual void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + string constraintName = string.Format("PK_{0}_{1}", tableName, item.DbColumnName); + if (this.Context.DbMaintenance.IsAnyConstraint(constraintName)) + this.Context.DbMaintenance.DropConstraint(tableName, constraintName); + this.Context.DbMaintenance.DropColumn(tableName, item.DbColumnName); + this.Context.DbMaintenance.AddColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + protected virtual void ExistLogicEnd(List dbColumns) + { + + } + protected virtual void ConvertColumns(List dbColumns) + { + + } + #endregion + + #region Helper methods + private void RestMappingTables(MappingTableList oldTableList) + { + this.Context.MappingTables.Clear(); + foreach (var table in oldTableList) + { + this.Context.MappingTables.Add(table.EntityName, table.DbTableName); + } + } + private MappingTableList CopyMappingTalbe() + { + MappingTableList oldTableList = new MappingTableList(); + if (this.Context.MappingTables == null) + { + this.Context.MappingTables = new MappingTableList(); + } + foreach (var table in this.Context.MappingTables) + { + oldTableList.Add(table.EntityName, table.DbTableName); + } + return oldTableList; + } + + public virtual string GetCreateTableString(EntityInfo entityInfo) + { + StringBuilder result = new StringBuilder(); + var tableName = GetTableName(entityInfo); + return result.ToString(); + } + public virtual string GetCreateColumnsString(EntityInfo entityInfo) + { + StringBuilder result = new StringBuilder(); + var tableName = GetTableName(entityInfo); + return result.ToString(); + } + protected virtual string GetTableName(EntityInfo entityInfo) + { + return this.Context.EntityMaintenance.GetTableName(entityInfo.EntityName); + } + protected virtual DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + DecimalDigits = item.DecimalDigits, + CreateTableFieldSort = item.CreateTableFieldSort + }; + GetDbType(item, propertyType, result); + return result; + } + + protected virtual void GetDbType(EntityColumnInfo item, Type propertyType, DbColumnInfo result) + { + if (!string.IsNullOrEmpty(item.DataType)) + { + result.DataType = item.DataType; + } + else if (propertyType.IsEnum()) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(item.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name); + } + else + { + var name = GetType(propertyType.Name); + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(name); + } + } + + protected virtual bool IsNoSamgeType(EntityColumnInfo ec, DbColumnInfo dc) + { + if (!string.IsNullOrEmpty(ec.DataType)) + { + if (ec.IsIdentity && dc.IsIdentity) + { + return false; + } + else + { + return ec.DataType != dc.DataType; + } + } + var propertyType = UtilMethods.GetUnderType(ec.PropertyInfo); + var properyTypeName = string.Empty; + if (propertyType.IsEnum()) + { + properyTypeName = this.Context.Ado.DbBind.GetDbTypeName(ec.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name); + } + else + { + var name = GetType(propertyType.Name); + properyTypeName = this.Context.Ado.DbBind.GetDbTypeName(name); + } + var dataType = dc.DataType; + if (properyTypeName == "boolean" && dataType == "bool") + { + return false; + } + if (properyTypeName?.ToLower() == "varchar" && dataType?.ToLower() == "string") + { + return false; + } + if (properyTypeName?.ToLower() == "varchar" && dataType?.ToLower() == "nvarchar") + { + return false; + } + if (properyTypeName?.ToLower() == "number" && dataType?.ToLower() == "decimal") + { + return false; + } + if (this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true && properyTypeName?.ToLower() == "int" && dataType?.ToLower() == "decimal") + { + return false; + } + if (properyTypeName?.ToLower() == "int" && dataType?.ToLower() == "decimal" && dc.Length == 22 && dc.Scale == 0 && this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + return false; + } + if (properyTypeName?.ToLower() == "int" && dataType?.ToLower() == "int32") + { + return false; + } + if (properyTypeName?.ToLower() == "date" && dataType?.ToLower() == "datetime") + { + return false; + } + if (properyTypeName?.ToLower() == "bigint" && dataType?.ToLower() == "int64") + { + return false; + } + if (properyTypeName?.ToLower() == "blob" && dataType?.ToLower() == "byte[]") + { + return false; + } + if (properyTypeName == null || dataType == null) + { + return properyTypeName != dataType; + } + else if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer && dataType.EqualCase("timestamp") && properyTypeName.EqualCase("varbinary")) + { + return false; + } + else if (properyTypeName.IsIn("int", "long") && dataType.EqualCase("decimal") && dc.Length == 38 && dc.DecimalDigits == 127) + { + return false; + } + else if (dataType.EqualCase("numeric") && properyTypeName.EqualCase("decimal")) + { + return false; + } + else if (ec.UnderType == UtilConstants.BoolType && dc.OracleDataType?.EqualCase("number") == true) + { + return false; + } + else if (ec.UnderType == UtilConstants.LongType && dc.Length == 19 && dc.DecimalDigits == 0 && dc.OracleDataType?.EqualCase("number") == true) + { + return false; + } + else + { + return !properyTypeName.Equals(dataType, StringComparison.CurrentCultureIgnoreCase); + } + } + protected string GetType(string name) + { + if (name.IsContainsIn("UInt32", "UInt16", "UInt64")) + { + name = name.TrimStart('U'); + } + if (name == "char") + { + name = "string"; + } + return name; + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/SplitCodeFirstProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/SplitCodeFirstProvider.cs new file mode 100644 index 000000000..eab8b23b3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/SplitCodeFirstProvider.cs @@ -0,0 +1,66 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class SplitCodeFirstProvider + { + public SqlSugarProvider Context; + + public int DefaultLength { get; set; } + + public void InitTables() + { + var type = typeof(T); + InitTables(type); + } + + public void InitTables(Type type) + { + var isSplitEntity = type.GetCustomAttribute() != null; + if (isSplitEntity) + { + UtilMethods.StartCustomSplitTable(this.Context, type); + _InitTables(type); + UtilMethods.EndCustomSplitTable(this.Context, type); + } + else + { + this.Context.CodeFirst.SetStringDefaultLength(this.DefaultLength).InitTables(type); + } + + } + private void _InitTables(Type type) + { + //var oldMapping = this.Context.Utilities.TranslateCopy(this.Context.MappingTables); + SplitTableContext helper = new SplitTableContext(Context) + { + EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(type) + }; + helper.CheckPrimaryKey(); + var tables = helper.GetTables(); + //var oldMapingTables = this.Context.MappingTables; + if (tables.Count > 0) + { + foreach (var item in tables) + { + this.Context.MappingTables.Add(helper.EntityInfo.EntityName, item.TableName); + this.Context.CodeFirst.SetStringDefaultLength(this.DefaultLength).InitTables(type); + } + } + else + { + this.Context.MappingTables.Add(helper.EntityInfo.EntityName, helper.GetDefaultTableName()); + this.Context.CodeFirst.SetStringDefaultLength(this.DefaultLength).InitTables(type); + } + this.Context.MappingTables.Add(helper.EntityInfo.EntityName, helper.EntityInfo.DbTableName); + } + + public void InitTables(Type[] types) + { + foreach (var type in types) + { + InitTables(type); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/TableDifferenceProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/TableDifferenceProvider.cs new file mode 100644 index 000000000..e0c1d4734 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/CodeFirstProvider/TableDifferenceProvider.cs @@ -0,0 +1,176 @@ +using System.Text; +namespace SqlSugar +{ + public class TableDifferenceProvider + { + internal List tableInfos = new List(); + public string ToDiffString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine(); + var diffTables = this.ToDiffList(); + if (diffTables.IsNullOrEmpty()) + { + sb.AppendLine("No change"); + } + else + { + foreach (var item in diffTables) + { + sb.AppendLine($"----Table:{item.TableName}----"); + if (item.AddColums.HasValue()) + { + sb.AppendLine($"Add column: "); + foreach (var addItem in item.AddColums) + { + sb.AppendLine($"{addItem.Message} "); + } + } + if (item.UpdateColums.HasValue()) + { + sb.AppendLine($"Update column: "); + foreach (var addItem in item.UpdateColums) + { + sb.AppendLine($"{addItem.Message} "); + } + } + if (item.DeleteColums.HasValue()) + { + sb.AppendLine($"Delete column: "); + foreach (var addItem in item.DeleteColums) + { + sb.AppendLine($"{addItem.Message} "); + } + } + } + } + sb.AppendLine(); + sb.AppendLine(); + return sb.ToString(); + } + + public List ToDiffList() + { + List result = new List(); + foreach (var tableInfo in tableInfos) + { + TableDifferenceInfo addItem = new TableDifferenceInfo(); + if (tableInfo.OldTableInfo == null) + tableInfo.OldTableInfo = new DbTableInfo(); + addItem.TableName = tableInfo.OldTableInfo.Name; + addItem.AddColums = GetAddColumn(tableInfo); + addItem.UpdateColums = GetUpdateColumn(tableInfo); + addItem.DeleteColums = GetDeleteColumn(tableInfo); + if (addItem.IsDiff) + result.Add(addItem); + } + return result; + } + + private static List GetDeleteColumn(DiffTableInfo tableInfo) + { + List result = new List(); + var columns = tableInfo.OldColumnInfos.Where(z => !tableInfo.NewColumnInfos.Any(y => y.DbColumnName.EqualCase(z.DbColumnName))); + return columns.Select(it => new DiffColumsInfo() { Message = GetColumnString(it) }).ToList(); + } + + private List GetUpdateColumn(DiffTableInfo tableInfo) + { + List result = new List(); + result = tableInfo.NewColumnInfos + .Where(z => tableInfo.OldColumnInfos.Any(y => y.DbColumnName.EqualCase(z.DbColumnName) && ( + z.Length != y.Length || + z.ColumnDescription != y.ColumnDescription || + z.DataType != y.DataType || + z.DecimalDigits != y.DecimalDigits || + z.IsPrimarykey != y.IsPrimarykey || + z.IsIdentity != y.IsIdentity || + z.IsNullable != y.IsNullable + ))).Select(it => new DiffColumsInfo() + { + Message = GetUpdateColumnString(it, tableInfo.OldColumnInfos.FirstOrDefault(y => y.DbColumnName.EqualCase(it.DbColumnName))) + }).ToList(); + return result; + } + + private static List GetAddColumn(DiffTableInfo tableInfo) + { + List result = new List(); + var columns = tableInfo.NewColumnInfos.Where(z => !tableInfo.OldColumnInfos.Any(y => y.DbColumnName.EqualCase(z.DbColumnName))); + return columns.Select(it => new DiffColumsInfo() { Message = GetColumnString(it) }).ToList(); + } + + private static string GetColumnString(DbColumnInfo it) + { + return $"{it.DbColumnName} {it.DataType} {it.Length} {it.Scale} default:{it.DefaultValue} description:{it.ColumnDescription} pk:{it.IsPrimarykey} nullable:{it.IsNullable} identity:{it.IsIdentity} "; + } + + private static string GetUpdateColumnString(DbColumnInfo it, DbColumnInfo old) + { + var result = $"{it.DbColumnName} changes: "; + if (it.DataType != old.DataType) + { + result += $" [DataType:{old.DataType}->{it.DataType}] "; + } + if (it.Length != old.Length) + { + result += $" [Length:{old.Length}->{it.Length}] "; + } + if (it.Scale != old.Scale) + { + result += $" [Scale:{old.Scale}->{it.Scale}] "; + } + if (it.ColumnDescription != old.ColumnDescription) + { + result += $" [Description:{old.ColumnDescription}->{it.ColumnDescription}] "; + } + if (it.IsPrimarykey != old.IsPrimarykey) + { + result += $" [Pk:{old.IsPrimarykey}->{it.IsPrimarykey}] "; + } + if (it.IsNullable != old.IsNullable) + { + result += $" [Nullable:{old.IsNullable}->{it.IsNullable}] "; + } + if (it.IsIdentity != old.IsIdentity) + { + result += $" [Identity:{old.IsIdentity}->{it.IsIdentity}] "; + } + return result; + } + } + public class TableDifferenceInfo + { + public List DeleteColums { get; set; } = new List(); + public List UpdateColums { get; set; } = new List(); + public List AddColums { get; set; } = new List(); + public List UpdateRemark { get; set; } = new List(); + public bool IsDiff + { + get + { + return + (DeleteColums.Count > 0 || + UpdateColums.Count > 0 || + AddColums.Count > 0 || + UpdateRemark.Count > 0); + } + } + + public string TableName { get; set; } + } + + public class DiffColumsInfo + { + public string SqlTemplate { get; set; } + public string Message { get; set; } + } + + public class DiffTableInfo + { + public DbTableInfo OldTableInfo { get; set; } + public DbTableInfo NewTableInfo { get; set; } + public List OldColumnInfos { get; set; } + public List NewColumnInfos { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/DbBindAccessory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/DbBindAccessory.cs new file mode 100644 index 000000000..3187c79e3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/DbBindAccessory.cs @@ -0,0 +1,446 @@ +using System.Data; +using System.Data.Common; +using System.Text; + +namespace SqlSugar +{ + public partial class DbBindAccessory + { + public QueryBuilder QueryBuilder { get; set; } + + protected List GetEntityList(SqlSugarProvider context, IDataReader dataReader) + { + Type type = typeof(T); + var entityInfo = context.EntityMaintenance.GetEntityInfo(type); + var isOwnsOne = entityInfo.Columns.Any(it => it.ForOwnsOnePropertyInfo != null); + string types = null; + var fieldNames = GetDataReaderNames(dataReader, ref types); + string cacheKey = GetCacheKey(type, fieldNames) + types; + var dataAfterFunc = context.CurrentConnectionConfig?.AopEvents?.DataExecuted; + IDataReaderEntityBuilder entytyList = context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => + { + var cacheResult = new IDataReaderEntityBuilder(context, dataReader, fieldNames).CreateBuilder(type); + return cacheResult; + }); + List result = new List(); + try + { + if (dataReader == null) return result; + while (dataReader.Read()) + { + //try + //{ + var addItem = entytyList.Build(dataReader); + if (this.QueryBuilder?.QueryableFormats?.Count > 0) + { + FormatT(addItem); + } + result.Add(addItem); + //} + //catch (Exception ex) + //{ + // Check.Exception(true, ErrorMessage.EntityMappingErrorCompositeFormat, ex.Message); + //} + SetAppendColumns(dataReader); + SetOwnsOne(addItem, isOwnsOne, entityInfo, dataReader); + } + ExecuteDataAfterFun(context, dataAfterFunc, result); + } + catch (Exception ex) + { + if (ex.Message == "Common Language Runtime detected an invalid program.") + { + Check.Exception(true, ErrorMessage.EntityMappingErrorCompositeFormat, ex.Message); + } + else + { + throw; + } + } + return result; + } + + protected async Task> GetEntityListAsync(SqlSugarProvider context, IDataReader dataReader) + { + Type type = typeof(T); + var entityInfo = context.EntityMaintenance.GetEntityInfo(type); + var isOwnsOne = entityInfo.Columns.Any(it => it.ForOwnsOnePropertyInfo != null); + string types = null; + var fieldNames = GetDataReaderNames(dataReader, ref types); + string cacheKey = GetCacheKey(type, fieldNames) + types; + var dataAfterFunc = context.CurrentConnectionConfig?.AopEvents?.DataExecuted; + IDataReaderEntityBuilder entytyList = context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => + { + var cacheResult = new IDataReaderEntityBuilder(context, dataReader, fieldNames).CreateBuilder(type); + return cacheResult; + }); + List result = new List(); + try + { + if (dataReader == null) return result; + while (await GetReadAsync(dataReader, context).ConfigureAwait(false)) + { + //try + //{ + var addItem = entytyList.Build(dataReader); + if (this.QueryBuilder?.QueryableFormats?.Count > 0) + { + FormatT(addItem); + } + result.Add(addItem); + //} + //catch (Exception ex) + //{ + // Check.Exception(true, ErrorMessage.EntityMappingErrorCompositeFormat, ex.Message); + //} + SetAppendColumns(dataReader); + SetOwnsOne(addItem, isOwnsOne, entityInfo, dataReader); + } + ExecuteDataAfterFun(context, dataAfterFunc, result); + } + catch (Exception ex) + { + if (ex.Message == "Common Language Runtime detected an invalid program.") + { + Check.Exception(true, ErrorMessage.EntityMappingErrorCompositeFormat, ex.Message); + } + else + { + throw; + } + } + return result; + } + + private Task GetReadAsync(IDataReader dataReader, SqlSugarProvider context) + { + if (this.QueryBuilder?.Builder?.SupportReadToken == true && context.Ado.CancellationToken != null) + { + return this.QueryBuilder.Builder.GetReaderByToken(dataReader, context.Ado.CancellationToken.Value); + } + else + { + return ((DbDataReader)dataReader).ReadAsync(); + } + } + + private void SetOwnsOne(object addItem, bool isOwnsOne, EntityInfo entityInfo, IDataReader dataReader) + { + if (isOwnsOne) + { + var ownsOneColumnsKv = entityInfo.Columns.Where(it => it.ForOwnsOnePropertyInfo != null) + .GroupBy(it => it.ForOwnsOnePropertyInfo).ToList(); + foreach (var kv in ownsOneColumnsKv) + { + var parentObj = kv.Key.GetValue(addItem); + if (parentObj == null) + { + parentObj = kv.Key.PropertyType.Assembly.CreateInstance(kv.Key.PropertyType.FullName); + kv.Key.SetValue(addItem, parentObj); + } + foreach (var item in kv.ToList()) + { + if (this.QueryBuilder?.SelectValue?.Equals("1") == true) + { + continue; + } + var itemIndex = dataReader.GetOrdinal(item.DbColumnName); + if (item.SqlParameterDbType is Type && item.UnderType.IsEnum && dataReader.GetValue(itemIndex) is string value) + { + item.PropertyInfo.SetValue(parentObj, UtilMethods.ChangeType2(value, item.PropertyInfo.PropertyType)); + } + else if (item.IsJson) + { + item.PropertyInfo.SetValue(parentObj, Newtonsoft.Json.JsonConvert.DeserializeObject(dataReader.GetValue(itemIndex)?.ToString(), item.PropertyInfo.PropertyType)); + } + else + { + var setValue = dataReader.GetValue(itemIndex); + if (setValue == DBNull.Value) + { + setValue = null; + } + if (item.UnderType == UtilConstants.GuidType && setValue is string) + { + if (setValue != null) + { + setValue = Guid.Parse(setValue + ""); + } + } + else if (item.UnderType?.IsEnum == true && setValue != null) + { + setValue = UtilMethods.ChangeType2(setValue, item.UnderType); + } + else if (UtilMethods.IsParameterConverter(item)) + { + setValue = UtilMethods.QueryConverter(itemIndex, null, dataReader, entityInfo, item); + } + item.PropertyInfo.SetValue(parentObj, setValue); + } + } + } + } + } + + private void FormatT(T addItem) + { + var formats = this.QueryBuilder.QueryableFormats; + var columns = this.QueryBuilder.Context.EntityMaintenance.GetEntityInfoWithAttr(typeof(T)) + .Columns.Where(it => formats.Any(y => y.PropertyName == it.PropertyName)).ToList(); + if (columns.Count != 0) + { + foreach (var item in formats) + { + var columnInfo = columns.FirstOrDefault(it => it.PropertyName == item.PropertyName); + var value = columnInfo.PropertyInfo.GetValue(addItem); + value = UtilMethods.GetFormatValue(value, item); + columnInfo.PropertyInfo.SetValue(addItem, value); + } + } + } + + private static void ExecuteDataAfterFun(SqlSugarProvider context, Action dataAfterFunc, List result) + { + if (dataAfterFunc != null) + { + ((AdoProvider)context.Ado).AfterTime = DateTime.Now; + var entity = context.EntityMaintenance.GetEntityInfo(); + foreach (var item in result) + { + dataAfterFunc(item, new DataAfterModel() + { + EntityColumnInfos = entity.Columns, + Entity = entity, + EntityValue = item + }); + } + } + } + + private string GetCacheKey(Type type, List keys) + { + StringBuilder sb = new StringBuilder("DataReaderToList."); + sb.Append(type.FullName); + sb.Append('.'); + foreach (var item in keys) + { + sb.Append(item); + } + return sb.ToString(); + } + + private void SetAppendColumns(IDataReader dataReader) + { + if (QueryBuilder?.AppendColumns != null && QueryBuilder.AppendColumns.Count != 0) + { + if (QueryBuilder.AppendValues == null) + QueryBuilder.AppendValues = new List>(); + List addItems = new List(); + foreach (var item in QueryBuilder.AppendColumns) + { + var vi = dataReader.GetOrdinal(item.AsName); + var value = dataReader.GetValue(vi); + addItems.Add(new QueryableAppendColumn() + { + Name = item.Name, + AsName = item.AsName, + Value = value + }); + } + QueryBuilder.AppendValues.Add(addItems); + } + if (QueryBuilder?.AppendNavInfo != null) + { + var navResult = new AppendNavResult(); + foreach (var item in QueryBuilder?.AppendNavInfo.AppendProperties) + { + var vi = dataReader.GetOrdinal("SugarNav_" + item.Key); + var value = dataReader.GetValue(vi); + navResult.result.Add("SugarNav_" + item.Key, value); + } + QueryBuilder?.AppendNavInfo.Result.Add(navResult); + } + } + + private List GetDataReaderNames(IDataReader dataReader, ref string types) + { + List keys = new List(); + StringBuilder sbTypes = new StringBuilder(); + var count = dataReader.FieldCount; + for (int i = 0; i < count; i++) + { + keys.Add(dataReader.GetName(i)); + var type = dataReader.GetFieldType(i); + if (type != null) + { + sbTypes.Append(type.Name.AsSpan(0, 2)); + } + } + types = sbTypes.ToString(); + if (this.QueryBuilder?.Context?.Ado is AdoProvider adoProvider) + { + if (adoProvider.IsNoSql) + { + types = "NoSql"; + } + } + return keys; + } + + protected List GetKeyValueList(Type type, IDataReader dataReader) + { + List result = new List(); + while (dataReader.Read()) + { + GetKeyValueList(type, dataReader, result); + } + return result; + } + + protected async Task> GetKeyValueListAsync(Type type, IDataReader dataReader) + { + List result = new List(); + while (await ((DbDataReader)dataReader).ReadAsync().ConfigureAwait(false)) + { + GetKeyValueList(type, dataReader, result); + } + return result; + } + + private static void GetKeyValueList(Type type, IDataReader dataReader, List result) + { + if (UtilConstants.DicOO == type) + { + var kv = new KeyValuePair(dataReader.GetValue(0), dataReader.GetValue(1)); + result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); + } + else if (UtilConstants.DicIS == type) + { + var kv = new KeyValuePair(dataReader.GetValue(0).ObjToInt(), dataReader.GetValue(1).ObjToString()); + result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); + } + else if (UtilConstants.Dicii == type) + { + var kv = new KeyValuePair(dataReader.GetValue(0).ObjToInt(), dataReader.GetValue(1).ObjToInt()); + result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); + } + else if (UtilConstants.DicSi == type) + { + var kv = new KeyValuePair(dataReader.GetValue(0).ObjToString(), dataReader.GetValue(1).ObjToInt()); + result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); + } + else if (UtilConstants.DicSo == type) + { + var kv = new KeyValuePair(dataReader.GetValue(0).ObjToString(), dataReader.GetValue(1)); + result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); + } + else if (UtilConstants.DicSS == type) + { + var kv = new KeyValuePair(dataReader.GetValue(0).ObjToString(), dataReader.GetValue(1).ObjToString()); + result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); + } + else + { + Check.Exception(true, ErrorMessage.NotSupportedDictionaryCompositeFormat); + } + } + + + protected async Task> GetArrayListAsync(Type type, IDataReader dataReader) + { + List result = new List(); + int count = dataReader.FieldCount; + var childType = type.GetElementType(); + while (await ((DbDataReader)dataReader).ReadAsync().ConfigureAwait(false)) + { + GetArrayList(type, dataReader, result, count, childType); + } + return result; + } + + protected List GetArrayList(Type type, IDataReader dataReader) + { + List result = new List(); + int count = dataReader.FieldCount; + var childType = type.GetElementType(); + while (dataReader.Read()) + { + GetArrayList(type, dataReader, result, count, childType); + } + return result; + } + + + + private static void GetArrayList(Type type, IDataReader dataReader, List result, int count, Type childType) + { + object[] array = new object[count]; + for (int i = 0; i < count; i++) + { + array[i] = Convert.ChangeType(dataReader.GetValue(i), childType); + } + if (childType == UtilConstants.StringType) + result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToString()).ToArray(), type)); + else if (childType == UtilConstants.ObjType) + result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? null : (object)it).ToArray(), type)); + else if (childType == UtilConstants.BoolType) + result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToBool()).ToArray(), type)); + else if (childType == UtilConstants.ByteType) + result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? 0 : (byte)it).ToArray(), type)); + else if (childType == UtilConstants.DecType) + result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToDecimal()).ToArray(), type)); + else if (childType == UtilConstants.GuidType) + result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? Guid.Empty : (Guid)it).ToArray(), type)); + else if (childType == UtilConstants.DateType) + result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? DateTime.MinValue : (DateTime)it).ToArray(), type)); + else if (childType == UtilConstants.IntType) + result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToInt()).ToArray(), type)); + else + Check.Exception(true, ErrorMessage.NotSupportedArrayCompositeFormat); + } + + protected List GetValueTypeList(Type type, IDataReader dataReader) + { + List result = new List(); + while (dataReader.Read()) + { + GetValueTypeList(type, dataReader, result); + } + return result; + } + protected async Task> GetValueTypeListAsync(Type type, IDataReader dataReader) + { + List result = new List(); + while (await ((DbDataReader)dataReader).ReadAsync().ConfigureAwait(false)) + { + GetValueTypeList(type, dataReader, result); + } + return result; + } + + private static void GetValueTypeList(Type type, IDataReader dataReader, List result) + { + var value = dataReader.GetValue(0); + if (type == UtilConstants.GuidType) + { + value = Guid.Parse(value.ToString()); + } + if (value == DBNull.Value) + { + result.Add(default(T)); + } + else if (type.IsEnum) + { + result.Add((T)Enum.Parse(type, value.ObjToString())); + } + else if (value != null && UtilMethods.GetUnderType(type).IsEnum) + { + result.Add((T)Enum.Parse(UtilMethods.GetUnderType(type), value.ObjToString())); + } + else + { + result.Add((T)UtilMethods.ChangeType2(value, type)); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/DbBindProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/DbBindProvider.cs new file mode 100644 index 000000000..c36e679ea --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/DbBindProvider.cs @@ -0,0 +1,376 @@ +using System.Collections; +using System.Data; +using System.Reflection; + +namespace SqlSugar +{ + public abstract partial class DbBindProvider : DbBindAccessory, IDbBind + { + #region Properties + public virtual SqlSugarProvider Context { get; set; } + public abstract List> MappingTypes { get; } + #endregion + + #region Public methods + public virtual string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "varbinary"; + if (csharpTypeName.Equals("int32", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "int"; + if (csharpTypeName.Equals("int16", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "short"; + if (csharpTypeName.Equals("int64", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "long"; + if (csharpTypeName.ToLower().IsIn("boolean", "bool")) + csharpTypeName = "bool"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + if (mappings?.Count > 0) + return mappings.First().Key; + else + return "varchar"; + } + public string GetCsharpTypeName(string dbTypeName) + { + var mappings = this.MappingTypes.Where(it => it.Key == dbTypeName); + return mappings.HasValue() ? mappings.First().Key : "string"; + } + + public string GetCsharpTypeNameByDbTypeName(string dbTypeName) + { + var mappings = this.MappingTypes.Where(it => it.Key == dbTypeName); + if (mappings?.Any() != true) + { + return "string"; + } + var result = mappings.First().Value.ObjToString(); + return result; + } + public virtual string GetConvertString(string dbTypeName) + { + string result = string.Empty; + switch (dbTypeName.ToLower()) + { + #region Int + case "int": + result = "Convert.ToInt32"; + break; + #endregion + + #region String + case "nchar": + case "char": + case "ntext": + case "nvarchar": + case "varchar": + case "text": + result = "Convert.ToString"; + break; + #endregion + + #region Long + case "bigint": + result = "Convert.ToInt64"; + break; + #endregion + + #region Bool + case "bit": + result = "Convert.ToBoolean"; + break; + + #endregion + + #region Datetime + case "timestamp": + case "smalldatetime": + case "datetime": + case "date": + case "datetime2": + result = "Convert.ToDateTime"; + break; + #endregion + + #region Decimal + case "smallmoney": + case "single": + case "numeric": + case "money": + case "decimal": + result = "Convert.ToDecimal"; + break; + #endregion + + #region Double + case "float": + result = "Convert.ToSingle"; + break; + case "double": + result = "Convert.ToDouble"; + break; + #endregion + + #region Byte[] + case "varbinary": + case "binary": + case "image": + result = "byte[]"; + break; + #endregion + + #region Float + case "real": + result = "Convert.ToSingle"; + break; + #endregion + + #region Short + case "smallint": + result = "Convert.ToInt16"; + break; + #endregion + + #region Byte + case "tinyint": + result = "Convert.ToByte"; + break; + + #endregion + + #region Guid + case "uniqueidentifier": + result = "Guid.Parse"; + break; + #endregion + + #region Null + default: + result = null; + break; + #endregion + } + return result; + } + public virtual string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (dbTypeName == "int32") + { + return "int"; + } + else if (dbTypeName == "int64") + { + return "long"; + } + else if (dbTypeName == "int16") + { + return "short"; + } + else if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName.IsContainsIn("xml", "string", "String")) + { + return "string"; + } + else if (dbTypeName.IsContainsIn("boolean", "bool")) + { + return "bool"; + } + else if (propertyTypes?.Any() != true) + { + return "object"; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public virtual List DataReaderToList(Type type, IDataReader dataReader) + { + using (dataReader) + { + if (type.Name.StartsWith("KeyValuePair")) + { + return GetKeyValueList(type, dataReader); + } + else if (type.IsValueType() || type == UtilConstants.StringType || type == UtilConstants.ByteArrayType) + { + return GetValueTypeList(type, dataReader); + } + else if (type.IsArray) + { + return GetArrayList(type, dataReader); + } + else if (typeof(T) != type && typeof(T).IsInterface) + { + //这里是为了解决返回类型是接口的问题 + return GetEntityListByType(type, Context, dataReader); + } + else + { + return GetEntityList(Context, dataReader); + } + } + } + + public virtual async Task> DataReaderToListAsync(Type type, IDataReader dataReader) + { + using (dataReader) + { + if (type.Name.StartsWith("KeyValuePair")) + { + return await GetKeyValueListAsync(type, dataReader).ConfigureAwait(false); + } + else if (type.IsValueType() || type == UtilConstants.StringType || type == UtilConstants.ByteArrayType) + { + return await GetValueTypeListAsync(type, dataReader).ConfigureAwait(false); + } + else if (type.IsArray) + { + return await GetArrayListAsync(type, dataReader).ConfigureAwait(false); + } + else if (typeof(T) != type && typeof(T).IsInterface) + { + //这里是为了解决返回类型是接口的问题 + return await GetEntityListByTypeAsync(type, Context, dataReader).ConfigureAwait(false); + } + else + { + return await GetEntityListAsync(Context, dataReader).ConfigureAwait(false); + } + } + } + public virtual List DataReaderToListNoUsing(Type type, IDataReader dataReader) + { + if (type.Name.StartsWith("KeyValuePair")) + { + return GetKeyValueList(type, dataReader); + } + else if (type.IsValueType() || type == UtilConstants.StringType || type == UtilConstants.ByteArrayType) + { + return GetValueTypeList(type, dataReader); + } + else if (type.IsArray) + { + return GetArrayList(type, dataReader); + } + else + { + return GetEntityList(Context, dataReader); + } + } + public virtual Task> DataReaderToListNoUsingAsync(Type type, IDataReader dataReader) + { + if (type.Name.StartsWith("KeyValuePair")) + { + return GetKeyValueListAsync(type, dataReader); + } + else if (type.IsValueType() || type == UtilConstants.StringType || type == UtilConstants.ByteArrayType) + { + return GetValueTypeListAsync(type, dataReader); + } + else if (type.IsArray) + { + return GetArrayListAsync(type, dataReader); + } + else + { + return GetEntityListAsync(Context, dataReader); + } + } + public virtual List GetEntityListByType(Type entityType, SqlSugarProvider context, IDataReader dataReader) + { + var method = typeof(DbBindProvider).GetMethod("GetEntityList", BindingFlags.Instance | BindingFlags.NonPublic); + var genericMethod = method.MakeGenericMethod(entityType); + var objectValue = genericMethod.Invoke(this, new object[] { context, dataReader }); + List result = new List(); + foreach (var item in objectValue as IEnumerable) + { + result.Add((T)item); + } + return result; + } + public virtual async Task> GetEntityListByTypeAsync(Type entityType, SqlSugarProvider context, IDataReader dataReader) + { + var method = typeof(DbBindProvider).GetMethod("GetEntityListAsync", BindingFlags.Instance | BindingFlags.NonPublic); + var genericMethod = method.MakeGenericMethod(entityType); + Task task = (Task)genericMethod.Invoke(this, new object[] { context, dataReader }); + return await GetTask(task).ConfigureAwait(false); + } + private static async Task> GetTask(Task task) + { + await task.ConfigureAwait(false); // 等待任务完成 + var resultProperty = task.GetType().GetProperty("Result"); + var value = resultProperty.GetValue(task); + List result = new List(); + foreach (var item in value as IEnumerable) + { + result.Add((T)item); + } + return (List)result; + } + #endregion + + #region Throw rule + + public virtual List IntThrow + { + get + { + return new List() { "datetime", "byte" }; + } + } + public virtual List ShortThrow + { + get + { + return new List() { "datetime", "guid" }; + } + } + public virtual List DecimalThrow + { + get + { + return new List() { "datetime", "byte", "guid" }; + } + } + public virtual List DoubleThrow + { + get + { + return new List() { "datetime", "byte", "guid" }; + } + } + public virtual List DateThrow + { + get + { + return new List() { "int32", "decimal", "double", "byte", "guid" }; + } + } + public virtual List GuidThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + public virtual List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte", "int64", "uint32", "uint64" }; + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs new file mode 100644 index 000000000..4cb147f1d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs @@ -0,0 +1,511 @@ +using System.Data; +using System.Reflection; +using System.Reflection.Emit; +using System.Xml.Linq; + +namespace SqlSugar +{ + /// + /// ** description:IDataReader Entity Builder + /// ** author:sunkaixuan + /// ** date:2017/4/2 + /// ** qq:610262374 + /// + public partial class IDataReaderEntityBuilder + { + #region Properies + private List ReaderKeys { get; set; } + #endregion + + #region Fields + private SqlSugarProvider Context = null; + private IDataReaderEntityBuilder DynamicBuilder; + private IDataRecord DataRecord; + private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) }); + private static readonly MethodInfo getBoolean = typeof(IDataRecord).GetMethod("GetBoolean", new Type[] { typeof(int) }); + private static readonly MethodInfo getByte = typeof(IDataRecord).GetMethod("GetByte", new Type[] { typeof(int) }); + private static readonly MethodInfo getDateTime = typeof(IDataRecord).GetMethod("GetDateTime", new Type[] { typeof(int) }); + private static readonly MethodInfo getDecimal = typeof(IDataRecord).GetMethod("GetDecimal", new Type[] { typeof(int) }); + private static readonly MethodInfo getDouble = typeof(IDataRecord).GetMethod("GetDouble", new Type[] { typeof(int) }); + private static readonly MethodInfo getFloat = typeof(IDataRecord).GetMethod("GetFloat", new Type[] { typeof(int) }); + private static readonly MethodInfo getGuid = typeof(IDataRecord).GetMethod("GetGuid", new Type[] { typeof(int) }); + private static readonly MethodInfo getInt16 = typeof(IDataRecord).GetMethod("GetInt16", new Type[] { typeof(int) }); + private static readonly MethodInfo getInt32 = typeof(IDataRecord).GetMethod("GetInt32", new Type[] { typeof(int) }); + private static readonly MethodInfo getInt64 = typeof(IDataRecord).GetMethod("GetInt64", new Type[] { typeof(int) }); + private static readonly MethodInfo getString = typeof(IDataRecord).GetMethod("GetString", new Type[] { typeof(int) }); + //private static readonly MethodInfo getConvertValueMethod = typeof(IDataRecordExtensions).GetMethod("GetConvertValue"); + private static readonly MethodInfo getdatetimeoffset = typeof(IDataRecordExtensions).GetMethod("Getdatetimeoffset"); + private static readonly MethodInfo getdatetimeoffsetDate = typeof(IDataRecordExtensions).GetMethod("GetdatetimeoffsetDate"); + private static readonly MethodInfo getStringGuid = typeof(IDataRecordExtensions).GetMethod("GetStringGuid"); + private static readonly MethodInfo getXelement = typeof(IDataRecordExtensions).GetMethod("GetXelement"); + private static readonly MethodInfo getConvertStringGuid = typeof(IDataRecordExtensions).GetMethod("GetConvertStringGuid"); + private static readonly MethodInfo getEnum = typeof(IDataRecordExtensions).GetMethod("GetEnum"); + private static readonly MethodInfo getConvertString = typeof(IDataRecordExtensions).GetMethod("GetConvertString"); + private static readonly MethodInfo getConvertFloat = typeof(IDataRecordExtensions).GetMethod("GetConvertFloat"); + private static readonly MethodInfo getConvertBoolean = typeof(IDataRecordExtensions).GetMethod("GetConvertBoolean"); + private static readonly MethodInfo getConvertByte = typeof(IDataRecordExtensions).GetMethod("GetConvertByte"); + private static readonly MethodInfo getConvertChar = typeof(IDataRecordExtensions).GetMethod("GetConvertChar"); + private static readonly MethodInfo getConvertDateTime = typeof(IDataRecordExtensions).GetMethod("GetConvertDateTime"); + private static readonly MethodInfo getConvertTime = typeof(IDataRecordExtensions).GetMethod("GetConvertTime"); + private static readonly MethodInfo getTime = typeof(IDataRecordExtensions).GetMethod("GetTime"); + private static readonly MethodInfo getConvertDecimal = typeof(IDataRecordExtensions).GetMethod("GetConvertDecimal"); + private static readonly MethodInfo getConvertDouble = typeof(IDataRecordExtensions).GetMethod("GetConvertDouble"); + private static readonly MethodInfo getConvertDoubleToFloat = typeof(IDataRecordExtensions).GetMethod("GetConvertDoubleToFloat"); + private static readonly MethodInfo getConvertGuid = typeof(IDataRecordExtensions).GetMethod("GetConvertGuid"); + private static readonly MethodInfo getConvertInt16 = typeof(IDataRecordExtensions).GetMethod("GetConvertInt16"); + private static readonly MethodInfo getConvertInt32 = typeof(IDataRecordExtensions).GetMethod("GetConvertInt32"); + private static readonly MethodInfo getConvertInt64 = typeof(IDataRecordExtensions).GetMethod("GetConvetInt64"); + private static readonly MethodInfo getConvertEnum_Null = typeof(IDataRecordExtensions).GetMethod("GetConvertEnum_Null"); + private static readonly MethodInfo getConvertdatetimeoffset = typeof(IDataRecordExtensions).GetMethod("GetConvertdatetimeoffset"); + private static readonly MethodInfo getConvertdatetimeoffsetDate = typeof(IDataRecordExtensions).GetMethod("GetConvertdatetimeoffsetDate"); + private static readonly MethodInfo getOtherNull = typeof(IDataRecordExtensions).GetMethod("GetOtherNull"); + private static readonly MethodInfo getOther = typeof(IDataRecordExtensions).GetMethod("GetOther"); + private static readonly MethodInfo getJson = typeof(IDataRecordExtensions).GetMethod("GetJson"); + private static readonly MethodInfo getArray = typeof(IDataRecordExtensions).GetMethod("GetArray"); + private static readonly MethodInfo getEntity = typeof(IDataRecordExtensions).GetMethod("GetEntity", new Type[] { typeof(SqlSugarProvider) }); + private static readonly MethodInfo getMyIntNull = typeof(IDataRecordExtensions).GetMethod("GetMyIntNull"); + private static readonly MethodInfo getMyInt = typeof(IDataRecordExtensions).GetMethod("GetMyInt"); + + private delegate T Load(IDataRecord dataRecord); + private Load handler; + #endregion + + #region Constructor + private IDataReaderEntityBuilder() + { + + } + + public IDataReaderEntityBuilder(SqlSugarProvider context, IDataRecord dataRecord, List fieldNames) + { + this.Context = context; + this.DataRecord = dataRecord; + this.DynamicBuilder = new IDataReaderEntityBuilder(); + this.ReaderKeys = fieldNames; + } + #endregion + + #region Public methods + public T Build(IDataRecord dataRecord) + { + return handler(dataRecord); + } + + public IDataReaderEntityBuilder CreateBuilder(Type type) + { + DynamicMethod method = new DynamicMethod("SqlSugarEntity", type, + new Type[] { typeof(IDataRecord) }, type, true); + ILGenerator generator = method.GetILGenerator(); + LocalBuilder result = generator.DeclareLocal(type); + generator.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, Type.EmptyTypes, null)); + generator.Emit(OpCodes.Stloc, result); + this.Context.InitMappingInfo(type); + var columnInfos = this.Context.EntityMaintenance.GetEntityInfoWithAttr(type).Columns; + foreach (var columnInfo in columnInfos) + { + string fileName = columnInfo.DbColumnName ?? columnInfo.PropertyName; + if (columnInfo.IsIgnore && !this.ReaderKeys.Any(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))) + { + continue; + } + else if (columnInfo.ForOwnsOnePropertyInfo != null) + { + continue; + } + if (columnInfo?.PropertyInfo.GetSetMethod(true) != null) + { + var isGemo = columnInfo.PropertyInfo?.PropertyType?.FullName == "NetTopologySuite.Geometries.Geometry"; + if (isGemo == false && columnInfo.PropertyInfo?.PropertyType?.FullName == "Kdbndp.LegacyPostgis.PostgisGeometry") + { + isGemo = true; + } + if (!isGemo && columnInfo.PropertyInfo.PropertyType.IsClass() && columnInfo.PropertyInfo.PropertyType != UtilConstants.ByteArrayType && columnInfo.PropertyInfo.PropertyType != UtilConstants.ObjType) + { + if (this.ReaderKeys.Any(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))) + { + BindClass(generator, result, columnInfo, ReaderKeys.First(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))); + } + else if (this.ReaderKeys.Any(it => it.Equals(columnInfo.PropertyName, StringComparison.CurrentCultureIgnoreCase))) + { + BindClass(generator, result, columnInfo, ReaderKeys.First(it => it.Equals(columnInfo.PropertyName, StringComparison.CurrentCultureIgnoreCase))); + } + } + else if (!isGemo && columnInfo.IsJson && columnInfo.PropertyInfo.PropertyType != UtilConstants.StringType) + { //json is struct + if (this.ReaderKeys.Any(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))) + { + BindClass(generator, result, columnInfo, ReaderKeys.First(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))); + } + } + else + { + if (this.ReaderKeys.Any(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))) + { + BindField(generator, result, columnInfo, ReaderKeys.First(it => it.Equals(fileName, StringComparison.CurrentCultureIgnoreCase))); + } + else if (this.ReaderKeys.Any(it => it.Equals(columnInfo.PropertyName, StringComparison.CurrentCultureIgnoreCase))) + { + BindField(generator, result, columnInfo, ReaderKeys.First(it => it.Equals(columnInfo.PropertyName, StringComparison.CurrentCultureIgnoreCase))); + } + } + } + } + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ret); + DynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); + return DynamicBuilder; + } + + #endregion + + #region Private methods + private void BindCustomFunc(ILGenerator generator, LocalBuilder result, EntityColumnInfo columnInfo, string fieldName) + { + int i = DataRecord.GetOrdinal(fieldName); + Label endIfLabel = generator.DefineLabel(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, isDBNullMethod); + generator.Emit(OpCodes.Brtrue, endIfLabel); + generator.Emit(OpCodes.Ldloc, result); + //generator.Emit(OpCodes.Ldarg_0); + //generator.Emit(OpCodes.Ldc_I4, i); + var method = (columnInfo.SqlParameterDbType as Type).GetMethod("QueryConverter"); + method = method.MakeGenericMethod(new Type[] { columnInfo.PropertyInfo.PropertyType }); + Type type = (columnInfo.SqlParameterDbType as Type); + //ConstructorInfo info = type.GetConstructor(Type.EmptyTypes); + //il.Emit(OpCodes.Newobj, info); + generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + //method = (columnInfo.SqlParameterDbType as Type).GetMethod("QueryConverter"); + //method = method.MakeGenericMethod(new Type[] { columnInfo.PropertyInfo.PropertyType }); + if (method.IsVirtual) + generator.Emit(OpCodes.Callvirt, method); + else + generator.Emit(OpCodes.Call, method); + generator.Emit(OpCodes.Callvirt, columnInfo.PropertyInfo.GetSetMethod(true)); + generator.MarkLabel(endIfLabel); + } + private void BindClass(ILGenerator generator, LocalBuilder result, EntityColumnInfo columnInfo, string fieldName) + { + + if (columnInfo.SqlParameterDbType is Type) + { + BindCustomFunc(generator, result, columnInfo, fieldName); + return; + } + + if (columnInfo.IsJson) + { + MethodInfo jsonMethod = getJson.MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + int i = DataRecord.GetOrdinal(fieldName); + Label endIfLabel = generator.DefineLabel(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, isDBNullMethod); + generator.Emit(OpCodes.Brtrue, endIfLabel); + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Call, jsonMethod); + generator.Emit(OpCodes.Callvirt, columnInfo.PropertyInfo.GetSetMethod(true)); + generator.MarkLabel(endIfLabel); + } + if (columnInfo.IsArray) + { + MethodInfo arrayMehtod = getArray.MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + int i = DataRecord.GetOrdinal(fieldName); + Label endIfLabel = generator.DefineLabel(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, isDBNullMethod); + generator.Emit(OpCodes.Brtrue, endIfLabel); + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Call, arrayMehtod); + generator.Emit(OpCodes.Callvirt, columnInfo.PropertyInfo.GetSetMethod(true)); + generator.MarkLabel(endIfLabel); + } + else if (columnInfo.UnderType == typeof(XElement)) + { + int i = DataRecord.GetOrdinal(fieldName); + Label endIfLabel = generator.DefineLabel(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, isDBNullMethod); + generator.Emit(OpCodes.Brtrue, endIfLabel); + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + BindMethod(generator, columnInfo, i); + generator.Emit(OpCodes.Callvirt, columnInfo.PropertyInfo.GetSetMethod(true)); + generator.MarkLabel(endIfLabel); + } + } + private void BindField(ILGenerator generator, LocalBuilder result, EntityColumnInfo columnInfo, string fieldName) + { + if (columnInfo.SqlParameterDbType is Type) + { + BindCustomFunc(generator, result, columnInfo, fieldName); + return; + } + int i = DataRecord.GetOrdinal(fieldName); + Label endIfLabel = generator.DefineLabel(); + + //2023-3-8 + Label tryStart = generator.BeginExceptionBlock();//begin try + //2023-3-8 + + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, isDBNullMethod); + generator.Emit(OpCodes.Brtrue, endIfLabel); + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + BindMethod(generator, columnInfo, i); + generator.Emit(OpCodes.Callvirt, columnInfo.PropertyInfo.GetSetMethod(true)); + generator.MarkLabel(endIfLabel); + + //2023-3-8 + generator.Emit(OpCodes.Leave, tryStart);//eng try + generator.BeginCatchBlock(typeof(Exception));//begin catch + generator.Emit(OpCodes.Ldstr, ErrorMessage.GetThrowMessage($"{columnInfo.EntityName} {columnInfo.PropertyName} bind error", $"{columnInfo.PropertyName}绑定到{columnInfo.EntityName}失败,可以试着换一个类型,或者使用ORM自定义类型实现"));//thow message + generator.Emit(OpCodes.Newobj, typeof(Exception).GetConstructor(new Type[] { typeof(string) })); + generator.Emit(OpCodes.Throw); + generator.EndExceptionBlock(); + //2023-3-8 + } + private void BindMethod(ILGenerator generator, EntityColumnInfo columnInfo, int ordinal) + { + IDbBind bind = Context.Ado.DbBind; + bool isNullableType = false; + MethodInfo method = null; + Type bindPropertyType = UtilMethods.GetUnderType(columnInfo.PropertyInfo, ref isNullableType); + string dbTypeName = UtilMethods.GetParenthesesValue(DataRecord.GetDataTypeName(ordinal)); + if (dbTypeName.IsNullOrEmpty()) + { + dbTypeName = bindPropertyType.Name; + } + string propertyName = columnInfo.PropertyName; + string validPropertyName = bind.GetPropertyTypeName(dbTypeName); + validPropertyName = validPropertyName == "byte[]" ? "byteArray" : validPropertyName; + CSharpDataType validPropertyType = (CSharpDataType)Enum.Parse(typeof(CSharpDataType), validPropertyName); + + #region NoSql + if (this.Context.Ado is AdoProvider provider) + { + if (provider.IsNoSql) + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + if (method.IsVirtual) + generator.Emit(OpCodes.Callvirt, method); + else + generator.Emit(OpCodes.Call, method); + return; + } + } + #endregion + + #region Sqlite Logic + if (this.Context.CurrentConnectionConfig.DbType == DbType.Sqlite) + { + if (bindPropertyType.IsEnum()) + { + method = isNullableType ? getConvertEnum_Null.MakeGenericMethod(bindPropertyType) : getEnum.MakeGenericMethod(bindPropertyType); + } + else if (bindPropertyType == UtilConstants.IntType) + { + method = isNullableType ? getConvertInt32 : getInt32; + } + else if (bindPropertyType == UtilConstants.DateTimeOffsetType && SugarCompatible.IsFramework) + { + method = isNullableType ? getConvertdatetimeoffset : getdatetimeoffset; + } + else if (bindPropertyType == UtilConstants.ByteType) + { + method = isNullableType ? getConvertByte : getByte; + } + else if (bindPropertyType == UtilConstants.StringType && dbTypeName?.ToLower() == "timestamp") + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + else if (dbTypeName.EqualCase("STRING")) + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + else if (bindPropertyType == UtilConstants.StringType && validPropertyName == "int") + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + else if (bindPropertyType == UtilConstants.StringType) + { + method = getString; + } + else + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + if (method.IsVirtual) + generator.Emit(OpCodes.Callvirt, method); + else + generator.Emit(OpCodes.Call, method); + return; + } + ; + #endregion + + #region Common Database Logic + string bindProperyTypeName = bindPropertyType.Name.ToLower(); + bool isEnum = bindPropertyType.IsEnum(); + if (isEnum) { validPropertyType = CSharpDataType.@enum; } + switch (validPropertyType) + { + case CSharpDataType.@int: + CheckType(bind.IntThrow, bindProperyTypeName, validPropertyName, propertyName); + if (bindProperyTypeName.IsContainsIn("int", "int32")) + method = isNullableType ? getConvertInt32 : getInt32; + if (bindProperyTypeName.IsContainsIn("int64")) + method = null; + if (bindProperyTypeName.IsContainsIn("byte")) + method = isNullableType ? getConvertByte : getByte; + if (bindProperyTypeName.IsContainsIn("int16")) + method = isNullableType ? getConvertInt16 : getInt16; + if (bindProperyTypeName == "uint32" && this.Context.CurrentConnectionConfig.DbType.IsIn(DbType.MySql, DbType.MySqlConnector)) + method = null; + if (bindPropertyType == UtilConstants.IntType && this.Context.CurrentConnectionConfig.DbType == DbType.OceanBaseForOracle) + method = isNullableType ? getMyIntNull : getMyInt; + if (bindProperyTypeName == "int16") + method = null; + break; + case CSharpDataType.@bool: + if (bindProperyTypeName == "bool" || bindProperyTypeName == "boolean") + method = isNullableType ? getConvertBoolean : getBoolean; + break; + case CSharpDataType.@string: + if (this.Context.CurrentConnectionConfig.DbType != DbType.Oracle) + { + CheckType(bind.StringThrow, bindProperyTypeName, validPropertyName, propertyName); + } + method = getString; + if (bindProperyTypeName == "guid") + { + method = isNullableType ? getConvertStringGuid : getStringGuid; + } + else if (bindProperyTypeName == "xelement") + { + method = getXelement; + } + else if (dbTypeName == "CHAR" && DataRecord.GetDataTypeName(ordinal) == "CHAR(36)") + { + method = null; + } + else if (bindPropertyType.Name == "Char") + { + method = null; + } + break; + case CSharpDataType.DateTime: + CheckType(bind.DateThrow, bindProperyTypeName, validPropertyName, propertyName); + if (bindProperyTypeName == "datetime") + method = isNullableType ? getConvertDateTime : getDateTime; + if (bindProperyTypeName == "datetime" && dbTypeName.Equals("time", StringComparison.CurrentCultureIgnoreCase)) + method = isNullableType ? getConvertTime : getTime; + if (bindProperyTypeName == "datetimeoffset") + method = isNullableType ? getConvertdatetimeoffset : getdatetimeoffset; + break; + case CSharpDataType.@decimal: + CheckType(bind.DecimalThrow, bindProperyTypeName, validPropertyName, propertyName); + if (bindProperyTypeName == "decimal") + method = isNullableType ? getConvertDecimal : getDecimal; + break; + case CSharpDataType.@float: + case CSharpDataType.@double: + CheckType(bind.DoubleThrow, bindProperyTypeName, validPropertyName, propertyName); + if (bindProperyTypeName.IsIn("double", "single") && dbTypeName != "real") + method = isNullableType ? getConvertDouble : getDouble; + else + method = isNullableType ? getConvertFloat : getFloat; + if (dbTypeName.Equals("float", StringComparison.CurrentCultureIgnoreCase) && isNullableType && bindProperyTypeName.Equals("single", StringComparison.CurrentCultureIgnoreCase)) + { + method = getConvertDoubleToFloat; + } + if (bindPropertyType == UtilConstants.DecType) + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + if (bindPropertyType == UtilConstants.IntType) + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + if (bindProperyTypeName == "string") + { + method = null; + } + break; + case CSharpDataType.Guid: + CheckType(bind.GuidThrow, bindProperyTypeName, validPropertyName, propertyName); + if (bindProperyTypeName == "guid") + method = isNullableType ? getConvertGuid : getGuid; + break; + case CSharpDataType.@byte: + if (bindProperyTypeName == "byte") + method = isNullableType ? getConvertByte : getByte; + break; + case CSharpDataType.@enum: + method = isNullableType ? getConvertEnum_Null.MakeGenericMethod(bindPropertyType) : getEnum.MakeGenericMethod(bindPropertyType); + break; + case CSharpDataType.@short: + CheckType(bind.ShortThrow, bindProperyTypeName, validPropertyName, propertyName); + if (bindProperyTypeName == "int16" || bindProperyTypeName == "short") + method = isNullableType ? getConvertInt16 : getInt16; + break; + case CSharpDataType.@long: + if (bindProperyTypeName == "int64" || bindProperyTypeName == "long") + method = isNullableType ? getConvertInt64 : getInt64; + break; + case CSharpDataType.DateTimeOffset: + method = isNullableType ? getConvertdatetimeoffset : getdatetimeoffset; + if (bindProperyTypeName == "datetime") + method = isNullableType ? getConvertdatetimeoffsetDate : getdatetimeoffsetDate; + break; + case CSharpDataType.Single: + break; + default: + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + break; + } + if (method == null && bindPropertyType == UtilConstants.StringType) + { + method = getConvertString; + } + if (bindPropertyType == UtilConstants.ObjType) + { + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + } + if (method == null) + method = isNullableType ? getOtherNull.MakeGenericMethod(bindPropertyType) : getOther.MakeGenericMethod(bindPropertyType); + + + if (method.IsVirtual) + generator.Emit(OpCodes.Callvirt, method); + else + generator.Emit(OpCodes.Call, method); + #endregion + } + + + private void CheckType(List invalidTypes, string bindProperyTypeName, string validPropertyType, string propertyName) + { + var isAny = invalidTypes.Contains(bindProperyTypeName); + if (isAny) + { + throw new SqlSugarException(string.Format("{0} can't convert {1} to {2}", propertyName, validPropertyType, bindProperyTypeName)); + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/IDataRecordExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/IDataRecordExtensions.cs new file mode 100644 index 000000000..f038c8d2e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbBindProvider/IDataRecordExtensions.cs @@ -0,0 +1,399 @@ +using System.Data; +using System.Xml.Linq; + +namespace SqlSugar +{ + public static partial class IDataRecordExtensions + { + + #region Common Extensions + public static XElement GetXelement(this IDataRecord dr, int i) + { + var result = XElement.Parse(dr.GetString(i).ToString()); + return result; + } + public static Guid GetStringGuid(this IDataRecord dr, int i) + { + var result = Guid.Parse(dr.GetValue(i).ToString()); + return result; + } + + public static Guid? GetConvertStringGuid(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return Guid.Empty; + } + var result = Guid.Parse(dr.GetValue(i).ToString()); + return result; + } + + public static bool? GetConvertBoolean(this IDataRecord dr, int i) + { + var result = dr.GetBoolean(i); + return result; + } + + public static byte? GetConvertByte(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetByte(i); + return result; + } + + public static char? GetConvertChar(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetChar(i); + return result; + } + + public static DateTime? GetConvertDateTime(this IDataRecord dr, int i) + { + var result = dr.GetDateTime(i); + if (result == DateTime.MinValue) + { + return null; ; + } + return result; + } + public static DateTime? GetConvertTime(this IDataRecord dr, int i) + { + var result = dr.GetValue(i); + if (result == DBNull.Value) + { + return null; ; + } + return Convert.ToDateTime(result.ToString()); + } + public static DateTime GetTime(this IDataRecord dr, int i) + { + return Convert.ToDateTime(dr.GetValue(i).ToString()); + } + + public static decimal? GetConvertDecimal(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetDecimal(i); + return result; + } + + + public static double? GetConvertDouble(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetDouble(i); + return result; + } + + + public static float? GetConvertDoubleToFloat(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetDouble(i); + return Convert.ToSingle(result); + } + + + public static Guid? GetConvertGuid(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetGuid(i); + return result; + } + + public static short? GetConvertInt16(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetInt16(i); + return result; + } + public static Int32? GetMyIntNull(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + if (dr.GetDataTypeName(i) == "NUMBER") + { + return Convert.ToInt32(dr.GetDouble(i)); + } + var result = dr.GetInt32(i); + return result; + } + public static Int32 GetMyInt(this IDataRecord dr, int i) + { + if (dr.GetDataTypeName(i) == "NUMBER") + { + return Convert.ToInt32(dr.GetDouble(i)); + } + var result = dr.GetInt32(i); + return result; + } + + public static Int32? GetConvertInt32(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetInt32(i); + return result; + } + //public static T GetConvertValue(this IDataRecord dr, int i) + //{ + // try + // { + // if (dr.IsDBNull(i)) + // { + // return default(T); + // } + // var result = dr.GetValue(i); + // return UtilMethods.To(result); + // } + // catch (Exception ex) + // { + // return OtherException(dr, i, ex); + // } + //} + + public static long? GetConvetInt64(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetInt64(i); + return result; + } + + public static float? GetConvertFloat(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = dr.GetFloat(i); + return result; + } + + public static DateTime GetdatetimeoffsetDate(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return DateTime.MinValue; + } + var offsetValue = (DateTimeOffset)dr.GetValue(i); + var result = offsetValue.DateTime; + return result; + } + + public static DateTime? GetConvertdatetimeoffsetDate(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return DateTime.MinValue; + } + var offsetValue = (DateTimeOffset)dr.GetValue(i); + var result = offsetValue.DateTime; + return result; + } + + public static DateTimeOffset Getdatetimeoffset(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return default(DateTimeOffset); + } + var date = dr.GetValue(i); + if (date is DateTime) + { + return new DateTimeOffset((DateTime)(date)); + } + else + { + var result = (DateTimeOffset)date; + return result; + } + } + + public static DateTimeOffset? GetConvertdatetimeoffset(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return default(DateTimeOffset); + } + var date = dr.GetValue(i); + if (date is DateTime) + { + return new DateTimeOffset((DateTime)(date)); + } + else + { + var result = (DateTimeOffset)date; + return result; + } + } + + + public static string GetConvertString(this IDataRecord dr, int i) + { + if (dr.IsDBNull(i)) + { + return null; + } + var result = Convert.ToString(dr.GetValue(i)); + return result; + } + + public static Nullable GetOtherNull(this IDataReader dr, int i) where T : struct + { + if (dr.IsDBNull(i)) + { + return null; + } + return GetOther(dr, i); + + } + + public static T GetOther(this IDataReader dr, int i) + { + try + { + if (dr.IsDBNull(i)) + { + return default(T); + } + var result = dr.GetValue(i); + return UtilMethods.To(result); + } + catch (Exception ex) + { + return OtherException(dr, i, ex); + } + } + + public static T GetJson(this IDataReader dr, int i) + { + var obj = dr.GetValue(i); + if (obj == null) + return default(T); + var value = obj.ObjToString(); + return new SerializeService().DeserializeObject(value); + } + public static T GetArray(this IDataReader dr, int i) + { + //pgsql + var obj = dr.GetValue(i); + if (obj == null) + return default(T); + return (T)obj; + } + + public static Nullable GetConvertEnum_Null(this IDataReader dr, int i) where T : struct + { + if (dr.IsDBNull(i)) + { + return null; + } + object value = dr.GetValue(i); + if (value != null) + { + var valueType = value.GetType(); + if (valueType.IsIn(UtilConstants.FloatType, UtilConstants.DecType, UtilConstants.DobType)) + { + if (Convert.ToDecimal(value) < 0) + { + value = Convert.ToInt32(value); + } + else + { + value = Convert.ToUInt32(value); + } + } + else if (valueType == UtilConstants.StringType) + { + return (T)Enum.Parse(typeof(T), value.ObjToString()); + } + } + T t = (T)Enum.ToObject(typeof(T), value); + return t; + } + + public static T GetEnum(this IDataReader dr, int i) where T : struct + { + object value = dr.GetValue(i); + if (value != null) + { + var valueType = value.GetType(); + if (valueType.IsIn(UtilConstants.FloatType, UtilConstants.DecType, UtilConstants.DobType)) + { + if (Convert.ToDecimal(value) < 0) + { + value = Convert.ToInt32(value); + } + else + { + value = Convert.ToUInt32(value); + } + } + else if (valueType == UtilConstants.StringType) + { + return (T)Enum.Parse(typeof(T), value.ObjToString()); + } + } + T t = (T)Enum.ToObject(typeof(T), value); + return t; + } + + public static object GetEntity(this IDataReader dr, SqlSugarProvider context) + { + return null; + } + + + private static T OtherException(IDataRecord dr, int i, Exception ex) + { + if (dr.GetFieldType(i) == UtilConstants.DateType) + { + return UtilMethods.To(dr.GetConvertDouble(i)); + } + if (dr.GetFieldType(i) == UtilConstants.GuidType) + { + var data = dr.GetString(i); + if (string.IsNullOrEmpty(data)) + { + return UtilMethods.To(default(T)); + } + else + { + return UtilMethods.To(Guid.Parse(data)); + } + } + throw new Exception(ex.Message); + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbFirstProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbFirstProvider.cs new file mode 100644 index 000000000..cb201a465 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbFirstProvider.cs @@ -0,0 +1,605 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public abstract partial class DbFirstProvider : IDbFirst + { + public virtual ISqlSugarClient Context { get; set; } + private string ClassTemplate { get; set; } + private string ClassDescriptionTemplate { get; set; } + private string PropertyTemplate { get; set; } + private string PropertyDescriptionTemplate { get; set; } + private string ConstructorTemplate { get; set; } + private string UsingTemplate { get; set; } + private string Namespace { get; set; } + private bool IsAttribute { get; set; } + private bool IsDefaultValue { get; set; } + private Func WhereColumnsfunc; + private Func FormatFileNameFunc { get; set; } + private Func FormatClassNameFunc { get; set; } + private Func FormatPropertyNameFunc { get; set; } + private bool IsStringNullable { get; set; } + private Func PropertyTextTemplateFunc { get; set; } + private Func ReplaceClassStringFunc { get; set; } + private ISqlBuilder SqlBuilder + { + get + { + return InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + } + } + private List TableInfoList { get; set; } + + public DbFirstProvider() + { + this.ClassTemplate = DbFirstTemplate.ClassTemplate; + this.ClassDescriptionTemplate = DbFirstTemplate.ClassDescriptionTemplate; + this.PropertyTemplate = DbFirstTemplate.PropertyTemplate; + this.PropertyDescriptionTemplate = DbFirstTemplate.PropertyDescriptionTemplate; + this.ConstructorTemplate = DbFirstTemplate.ConstructorTemplate; + this.UsingTemplate = DbFirstTemplate.UsingTemplate; + } + + public void Init() + { + this.Context.Utilities.RemoveCacheAll(); + if (!this.Context.DbMaintenance.IsAnySystemTablePermissions()) + { + Check.Exception(true, "Dbfirst and Codefirst requires system table permissions"); + } + this.TableInfoList = this.Context.Utilities.TranslateCopy(this.Context.DbMaintenance.GetTableInfoList()); + var viewList = this.Context.Utilities.TranslateCopy(this.Context.DbMaintenance.GetViewInfoList()); + if (viewList.HasValue()) + { + this.TableInfoList.AddRange(viewList); + } + } + + #region Setting Template + public IDbFirst StringNullable() + { + IsStringNullable = true; + return this; + } + public IDbFirst SettingClassDescriptionTemplate(Func func) + { + this.ClassDescriptionTemplate = func(this.ClassDescriptionTemplate); + return this; + } + + public IDbFirst SettingClassTemplate(Func func) + { + this.ClassTemplate = func(this.ClassTemplate); + return this; + } + + public IDbFirst SettingConstructorTemplate(Func func) + { + this.ConstructorTemplate = func(this.ConstructorTemplate); + return this; + } + + public IDbFirst SettingPropertyDescriptionTemplate(Func func) + { + this.PropertyDescriptionTemplate = func(this.PropertyDescriptionTemplate); + return this; + } + + public IDbFirst SettingNamespaceTemplate(Func func) + { + this.UsingTemplate = func(this.UsingTemplate); + return this; + } + + public IDbFirst SettingPropertyTemplate(Func func) + { + this.PropertyTemplate = func(this.PropertyTemplate); + return this; + } + public IDbFirst SettingPropertyTemplate(Func func) + { + this.PropertyTextTemplateFunc = func; + return this; + } + public RazorFirst UseRazorAnalysis(string razorClassTemplate, string classNamespace = "Models") + { + if (razorClassTemplate == null) + { + razorClassTemplate = ""; + } + razorClassTemplate = razorClassTemplate.Replace("@Model.Namespace", classNamespace); + var result = new RazorFirst(); + if (this.Context.CurrentConnectionConfig.ConfigureExternalServices?.RazorService != null) + { + List razorList = new List(); + var tables = this.TableInfoList; + if (tables.HasValue()) + { + foreach (var item in tables) + { + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(item.Name, false); + RazorTableInfo table = new RazorTableInfo() + { + Columns = columns.Where(it => WhereColumnsfunc == null || WhereColumnsfunc(it.DbColumnName)).Select(it => new RazorColumnInfo() + { + ColumnDescription = it.ColumnDescription, + DataType = it.DataType, + DbColumnName = it.DbColumnName, + DefaultValue = it.DefaultValue, + IsIdentity = it.IsIdentity, + IsNullable = it.IsNullable, + IsPrimarykey = it.IsPrimarykey, + Length = it.Length + }).ToList(), + Description = item.Description, + DbTableName = item.Name + }; + foreach (var col in table.Columns) + { + col.DataType = GetPropertyTypeName(columns.First(it => it.DbColumnName == col.DbColumnName)); + } + razorList.Add(table); + } + } + result.ClassStringList = this.Context.CurrentConnectionConfig.ConfigureExternalServices.RazorService.GetClassStringList(razorClassTemplate, razorList); + } + else + { + Check.Exception(true, ErrorMessage.GetThrowMessage("Need to achieve ConnectionConfig.ConfigureExternal Services.RazorService", "需要实现 ConnectionConfig.ConfigureExternal Services.RazorService接口")); + } + this.Context.Utilities.RemoveCacheAll(); + result.FormatFileNameFunc = this.FormatFileNameFunc; + return result; + } + #endregion + + #region Setting Content + public IDbFirst IsCreateAttribute(bool isCreateAttribute = true) + { + this.IsAttribute = isCreateAttribute; + return this; + } + public IDbFirst FormatFileName(Func formatFileNameFunc) + { + this.FormatFileNameFunc = formatFileNameFunc; + return this; + } + public IDbFirst FormatClassName(Func formatClassNameFunc) + { + this.FormatClassNameFunc = formatClassNameFunc; + return this; + } + public IDbFirst FormatPropertyName(Func formatPropertyNameFunc) + { + this.FormatPropertyNameFunc = formatPropertyNameFunc; + return this; + } + public IDbFirst CreatedReplaceClassString(Func replaceClassStringFunc) + { + this.ReplaceClassStringFunc = replaceClassStringFunc; + return this; + } + public IDbFirst IsCreateDefaultValue(bool isCreateDefaultValue = true) + { + this.IsDefaultValue = isCreateDefaultValue; + return this; + } + #endregion + + #region Where + public IDbFirst Where(DbObjectType dbObjectType) + { + if (dbObjectType != DbObjectType.All) + this.TableInfoList = this.TableInfoList.Where(it => it.DbObjectType == dbObjectType).ToList(); + return this; + } + + public IDbFirst Where(Func func) + { + this.TableInfoList = this.TableInfoList.Where(it => func(it.Name)).ToList(); + return this; + } + + public IDbFirst WhereColumns(Func func) + { + WhereColumnsfunc = func; + return this; + } + + + public IDbFirst Where(params string[] objectNames) + { + if (objectNames.HasValue()) + { + this.TableInfoList = this.TableInfoList.Where(it => objectNames.Select(x => x.ToLower()).Contains(it.Name.ToLower())).ToList(); + } + return this; + } + #endregion + + #region Core + public Dictionary ToClassStringList(string nameSpace = "Models") + { + this.Namespace = nameSpace; + Dictionary result = new Dictionary(); + if (this.TableInfoList.HasValue()) + { + foreach (var tableInfo in this.TableInfoList) + { + try + { + string classText = null; + string className = tableInfo.Name; + var oldClasName = className; + classText = GetClassString(tableInfo, ref className); + result.Remove(className); + if (this.ReplaceClassStringFunc != null) + { + classText = this.ReplaceClassStringFunc(classText); + } + if (FormatClassNameFunc != null && FormatFileNameFunc != null) + { + className = oldClasName; + } + result.Add(className, classText); + } + catch (Exception ex) + { + Check.Exception(true, "Table '{0}' error,You can filter it with Db.DbFirst.Where(name=>name!=\"{0}\" ) \r\n Error message:{1}", tableInfo.Name, ex.Message); + } + } + } + return result; + } + + internal string GetClassString(DbTableInfo tableInfo, ref string className) + { + string classText; + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(tableInfo.Name, false); + if (this.Context.IgnoreColumns.HasValue()) + { + var entityName = this.Context.EntityMaintenance.GetEntityName(tableInfo.Name); + columns = columns.Where(c => + !this.Context.IgnoreColumns.Any(ig => ig.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && c.DbColumnName == ig.PropertyName) + ).ToList(); + } + classText = this.ClassTemplate; + string ConstructorText = IsDefaultValue ? this.ConstructorTemplate : null; + if (this.Context.MappingTables.HasValue()) + { + var mappingInfo = this.Context.MappingTables.FirstOrDefault(it => it.DbTableName.Equals(tableInfo.Name, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo.HasValue()) + { + className = mappingInfo.EntityName; + } + if (mappingInfo != null) + { + classText = classText.Replace(DbFirstTemplate.KeyClassName, mappingInfo.EntityName); + } + } + if (FormatClassNameFunc != null) + { + className = FormatClassNameFunc(className); + } + classText = classText.Replace(DbFirstTemplate.KeyClassName, className); + classText = classText.Replace(DbFirstTemplate.KeyNamespace, this.Namespace); + classText = classText.Replace(DbFirstTemplate.KeyUsing, IsAttribute ? (this.UsingTemplate + "using " + UtilConstants.AssemblyName + ";\r\n") : this.UsingTemplate); + classText = classText.Replace(DbFirstTemplate.KeyClassDescription, this.ClassDescriptionTemplate.Replace(DbFirstTemplate.KeyClassDescription, tableInfo.Description?.Replace(Environment.NewLine, "\t") + "\r\n")); + classText = classText.Replace(DbFirstTemplate.KeySugarTable, IsAttribute ? string.Format(null, DbFirstTemplate.ValueSugarTable, tableInfo.Name) : null); + if (columns.HasValue()) + { + foreach (var item in columns.Where(it => WhereColumnsfunc == null || WhereColumnsfunc(it.DbColumnName))) + { + var isLast = columns.Last() == item; + var index = columns.IndexOf(item); + string PropertyText = this.PropertyTemplate; + string PropertyDescriptionText = this.PropertyDescriptionTemplate; + string propertyName = GetPropertyName(item); + var oldPropertyName = propertyName; + if (FormatPropertyNameFunc != null) + { + item.DbColumnName = propertyName = FormatPropertyNameFunc(propertyName); + } + string propertyTypeName = GetPropertyTypeName(item); + PropertyText = this.PropertyTextTemplateFunc == null ? GetPropertyText(item, PropertyText) : this.PropertyTextTemplateFunc(item, this.PropertyTemplate, propertyTypeName); + PropertyDescriptionText = GetPropertyDescriptionText(item, PropertyDescriptionText); + if (this.IsAttribute && item.DataType?.StartsWith('_') == true && PropertyText.Contains("[]")) + { + PropertyDescriptionText += "\r\n [SugarColumn(IsArray=true)]"; + } + else if (item?.DataType?.StartsWith("json") == true) + { + PropertyDescriptionText += "\r\n [SugarColumn(IsJson=true)]"; + } + else if (FormatPropertyNameFunc != null) + { + if (PropertyText.Contains("SugarColumn")) + { + PropertyText = PropertyText.Replace(")]", ",ColumnName=\"" + oldPropertyName + "\")]"); + } + else + { + PropertyDescriptionText += "\r\n [SugarColumn(ColumnName=\"" + oldPropertyName + "\")]"; + } + } + PropertyText = PropertyDescriptionText + PropertyText; + classText = classText.Replace(DbFirstTemplate.KeyPropertyName, PropertyText + (isLast ? "" : ("\r\n" + DbFirstTemplate.KeyPropertyName))); + if (ConstructorText.HasValue() && item.DefaultValue != null && item.IsIdentity != true) + { + var hasDefaultValue = columns.Skip(index + 1).Any(it => it.DefaultValue.HasValue()); + if (item.DefaultValue.EqualCase("CURRENT_TIMESTAMP")) + { + item.DefaultValue = "DateTime.Now"; + } + else if (item.DefaultValue == "b'1'") + { + item.DefaultValue = "1"; + } + ConstructorText = ConstructorText.Replace(DbFirstTemplate.KeyPropertyName, propertyName); + ConstructorText = ConstructorText.Replace(DbFirstTemplate.KeyDefaultValue, GetPropertyTypeConvert(item)) + (!hasDefaultValue ? "" : this.ConstructorTemplate); + } + } + } + if (!columns.Any(it => it.DefaultValue != null && it.IsIdentity == false)) + { + ConstructorText = null; + } + classText = classText.Replace(DbFirstTemplate.KeyConstructor, ConstructorText); + classText = classText.Replace(DbFirstTemplate.KeyPropertyName, null); + return classText; + } + + internal string GetClassString(List columns, ref string className) + { + string classText = this.ClassTemplate; + string ConstructorText = IsDefaultValue ? this.ConstructorTemplate : null; + classText = classText.Replace(DbFirstTemplate.KeyClassName, className); + classText = classText.Replace(DbFirstTemplate.KeyNamespace, this.Namespace); + classText = classText.Replace(DbFirstTemplate.KeyUsing, IsAttribute ? (this.UsingTemplate + "using " + UtilConstants.AssemblyName + ";\r\n") : this.UsingTemplate); + classText = classText.Replace(DbFirstTemplate.KeyClassDescription, this.ClassDescriptionTemplate.Replace(DbFirstTemplate.KeyClassDescription, "\r\n")); + classText = classText.Replace(DbFirstTemplate.KeySugarTable, IsAttribute ? string.Format(null, DbFirstTemplate.ValueSugarTable, className) : null); + if (columns.HasValue()) + { + foreach (var item in columns) + { + var isLast = columns.Last() == item; + var index = columns.IndexOf(item); + string PropertyText = this.PropertyTemplate; + string PropertyDescriptionText = this.PropertyDescriptionTemplate; + string propertyName = GetPropertyName(item); + string propertyTypeName = item.PropertyName; + PropertyText = GetPropertyText(item, PropertyText); + PropertyDescriptionText = GetPropertyDescriptionText(item, PropertyDescriptionText); + PropertyText = PropertyDescriptionText + PropertyText; + classText = classText.Replace(DbFirstTemplate.KeyPropertyName, PropertyText + (isLast ? "" : ("\r\n" + DbFirstTemplate.KeyPropertyName))); + if (ConstructorText.HasValue() && item.DefaultValue != null) + { + var hasDefaultValue = columns.Skip(index + 1).Any(it => it.DefaultValue.HasValue()); + ConstructorText = ConstructorText.Replace(DbFirstTemplate.KeyPropertyName, propertyName); + ConstructorText = ConstructorText.Replace(DbFirstTemplate.KeyDefaultValue, GetPropertyTypeConvert(item)) + (!hasDefaultValue ? "" : this.ConstructorTemplate); + } + } + } + if (!columns.Any(it => it.DefaultValue != null)) + { + ConstructorText = null; + } + classText = classText.Replace(DbFirstTemplate.KeyConstructor, ConstructorText); + classText = classText.Replace(DbFirstTemplate.KeyPropertyName, null); + return classText; + } + public void CreateClassFile(string directoryPath, string nameSpace = "Models") + { + var seChar = Path.DirectorySeparatorChar.ToString(); + Check.ArgumentNullException(directoryPath, "directoryPath can't null"); + var classStringList = ToClassStringList(nameSpace); + if (classStringList.IsValuable()) + { + foreach (var item in classStringList) + { + var fileName = item.Key; + if (FormatFileNameFunc != null) + { + fileName = FormatFileNameFunc(fileName); + } + var filePath = directoryPath.TrimEnd('\\').TrimEnd('/') + string.Format(seChar + "{0}.cs", fileName); + FileHelper.CreateFile(filePath, item.Value, Encoding.UTF8); + } + } + } + #endregion + + #region Private methods + private string GetProertypeDefaultValue(DbColumnInfo item) + { + var result = item.DefaultValue; + if (result == null) return null; + if (Regex.IsMatch(result, @"^\(\'(.+)\'\)$")) + { + result = Regex.Match(result, @"^\(\'(.+)\'\)$").Groups[1].Value; + } + if (Regex.IsMatch(result, @"^\(\((.+)\)\)$")) + { + result = Regex.Match(result, @"^\(\((.+)\)\)$").Groups[1].Value; + } + if (Regex.IsMatch(result, @"^\((.+)\)$")) + { + result = Regex.Match(result, @"^\((.+)\)$").Groups[1].Value; + } + if (result.Equals(this.SqlBuilder.SqlDateNow, StringComparison.CurrentCultureIgnoreCase)) + { + result = "DateTime.Now"; + } + if (result.Equals("getdate()", StringComparison.CurrentCultureIgnoreCase)) + { + result = "DateTime.Now"; + } + if (result.Equals("getutcdate()", StringComparison.CurrentCultureIgnoreCase)) + { + result = "DateTime.Now"; + } + if (result.Equals("NOW()", StringComparison.CurrentCultureIgnoreCase)) + { + result = "DateTime.Now"; + } + result = result.Replace("\r", "\t").Replace("\n", "\t"); + result = result.IsIn("''", "\"\"") ? string.Empty : result; + return result; + } + private string GetPropertyText(DbColumnInfo item, string PropertyText) + { + string SugarColumnText = "\r\n [SugarColumn({0})]"; + var propertyName = GetPropertyName(item); + var isMappingColumn = propertyName != item.DbColumnName; + var hasSugarColumn = item.IsPrimarykey == true || item.IsIdentity == true || isMappingColumn; + if (hasSugarColumn && this.IsAttribute) + { + List joinList = new List(); + if (item.IsPrimarykey) + { + joinList.Add("IsPrimaryKey=true"); + } + if (item.IsIdentity) + { + joinList.Add("IsIdentity=true"); + } + if (isMappingColumn) + { + joinList.Add("ColumnName=\"" + item.DbColumnName + '\"'); + } + SugarColumnText = string.Format(SugarColumnText, string.Join(",", joinList)); + } + else + { + SugarColumnText = null; + } + string typeString = GetPropertyTypeName(item); + PropertyText = PropertyText.Replace(DbFirstTemplate.KeySugarColumn, SugarColumnText); + PropertyText = PropertyText.Replace(DbFirstTemplate.KeyPropertyType, typeString); + PropertyText = PropertyText.Replace(DbFirstTemplate.KeyPropertyName, propertyName); + if (typeString == "string" && this.IsStringNullable && item.IsNullable == false && PropertyText.EndsWith("{get;set;}\r\n")) + { + PropertyText = PropertyText.Replace("{get;set;}\r\n", "{get;set;} = null!;\r\n"); + } + return PropertyText; + } + private string GetEnityName(DbColumnInfo item) + { + var mappingInfo = this.Context.MappingTables.FirstOrDefault(it => it.DbTableName.Equals(item.TableName, StringComparison.CurrentCultureIgnoreCase)); + return mappingInfo == null ? item.TableName : mappingInfo.EntityName; + } + private string GetPropertyName(DbColumnInfo item) + { + if (this.Context.MappingColumns.HasValue()) + { + var mappingInfo = this.Context.MappingColumns.SingleOrDefault(it => it.DbColumnName == item.DbColumnName && it.EntityName == GetEnityName(item)); + return mappingInfo == null ? item.DbColumnName : mappingInfo.PropertyName; + } + else + { + return item.DbColumnName; + } + } + protected virtual string GetPropertyTypeName(DbColumnInfo item) + { + string result = item.PropertyType != null ? item.PropertyType.Name : this.Context.Ado.DbBind.GetPropertyTypeName(item.DataType); + if (result != "string" && result != "byte[]" && result != "object" && item.IsNullable) + { + result += "?"; + } + if (result == "Int32") + { + result = item.IsNullable ? "int?" : "int"; + } + if (result == "String") + { + result = "string"; + } + if (result == "string" && item.IsNullable && IsStringNullable) + { + result = result + "?"; + } + if (item.OracleDataType.EqualCase("raw") && item.Length == 16) + { + return "Guid"; + } + if (item.OracleDataType.EqualCase("number") && item.Length == 1 && item.Scale == 0) + { + return "bool"; + } + if (result.EqualCase("char") || result.EqualCase("char?")) + { + return "string"; + } + if (item.DataType == "tinyint unsigned") + { + return "short"; + } + if (item.DataType == "smallint unsigned") + { + return "ushort"; + } + if (item.DataType == "bigint unsigned") + { + return "ulong"; + } + if (item.DataType == "int unsigned") + { + return "uint"; + } + if (item.DataType == "MediumInt") + { + return "int"; + } + if (item.DataType == "MediumInt unsigned") + { + return "uint"; + } + return result; + } + private string GetPropertyTypeConvert(DbColumnInfo item) + { + var convertString = GetProertypeDefaultValue(item); + if (convertString == "DateTime.Now" || convertString == null) + return convertString; + if (convertString.ObjToString() == "newid()") + { + return "Guid.NewGuid()"; + } + if (item.DataType?.ToString()?.EndsWith("unsigned") == true) + { + return convertString; + } + if (item.DataType == "bit") + return (convertString == "1" || convertString.Equals("true", StringComparison.CurrentCultureIgnoreCase)).ToString().ToLower(); + if (convertString.EqualCase("NULL")) + { + return "null"; + } + string result = this.Context.Ado.DbBind.GetConvertString(item.DataType) + "(\"" + convertString + "\")"; + if (this.SqlBuilder.SqlParameterKeyWord == ":" && !string.IsNullOrEmpty(item.OracleDataType)) + { + result = this.Context.Ado.DbBind.GetConvertString(item.OracleDataType) + "(\"" + convertString + "\")"; + } + return result; + } + private string GetPropertyDescriptionText(DbColumnInfo item, string propertyDescriptionText) + { + propertyDescriptionText = propertyDescriptionText.Replace(DbFirstTemplate.KeyPropertyDescription, GetColumnDescription(item.ColumnDescription)); + propertyDescriptionText = propertyDescriptionText.Replace(DbFirstTemplate.KeyDefaultValue, GetProertypeDefaultValue(item)); + propertyDescriptionText = propertyDescriptionText.Replace(DbFirstTemplate.KeyIsNullable, item.IsNullable.ObjToString()); + return propertyDescriptionText; + } + private string GetColumnDescription(string columnDescription) + { + if (columnDescription == null) return columnDescription; + columnDescription = columnDescription.Replace("\r", "\t"); + columnDescription = columnDescription.Replace("\n", "\t"); + columnDescription = columnDescription.Replace(Environment.NewLine, "\t"); + columnDescription = Regex.Replace(columnDescription, "\t{2,}", "\t"); + return columnDescription; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbFirstTemplate.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbFirstTemplate.cs new file mode 100644 index 000000000..8b7a042d1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbFirstTemplate.cs @@ -0,0 +1,73 @@ +using System.Text; + +namespace SqlSugar +{ + public static class DbFirstTemplate + { + #region Template + public static string ClassTemplate = "{using}\r\n" + + "namespace {Namespace}\r\n" + + "{\r\n" + + "{ClassDescription}{SugarTable}\r\n" + + ClassSpace + "public partial class {ClassName}\r\n" + + ClassSpace + "{\r\n" + + PropertySpace + "public {ClassName}(){\r\n\r\n" + + "{Constructor}\r\n" + + PropertySpace + "}\r\n" + + "{PropertyName}\r\n" + + ClassSpace + "}\r\n" + + "}\r\n"; + public static string ClassDescriptionTemplate = + ClassSpace + "///\r\n" + + ClassSpace + "///{ClassDescription}" + + ClassSpace + "///"; + + public static string PropertyTemplate = PropertySpace + "{SugarColumn}\r\n" + + PropertySpace + "public {PropertyType} {PropertyName} {get;set;}\r\n"; + + public static string PropertyDescriptionTemplate = + PropertySpace + "/// \r\n" + + PropertySpace + "/// Desc:{PropertyDescription}\r\n" + + PropertySpace + "/// Default:{DefaultValue}\r\n" + + PropertySpace + "/// Nullable:{IsNullable}\r\n" + + PropertySpace + "/// "; + + public static string ConstructorTemplate = PropertySpace + " this.{PropertyName} ={DefaultValue};\r\n"; + + public static string UsingTemplate = "using System;\r\n" + + "using System.Linq;\r\n" + + "using System.Text;" + "\r\n"; + #endregion + + #region Replace Key + public const string KeyUsing = "{using}"; + public const string KeyNamespace = "{Namespace}"; + public const string KeyClassName = "{ClassName}"; + public const string KeyIsNullable = "{IsNullable}"; + public const string KeySugarTable = "{SugarTable}"; + public const string KeyConstructor = "{Constructor}"; + public const string KeySugarColumn = "{SugarColumn}"; + public const string KeyPropertyType = "{PropertyType}"; + public const string KeyPropertyName = "{PropertyName}"; + public const string KeyDefaultValue = "{DefaultValue}"; + public const string KeyClassDescription = "{ClassDescription}"; + public const string KeyPropertyDescription = "{PropertyDescription}"; + #endregion + + #region Replace Value + + public static readonly CompositeFormat ValueSugarTable = CompositeFormat.Parse(privateValueSugarTable); + + private const string privateValueSugarTable = "\r\n" + ClassSpace + "[SugarTable(\"{0}\")]"; + + public static readonly CompositeFormat ValueSugarCoulmn = CompositeFormat.Parse(privateValueSugarCoulmn); + + private const string privateValueSugarCoulmn = "\r\n" + PropertySpace + "[SugarColumn({0})]"; + #endregion + + #region Space + public const string PropertySpace = " "; + public const string ClassSpace = " "; + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbRazor.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbRazor.cs new file mode 100644 index 000000000..35492eaff --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbFirstProvider/DbRazor.cs @@ -0,0 +1,93 @@ +using System.Text; + +namespace SqlSugar +{ + public class RazorFirst + { + internal List> ClassStringList { get; set; } + internal Func FormatFileNameFunc { get; set; } + + public static string DefaultRazorClassTemplate = +@"using System; +using System.Linq; +using System.Text; +using SqlSugar; +namespace @Model.Namespace +{ + /// + /// + /// + public partial class @Model.ClassName + { + public @(Model.ClassName)(){ + + + } + @foreach (var item in @Model.Columns) + { + if(item.IsPrimarykey&&item.IsIdentity){ + @:/// + @:/// Desc:@item.ColumnDescription + @:/// Default:@item.DefaultValue + @:/// Nullable:@item.IsNullable + @:/// + @:[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + @:public @item.DataType @item.DbColumnName {get;set;} + } + else if(item.IsPrimarykey) + { + @:/// + @:/// Desc:@item.ColumnDescription + @:/// Default:@item.DefaultValue + @:/// Nullable:@item.IsNullable + @:/// + @:[SqlSugar.SugarColumn(IsPrimaryKey = true)] + @:public @item.DataType @item.DbColumnName {get;set;} + } + else if(item.IsIdentity) + { + @:/// + @:/// Desc:@item.ColumnDescription + @:/// Default:@item.DefaultValue + @:/// Nullable:@item.IsNullable + @:/// + @:[SqlSugar.SugarColumn(IsIdentity = true)] + @:public @item.DataType @item.DbColumnName {get;set;} + } + else + { + @:/// + @:/// Desc:@item.ColumnDescription + @:/// Default:@item.DefaultValue + @:/// Nullable:@item.IsNullable + @:/// + @:public @item.DataType @item.DbColumnName {get;set;} + } + } + + } +}"; + + public void CreateClassFile(string directoryPath) + { + var seChar = Path.DirectorySeparatorChar.ToString(); + if (ClassStringList.HasValue()) + { + foreach (var item in ClassStringList) + { + var fileName = item.Key; + if (this.FormatFileNameFunc != null) + { + fileName = this.FormatFileNameFunc(fileName); + } + var filePath = directoryPath.TrimEnd('\\').TrimEnd('/') + string.Format(seChar + "{0}.cs", fileName); + FileHelper.CreateFile(filePath, item.Value, Encoding.UTF8); + } + } + } + public List> GetClassStringList() + { + return ClassStringList; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbMaintenanceProvider/Methods.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbMaintenanceProvider/Methods.cs new file mode 100644 index 000000000..61cd49f6a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbMaintenanceProvider/Methods.cs @@ -0,0 +1,908 @@ +using System.Reflection; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public abstract partial class DbMaintenanceProvider : IDbMaintenance + { + #region DML + public List GetProcList() + { + return GetProcList(this.Context.Ado.Connection.Database); + } + public virtual List GetProcList(string dbName) + { + return new List(); + } + public virtual List GetDataBaseList(SqlSugarClient db) + { + return db.Ado.SqlQuery(this.GetDataBaseSql); + } + public virtual List GetDataBaseList() + { + return this.Context.Ado.SqlQuery(this.GetDataBaseSql); + } + public virtual List GetViewInfoList(bool isCache = true) + { + string cacheKey = "DbMaintenanceProvider.GetViewInfoList" + this.Context.CurrentConnectionConfig.ConfigId; + cacheKey = GetCacheKey(cacheKey); + var result = new List(); + if (isCache) + result = GetListOrCache(cacheKey, this.GetViewInfoListSql); + else + result = this.Context.Ado.SqlQuery(this.GetViewInfoListSql); + foreach (var item in result) + { + item.DbObjectType = DbObjectType.View; + } + return result; + } + public List GetTableInfoList(Func getChangeSqlFunc) + { + var db = this.Context.CopyNew(); + db.CurrentConnectionConfig.IsAutoCloseConnection = true; + db.Aop.OnExecutingChangeSql = (sql, pars) => + { + sql = getChangeSqlFunc(this.Context.CurrentConnectionConfig.DbType, sql); + return new KeyValuePair(sql, pars); + }; + var result = db.DbMaintenance.GetTableInfoList(false); + return result; + } + public virtual List GetTableInfoList(bool isCache = true) + { + string cacheKey = "DbMaintenanceProvider.GetTableInfoList" + this.Context.CurrentConnectionConfig.ConfigId; + cacheKey = GetCacheKey(cacheKey); + var result = new List(); + if (isCache) + result = GetListOrCache(cacheKey, this.GetTableInfoListSql); + else + result = this.Context.Ado.SqlQuery(this.GetTableInfoListSql); + foreach (var item in result) + { + item.DbObjectType = DbObjectType.Table; + } + return result; + } + public List GetColumnInfosByTableName(string tableName, Func getChangeSqlFunc) + { + var db = this.Context.CopyNew(); + db.CurrentConnectionConfig.IsAutoCloseConnection = true; + db.Aop.OnExecutingChangeSql = (sql, pars) => + { + sql = getChangeSqlFunc(this.Context.CurrentConnectionConfig.DbType, sql); + return new KeyValuePair(sql, pars); + }; + var result = db.DbMaintenance.GetColumnInfosByTableName(tableName, false); + return result; + } + public virtual List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + if (string.IsNullOrEmpty(tableName)) return new List(); + string cacheKey = "DbMaintenanceProvider.GetColumnInfosByTableName." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower() + this.Context.CurrentConnectionConfig.ConfigId; + cacheKey = GetCacheKey(cacheKey); + var sql = string.Format(this.GetColumnInfosByTableNameSql, tableName); + if (isCache) + return GetListOrCache(cacheKey, sql).GroupBy(it => it.DbColumnName).Select(it => it.First()).ToList(); + else + return this.Context.Ado.SqlQuery(sql).GroupBy(it => it.DbColumnName).Select(it => it.First()).ToList(); + + } + public virtual List GetIsIdentities(string tableName) + { + string cacheKey = "DbMaintenanceProvider.GetIsIdentities" + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower() + this.Context.CurrentConnectionConfig.ConfigId; + cacheKey = GetCacheKey(cacheKey); + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => + { + var result = GetColumnInfosByTableName(tableName).Where(it => it.IsIdentity).ToList(); + return result.Select(it => it.DbColumnName).ToList(); + }); + } + public virtual List GetPrimaries(string tableName) + { + string cacheKey = "DbMaintenanceProvider.GetPrimaries" + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower() + this.Context.CurrentConnectionConfig.ConfigId; + cacheKey = GetCacheKey(cacheKey); + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => + { + var result = GetColumnInfosByTableName(tableName).Where(it => it.IsPrimarykey).ToList(); + return result.Select(it => it.DbColumnName).ToList(); + }); + } + public virtual List GetIndexList(string tableName) + { + return new List(); + } + public virtual List GetFuncList() + { + return new List(); + } + public virtual List GetTriggerNames(string tableName) + { + return new List(); + } + public virtual List GetDbTypes() + { + return new List(); + } + #endregion + + #region Check + public virtual bool IsAnyTable() + { + if (typeof(T).GetCustomAttribute() != null) + { + var tables = this.Context.SplitHelper(typeof(T)).GetTables(); + var isAny = false; + foreach (var item in tables) + { + if (this.Context.DbMaintenance.IsAnyTable(item.TableName, false)) + { + isAny = true; + break; + } + } + return isAny; + } + else + { + this.Context.InitMappingInfo(); + return this.IsAnyTable(this.Context.EntityMaintenance.GetEntityInfo().DbTableName, false); + } + } + public virtual bool IsAnyTable(string tableName, bool isCache = true) + { + Check.Exception(string.IsNullOrEmpty(tableName), "IsAnyTable tableName is not null"); + tableName = this.SqlBuilder.GetNoTranslationColumnName(tableName); + var tables = GetTableInfoList(isCache); + if (tables == null) return false; + else return tables.Any(it => it.Name.Equals(tableName, StringComparison.CurrentCultureIgnoreCase)); + } + public virtual bool IsAnyColumn(string tableName, string columnName, bool isCache = true) + { + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); + tableName = this.SqlBuilder.GetNoTranslationColumnName(tableName); + var isAny = IsAnyTable(tableName, isCache); + Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); + var columns = GetColumnInfosByTableName(tableName, isCache); + if (columns.IsNullOrEmpty()) return false; + return columns.Any(it => it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)); + } + public virtual bool IsPrimaryKey(string tableName, string columnName) + { + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); + var isAny = IsAnyTable(tableName); + Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); + var columns = GetColumnInfosByTableName(tableName); + if (columns.IsNullOrEmpty()) return false; + var result = columns.Any(it => it.IsPrimarykey == true && it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)); + return result; + } + public virtual bool IsPrimaryKey(string tableName, string columnName, bool isCache = true) + { + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); + var isAny = IsAnyTable(tableName, isCache); + Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); + var columns = GetColumnInfosByTableName(tableName, isCache); + if (columns.IsNullOrEmpty()) return false; + var result = columns.Any(it => it.IsPrimarykey == true && it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)); + return result; + } + public virtual bool IsIdentity(string tableName, string columnName) + { + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); + var isAny = IsAnyTable(tableName); + Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); + var columns = GetColumnInfosByTableName(tableName); + if (columns.IsNullOrEmpty()) return false; + return columns.Any(it => it.IsIdentity = true && it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)); + } + public virtual bool IsAnyConstraint(string constraintName) + { + return this.Context.Ado.GetInt("select object_id('" + constraintName + "')") > 0; + } + public virtual bool IsAnySystemTablePermissions() + { + this.Context.Ado.CheckConnection(); + string sql = this.CheckSystemTablePermissionsSql; + try + { + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + this.Context.Ado.ExecuteCommand(sql); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return true; + } + catch + { + return false; + } + } + #endregion + + #region DDL + public virtual bool SetAutoIncrementInitialValue(string tableName, int initialValue) + { + Console.WriteLine("no support"); + return true; + } + public virtual bool SetAutoIncrementInitialValue(Type entityType, int initialValue) + { + Console.WriteLine("no support"); + return true; + } + public virtual bool DropIndex(string indexName) + { + indexName = this.SqlBuilder.GetNoTranslationColumnName(indexName); + this.Context.Ado.ExecuteCommand($" DROP INDEX {indexName} "); + return true; + } + public virtual bool DropIndex(string indexName, string tableName) + { + indexName = this.SqlBuilder.GetNoTranslationColumnName(indexName); + tableName = this.SqlBuilder.GetNoTranslationColumnName(tableName); + this.Context.Ado.ExecuteCommand($" DROP INDEX {indexName} "); + return true; + } + public virtual bool DropView(string viewName) + { + viewName = this.SqlBuilder.GetNoTranslationColumnName(viewName); + this.Context.Ado.ExecuteCommand($" DROP VIEW {viewName} "); + return true; + } + public virtual bool DropFunction(string funcName) + { + funcName = this.SqlBuilder.GetNoTranslationColumnName(funcName); + this.Context.Ado.ExecuteCommand($" DROP FUNCTION {funcName} "); + return true; + } + public virtual bool DropProc(string procName) + { + procName = this.SqlBuilder.GetNoTranslationColumnName(procName); + this.Context.Ado.ExecuteCommand($" DROP PROCEDURE {procName} "); + return true; + } + /// + ///by current connection string + /// + /// + /// + public virtual bool CreateDatabase(string databaseDirectory = null) + { + var seChar = Path.DirectorySeparatorChar.ToString(); + if (databaseDirectory.HasValue()) + { + databaseDirectory = databaseDirectory.TrimEnd('\\').TrimEnd('/'); + } + var databaseName = this.Context.Ado.Connection.Database; + return CreateDatabase(databaseName, databaseDirectory); + } + /// + /// by databaseName + /// + /// + /// + /// + public virtual bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + this.Context.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, databaseName, databaseDirectory)); + return true; + } + + public virtual bool AddPrimaryKey(string tableName, string columnName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + columnName = this.SqlBuilder.GetTranslationTableName(columnName); + var temp = "PK_{0}_{1}"; + if (tableName.IsContainsIn(" ", "-")) + { + temp = SqlBuilder.GetTranslationColumnName(temp); + } + string sql = string.Format(this.AddPrimaryKeySql, tableName, string.Format(temp, this.SqlBuilder.GetNoTranslationColumnName(tableName).Replace("-", "_"), this.SqlBuilder.GetNoTranslationColumnName(columnName)), columnName); + if ((tableName + columnName).Length > 25 && this.Context?.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength > 0) + { + sql = string.Format(this.AddPrimaryKeySql, tableName, string.Format(temp, this.SqlBuilder.GetNoTranslationColumnName(tableName).GetNonNegativeHashCodeString(), "Id"), columnName); + } + this.Context.Ado.ExecuteCommand(sql); + return true; + } + + public bool AddPrimaryKeys(string tableName, string[] columnNames) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName = string.Join(",", columnNames); + var pkName = string.Format("PK_{0}_{1}", this.SqlBuilder.GetNoTranslationColumnName(tableName), columnName.Replace(",", "_")); + if (pkName.Length > 25 && this.Context?.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength > 0) + { + pkName = "PK_" + pkName.GetNonNegativeHashCodeString(); + } + columnName = string.Join(",", columnNames.Select(it => SqlBuilder.GetTranslationColumnName(it))); + string sql = string.Format(this.AddPrimaryKeySql, tableName, pkName, columnName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public bool AddPrimaryKeys(string tableName, string[] columnNames, string pkName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName = string.Join(",", columnNames); + //var pkName = string.Format("PK_{0}_{1}", this.SqlBuilder.GetNoTranslationColumnName(tableName), columnName.Replace(",", "_")); + string sql = string.Format(this.AddPrimaryKeySql, tableName, pkName, columnName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool AddColumn(string tableName, DbColumnInfo columnInfo) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var isAddNotNUll = columnInfo.IsNullable == false && columnInfo.DefaultValue.HasValue(); + if (isAddNotNUll) + { + columnInfo = this.Context.Utilities.TranslateCopy(columnInfo); + columnInfo.IsNullable = true; + } + string sql = GetAddColumnSql(tableName, columnInfo); + this.Context.Ado.ExecuteCommand(sql); + if (isAddNotNUll) + { + if (columnInfo.TableName == null) + { + columnInfo.TableName = tableName; + } + var dtColums = this.Context.Queryable().AS(columnInfo.TableName).Where("1=2") + .Select(this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName)).ToDataTable().Columns.Cast(); + var dtColumInfo = dtColums.First(it => it.ColumnName.EqualCase(columnInfo.DbColumnName)); + var type = UtilMethods.GetUnderType(dtColumInfo.DataType); + var value = type == UtilConstants.StringType ? (object)"" : Activator.CreateInstance(type); + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + value = columnInfo.DefaultValue; + if (value.Equals("")) + { + value = "empty"; + } + } + value = GetDefaultValue(columnInfo, value); + var dt = new Dictionary(); + dt.Add(columnInfo.DbColumnName, value); + if (columnInfo.DataType.EqualCase("json") && columnInfo.DefaultValue?.Contains('}') == true) + { + { + dt[columnInfo.DbColumnName] = "{}"; + var sqlobj = this.Context.Updateable(dt) + .AS(tableName) + .Where($"{this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName)} is null ").ToSql(); + sqlobj.Value[0].IsJson = true; + this.Context.Ado.ExecuteCommand(sqlobj.Key, sqlobj.Value); + } + } + else if (columnInfo.DataType.EqualCase("json") && columnInfo.DefaultValue?.Contains(']') == true) + { + { + dt[columnInfo.DbColumnName] = "[]"; + var sqlobj = this.Context.Updateable(dt) + .AS(tableName) + .Where($"{this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName)} is null ").ToSql(); + sqlobj.Value[0].IsJson = true; + this.Context.Ado.ExecuteCommand(sqlobj.Key, sqlobj.Value); + } + } + else + { + this.Context.Updateable(dt) + .AS(tableName) + .Where($"{this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName)} is null ").ExecuteCommand(); + } + columnInfo.IsNullable = false; + UpdateColumn(tableName, columnInfo); + } + return true; + } + public virtual object GetDefaultValue(DbColumnInfo columnInfo, object value) + { + if (columnInfo.DataType.ObjToString().ToLower().IsIn("varchar", "nvarchar", "varchar2", "nvarchar2") && !string.IsNullOrEmpty(columnInfo.DefaultValue) && Regex.IsMatch(columnInfo.DefaultValue, @"^\w+$")) + { + value = columnInfo.DefaultValue; + } + else if (columnInfo.DataType.ObjToString().ToLower().IsIn("float", "double", "decimal", "int", "int4", "bigint", "int8", "int2") && columnInfo.DefaultValue.IsInt()) + { + value = Convert.ToInt32(columnInfo.DefaultValue); + } + return value; + } + public virtual bool UpdateColumn(string tableName, DbColumnInfo column) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string sql = GetUpdateColumnSql(tableName, column); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public abstract bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true); + public virtual bool DropTable(string tableName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + this.Context.Ado.ExecuteCommand(string.Format(this.DropTableSql, tableName)); + return true; + } + public virtual bool DropTable(string[] tableName) + { + foreach (var item in tableName) + { + DropTable(item); + } + return true; + } + public virtual bool DropTable(Type[] tableEnittyTypes) + { + foreach (var item in tableEnittyTypes) + { + var tableName = this.Context.EntityMaintenance.GetTableName(item); + DropTable(tableName); + } + return true; + } + public virtual bool DropTable() + { + if (typeof(T).GetCustomAttribute() != null) + { + var tables = this.Context.SplitHelper(typeof(T)).GetTables(); + foreach (var item in tables) + { + this.Context.DbMaintenance.DropTable(SqlBuilder.GetTranslationColumnName(item.TableName)); + } + return true; + } + else + { + var tableName = this.Context.EntityMaintenance.GetTableName(); + return DropTable(tableName); + } + } + public virtual bool DropTable() + { + DropTable(); + DropTable(); + return true; + } + public virtual bool DropTable() + { + DropTable(); + DropTable(); + DropTable(); + return true; + } + public virtual bool DropTable() + { + DropTable(); + DropTable(); + DropTable(); + DropTable(); + return true; + } + public virtual bool TruncateTable() + { + if (typeof(T).GetCustomAttribute() != null) + { + var tables = this.Context.SplitHelper(typeof(T)).GetTables(); + foreach (var item in tables) + { + this.Context.DbMaintenance.TruncateTable(SqlBuilder.GetTranslationColumnName(item.TableName)); + } + return true; + } + else + { + this.Context.InitMappingInfo(); + return this.TruncateTable(this.Context.EntityMaintenance.GetEntityInfo().DbTableName); + } + } + public virtual bool TruncateTable() + { + TruncateTable(); + TruncateTable(); + return true; + } + public virtual bool TruncateTable() + { + TruncateTable(); + TruncateTable(); + TruncateTable(); + return true; + } + public virtual bool TruncateTable() + { + TruncateTable(); + TruncateTable(); + TruncateTable(); + TruncateTable(); + return true; + } + public virtual bool TruncateTable() + { + TruncateTable(); + TruncateTable(); + TruncateTable(); + TruncateTable(); + TruncateTable(); + return true; + } + public virtual bool DropColumn(string tableName, string columnName) + { + columnName = this.SqlBuilder.GetTranslationColumnName(columnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + this.Context.Ado.ExecuteCommand(string.Format(this.DropColumnToTableSql, tableName, columnName)); + return true; + } + public virtual bool DropConstraint(string tableName, string constraintName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string sql = string.Format(this.DropConstraintSql, tableName, constraintName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool TruncateTable(string tableName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + this.Context.Ado.ExecuteCommand(string.Format(this.TruncateTableSql, tableName)); + return true; + } + public bool TruncateTable(params string[] tableNames) + { + foreach (var item in tableNames) + { + TruncateTable(item); + } + return true; + } + public bool TruncateTable(params Type[] tableEnittyTypes) + { + foreach (var item in tableEnittyTypes) + { + var name = this.Context.EntityMaintenance.GetTableName(item); + TruncateTable(name); + } + return true; + } + public virtual bool BackupDataBase(string databaseName, string fullFileName) + { + var directory = FileHelper.GetDirectoryFromFilePath(fullFileName); + if (!FileHelper.IsExistDirectory(directory)) + { + FileHelper.CreateDirectory(directory); + } + this.Context.Ado.ExecuteCommand(string.Format(this.BackupDataBaseSql, databaseName, fullFileName)); + return true; + } + public virtual bool BackupTable(string oldTableName, string newTableName, int maxBackupDataRows = int.MaxValue) + { + oldTableName = this.SqlBuilder.GetTranslationTableName(oldTableName); + newTableName = this.SqlBuilder.GetTranslationTableName(newTableName); + string sql = string.Format(this.BackupTableSql, maxBackupDataRows, newTableName, oldTableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool RenameColumn(string tableName, string oldColumnName, string newColumnName) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + oldColumnName = this.SqlBuilder.GetTranslationColumnName(oldColumnName); + newColumnName = this.SqlBuilder.GetTranslationColumnName(newColumnName); + string sql = string.Format(this.RenameColumnSql, tableName, oldColumnName, newColumnName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool AddColumnRemark(string columnName, string tableName, string description) + { + string sql = string.Format(this.AddColumnRemarkSql, columnName, tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool DeleteColumnRemark(string columnName, string tableName) + { + string sql = string.Format(this.DeleteColumnRemarkSql, columnName, tableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool IsAnyColumnRemark(string columnName, string tableName) + { + string sql = string.Format(this.IsAnyColumnRemarkSql, columnName, tableName); + var dt = this.Context.Ado.GetDataTable(sql); + return dt.Rows?.Count > 0; + } + public virtual bool AddTableRemark(string tableName, string description) + { + string sql = string.Format(this.AddTableRemarkSql, tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool DeleteTableRemark(string tableName) + { + string sql = string.Format(this.DeleteTableRemarkSql, tableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool IsAnyTableRemark(string tableName) + { + string sql = string.Format(this.IsAnyTableRemarkSql, tableName); + var dt = this.Context.Ado.GetDataTable(sql); + return dt.Rows?.Count > 0; + } + public virtual bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue == "''") + { + defaultValue = ""; + } + if (defaultValue.IsDate() && !AddDefaultValueSql.Contains("'{2}'")) + { + defaultValue = "'" + defaultValue + "'"; + } + if (defaultValue?.EqualCase("'current_timestamp'") == true) + { + defaultValue = defaultValue.TrimEnd('\'').TrimStart('\''); + } + if (defaultValue?.EqualCase("'current_date'") == true) + { + defaultValue = defaultValue.TrimEnd('\'').TrimStart('\''); + } + string sql = string.Format(AddDefaultValueSql, tableName, columnName, defaultValue); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool CreateIndex(string tableName, string[] columnNames, bool isUnique = false) + { + string sql = string.Format(CreateIndexSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",", columnNames.Select(it => this.SqlBuilder.GetTranslationColumnName(it))), string.Join("_", columnNames) + this.Context.CurrentConnectionConfig.IndexSuffix, isUnique ? "UNIQUE" : ""); + sql = sql.Replace("_" + this.SqlBuilder.SqlTranslationLeft, "_"); + sql = sql.Replace(this.SqlBuilder.SqlTranslationRight + "_", "_"); + sql = sql.Replace(this.SqlBuilder.SqlTranslationLeft + this.SqlBuilder.SqlTranslationLeft, this.SqlBuilder.SqlTranslationLeft); + sql = sql.Replace(this.SqlBuilder.SqlTranslationRight + this.SqlBuilder.SqlTranslationRight, this.SqlBuilder.SqlTranslationRight); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool CreateUniqueIndex(string tableName, string[] columnNames) + { + string sql = string.Format(CreateIndexSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",", columnNames.Select(it => this.SqlBuilder.GetTranslationColumnName(it))), string.Join("_", columnNames) + this.Context.CurrentConnectionConfig.IndexSuffix + "_Unique", "UNIQUE"); + sql = sql.Replace("_" + this.SqlBuilder.SqlTranslationLeft, "_"); + sql = sql.Replace(this.SqlBuilder.SqlTranslationRight + "_", "_"); + sql = sql.Replace(this.SqlBuilder.SqlTranslationLeft + this.SqlBuilder.SqlTranslationLeft, this.SqlBuilder.SqlTranslationLeft); + sql = sql.Replace(this.SqlBuilder.SqlTranslationRight + this.SqlBuilder.SqlTranslationRight, this.SqlBuilder.SqlTranslationRight); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool CreateIndex(string tableName, string[] columnNames, string IndexName, bool isUnique = false) + { + var include = ""; + if (IndexName.Contains("{include:", StringComparison.CurrentCultureIgnoreCase)) + { + include = Regex.Match(IndexName, @"\{include\:.+$").Value; + IndexName = IndexName.Replace(include, ""); + if (include == null) + { + throw new Exception("include format error"); + } + include = include.Replace("{include:", "").Replace("}", ""); + include = $"include({include})"; + } + string sql = string.Format("CREATE {3} INDEX {2} ON {0}({1})" + include, this.SqlBuilder.GetTranslationColumnName(tableName), string.Join(",", columnNames), IndexName, isUnique ? "UNIQUE" : ""); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool IsAnyIndex(string indexName) + { + //string sql = string.Format(this.IsAnyIndexSql, indexName); + string sql = string.Format(this.IsAnyIndexSql, indexName, this.Context.Ado.Connection.Database); + return this.Context.Ado.GetInt(sql) > 0; + } + public virtual bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + List dbColumn = new List(); + if (entity.Columns.Any(it => it.ColumnDescription.HasValue())) + { + dbColumn = db.DbMaintenance.GetColumnInfosByTableName(entity.DbTableName, false); + } + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + //column remak + if (db.DbMaintenance.IsAnyColumnRemark(item.DbColumnName, item.DbTableName)) + { + if (!dbColumn.Any(it => it.DbColumnName == item.DbColumnName && it.ColumnDescription == item.ColumnDescription)) + { + db.DbMaintenance.DeleteColumnRemark(item.DbColumnName, item.DbTableName); + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + } + } + else + { + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + } + } + } + + //table remak + if (entity.TableDescription != null) + { + if (db.DbMaintenance.IsAnyTableRemark(entity.DbTableName)) + { + db.DbMaintenance.DeleteTableRemark(entity.DbTableName); + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + else + { + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + } + return true; + } + + public virtual void AddIndex(EntityInfo entityInfo) + { + var db = this.Context; + var columns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + var indexColumns = columns.Where(it => it.IndexGroupNameList.HasValue()).ToList(); + if (indexColumns.HasValue()) + { + var groups = indexColumns.SelectMany(it => it.IndexGroupNameList).GroupBy(it => it).Select(it => it.Key).ToList(); + foreach (var item in groups) + { + var columnNames = indexColumns.Where(it => it.IndexGroupNameList.Any(i => i.Equals(item, StringComparison.CurrentCultureIgnoreCase))).Select(it => it.DbColumnName).ToArray(); + var indexName = string.Format("Index_{0}_{1}" + this.Context.CurrentConnectionConfig.IndexSuffix, entityInfo.DbTableName, string.Join("_", columnNames)); + if (!IsAnyIndex(indexName)) + { + CreateIndex(entityInfo.DbTableName, columnNames); + } + } + } + + + var uIndexColumns = columns.Where(it => it.UIndexGroupNameList.HasValue()).ToList(); + if (uIndexColumns.HasValue()) + { + var groups = uIndexColumns.SelectMany(it => it.UIndexGroupNameList).GroupBy(it => it).Select(it => it.Key).ToList(); + foreach (var item in groups) + { + var columnNames = uIndexColumns.Where(it => it.UIndexGroupNameList.Any(i => i.Equals(item, StringComparison.CurrentCultureIgnoreCase))).Select(it => it.DbColumnName).ToArray(); + var indexName = string.Format("Index_{0}_{1}_Unique" + this.Context.CurrentConnectionConfig.IndexSuffix, entityInfo.DbTableName, string.Join("_", columnNames)); + if (!IsAnyIndex(indexName)) + { + CreateUniqueIndex(entityInfo.DbTableName, columnNames); + } + } + } + } + + protected virtual bool IsAnyDefaultValue(string tableName, string columnName, List columns) + { + var defaultValue = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)).First().DefaultValue; + return defaultValue.HasValue(); + } + + public virtual bool IsAnyDefaultValue(string tableName, string columnName) + { + return IsAnyDefaultValue(tableName, columnName, this.GetColumnInfosByTableName(tableName, false)); + } + + public virtual void AddDefaultValue(EntityInfo entityInfo) + { + var dbColumns = this.GetColumnInfosByTableName(entityInfo.DbTableName, false); + var db = this.Context; + var columns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + foreach (var item in columns) + { + if (item.DefaultValue != null) + { + if (!IsAnyDefaultValue(entityInfo.DbTableName, item.DbColumnName, dbColumns)) + { + this.AddDefaultValue(entityInfo.DbTableName, item.DbColumnName, item.DefaultValue); + } + } + } + } + + public virtual bool RenameTable(string oldTableName, string newTableName) + { + string sql = string.Format(this.RenameTableSql, oldTableName, newTableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool IsAnyProcedure(string procName) + { + string sql = string.Format(this.IsAnyProcedureSql, procName); + return this.Context.Ado.GetInt(sql) > 0; + } + #endregion + + #region Private + public virtual List GetSchemaTables(EntityInfo entityInfo) + { + return null; + } + protected List GetListOrCache(string cacheKey, string sql) + { + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + var isEnableLogEvent = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var result = this.Context.Ado.SqlQuery(sql); + this.Context.Ado.IsEnableLogEvent = isEnableLogEvent; + return result; + }); + } + protected virtual 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; + string primaryKey = null; + string identity = item.IsIdentity ? this.CreateTableIdentity : null; + string addItem = string.Format(this.CreateTableColumn, columnName, dataType, dataSize, nullType, primaryKey, identity); + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",\r\n", columnArray)); + return tableString; + } + protected virtual string GetAddColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataType = columnInfo.DataType; + if (dataType.EqualCase("varchar") + && this.Context.CurrentConnectionConfig?.MoreSettings?.SqlServerCodeFirstNvarchar == true + && this.Context.CurrentConnectionConfig?.DbType == DbType.SqlServer) + { + dataType = "nvarchar"; + } + string dataSize = GetSize(columnInfo); + string nullType = columnInfo.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AddColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + protected virtual string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + string nullType = columnInfo.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + protected virtual string GetCacheKey(string cacheKey) + { + return this.Context.CurrentConnectionConfig.DbType + "." + this.Context.Ado.Connection.Database + "." + cacheKey; + } + protected virtual string GetSize(DbColumnInfo item) + { + string dataSize = null; + var isMax = item.Length > 4000 || item.Length == -1; + if (isMax) + { + dataSize = item.Length > 0 ? string.Format("({0})", "max") : null; + } + else if (item.Length == 0 && item.DecimalDigits > 0) + { + item.Length = 10; + dataSize = string.Format("({0},{1})", item.Length, item.DecimalDigits); + } + else if (item.Length > 0 && item.DecimalDigits == 0) + { + dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + } + else if (item.Length > 0 && item.DecimalDigits > 0) + { + dataSize = item.Length > 0 ? string.Format("({0},{1})", item.Length, item.DecimalDigits) : null; + } + return dataSize; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbMaintenanceProvider/Properties.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbMaintenanceProvider/Properties.cs new file mode 100644 index 000000000..76ec2f787 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DbMaintenanceProvider/Properties.cs @@ -0,0 +1,67 @@ +namespace SqlSugar +{ + public abstract partial class DbMaintenanceProvider : IDbMaintenance + { + #region Context + private ISqlBuilder _SqlBuilder; + public SqlSugarProvider Context { get; set; } + public ISqlBuilder SqlBuilder + { + get + { + if (_SqlBuilder == null) + { + _SqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + _SqlBuilder.Context = this.Context; + } + return _SqlBuilder; + } + } + #endregion + + #region DML + protected abstract string GetViewInfoListSql { get; } + protected abstract string GetDataBaseSql { get; } + protected abstract string GetTableInfoListSql { get; } + protected abstract string GetColumnInfosByTableNameSql { get; } + #endregion + + #region DDL + protected abstract string CreateIndexSql { get; } + protected abstract string IsAnyIndexSql { get; } + protected abstract string AddDefaultValueSql { get; } + protected abstract string CreateDataBaseSql { get; } + protected abstract string AddColumnToTableSql { get; } + protected abstract string AlterColumnToTableSql { get; } + protected abstract string BackupDataBaseSql { get; } + protected abstract string CreateTableSql { get; } + protected abstract string CreateTableColumn { get; } + protected abstract string BackupTableSql { get; } + protected abstract string TruncateTableSql { get; } + protected abstract string DropTableSql { get; } + protected abstract string DropColumnToTableSql { get; } + protected abstract string DropConstraintSql { get; } + protected abstract string AddPrimaryKeySql { get; } + protected abstract string RenameColumnSql { get; } + protected abstract string AddColumnRemarkSql { get; } + protected abstract string DeleteColumnRemarkSql { get; } + protected abstract string IsAnyColumnRemarkSql { get; } + protected abstract string AddTableRemarkSql { get; } + protected abstract string DeleteTableRemarkSql { get; } + protected abstract string IsAnyTableRemarkSql { get; } + protected abstract string RenameTableSql { get; } + protected virtual string IsAnyProcedureSql { get; } + #endregion + + #region Check + protected abstract string CheckSystemTablePermissionsSql { get; } + #endregion + + #region Scattered + protected abstract string CreateTableNull { get; } + protected abstract string CreateTableNotNull { get; } + protected abstract string CreateTablePirmaryKey { get; } + protected abstract string CreateTableIdentity { get; } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteMethodInfo.cs new file mode 100644 index 000000000..155fc94a7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteMethodInfo.cs @@ -0,0 +1,61 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class DeleteMethodInfo + { + internal SqlSugarProvider Context { get; set; } + internal MethodInfo MethodInfo { get; set; } + internal object objectValue { get; set; } + + public int ExecuteCommand() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMethod("ExecuteCommand").Invoke(inertable, Array.Empty()); + return (int)result; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(inertable, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + + public CommonMethodInfo AS(string tableName) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("AS", 1, typeof(string)); + var result = newMethod.Invoke(inertable, new object[] { tableName }); + return new CommonMethodInfo() + { + Context = result + }; + } + public CommonMethodInfo EnableDiffLogEvent(object businessData = null) + { + if (Context == null) + { + return new CommonMethodInfo(); + } + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("EnableDiffLogEvent", 1, typeof(object)); + var result = newMethod.Invoke(inertable, new object[] { businessData }); + return new CommonMethodInfo() + { + Context = result + }; + } + public CommonMethodInfo SplitTable() + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("SplitTable", 0); + var result = newMethod.Invoke(inertable, Array.Empty()); + return new CommonMethodInfo() + { + Context = result + }; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteNavMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteNavMethodInfo.cs new file mode 100644 index 000000000..e7ab7658c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteNavMethodInfo.cs @@ -0,0 +1,49 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class DeleteNavMethodInfo + { + internal object MethodInfos { get; set; } + internal SqlSugarProvider Context { get; set; } + + public DeleteNavMethodInfo IncludeByNameString(string navMemberName, DeleteNavOptions deleteNavOptions = null) + { + var type = MethodInfos.GetType().GetGenericArguments()[0]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.MethodInfos.GetType().GetMyMethod("Include", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this.MethodInfos, new object[] { exp, deleteNavOptions }); + this.MethodInfos = obj; + return this; + } + public DeleteNavMethodInfo ThenIncludeByNameString(string navMemberName, DeleteNavOptions deleteNavOptions = null) + { + var type = MethodInfos.GetType().GetGenericArguments()[1]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.MethodInfos.GetType().GetMyMethod("ThenInclude", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this.MethodInfos, new object[] { exp, deleteNavOptions }); + this.MethodInfos = obj; + return this; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return false; + var result = MethodInfos.GetType().GetMethod("ExecuteCommandAsync").Invoke(MethodInfos, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public bool ExecuteCommand() + { + if (Context == null) return false; + var result = MethodInfos.GetType().GetMethod("ExecuteCommand").Invoke(MethodInfos, Array.Empty()); + return (bool)result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteablePage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteablePage.cs new file mode 100644 index 000000000..08f7b6790 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteablePage.cs @@ -0,0 +1,81 @@ +namespace SqlSugar +{ + public class DeleteablePage where T : class, new() + { + public T[] DataList { get; set; } + public ISqlSugarClient Context { get; set; } + public int PageSize { get; internal set; } + public string TableName { get; internal set; } + public bool IsEnableDiffLogEvent { get; internal set; } + public DiffLogModel DiffModel { get; internal set; } + public List UpdateColumns { get; internal set; } + public int ExecuteCommand() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + this.Context.Utilities.PageEach(DataList, PageSize, pageItem => + { + result += this.Context.Deleteable(pageItem).AS(TableName).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).ExecuteCommand(); + }); + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return result; + } + public async Task ExecuteCommandAsync() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + await Context.Utilities.PageEachAsync(DataList, PageSize, async pageItem => + { + result += await Context.Deleteable(pageItem).AS(TableName).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).ExecuteCommandAsync().ConfigureAwait(false); + }).ConfigureAwait(false); + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteableProvider.cs new file mode 100644 index 000000000..160472003 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/DeleteableProvider.cs @@ -0,0 +1,781 @@ +using System.Collections; +using System.Data; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class DeleteableProvider : IDeleteable where T : class, new() + { + public ISqlSugarClient Context { get; set; } + public IAdo Db { get { return Context.Ado; } } + public ISqlBuilder SqlBuilder { get; set; } + public DeleteBuilder DeleteBuilder { get; set; } + public MappingTableList OldMappingTableList { get; set; } + public bool IsAs { get; set; } + public bool IsEnableDiffLogEvent { get; set; } + public DiffLogModel diffModel { get; set; } + public List tempPrimaryKeys { get; set; } + internal Action RemoveCacheFunc { get; set; } + public List DeleteObjects { get; set; } + public EntityInfo EntityInfo + { + get + { + return this.Context.EntityMaintenance.GetEntityInfo(); + } + } + public void AddQueue() + { + var sqlObj = this.ToSql(); + this.Context.Queues.Add(sqlObj.Key, sqlObj.Value); + } + public int ExecuteCommand() + { + string sql; + SugarParameter[] paramters; + _ExecuteCommand(out sql, out paramters); + var result = Db.ExecuteCommand(sql, paramters); + After(sql); + return result; + } + public bool ExecuteCommandHasChange() + { + return ExecuteCommand() > 0; + } + public Task ExecuteCommandAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ExecuteCommandAsync(); + } + public async Task ExecuteCommandAsync() + { + string sql; + SugarParameter[] paramters; + _ExecuteCommand(out sql, out paramters); + var result = await Db.ExecuteCommandAsync(sql, paramters).ConfigureAwait(false); + After(sql); + return result; + } + public async Task ExecuteCommandHasChangeAsync() + { + return await ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public IDeleteable AsType(Type tableNameType) + { + return AS(this.Context.EntityMaintenance.GetEntityInfo(tableNameType).DbTableName); + } + public IDeleteable AS(string tableName) + { + if (tableName == null) return this; + //var entityName = typeof(T).Name; + //IsAs = true; + //OldMappingTableList = this.Context.MappingTables; + //this.Context.MappingTables = this.Context.Utilities.TranslateCopy(this.Context.MappingTables); + //if (this.Context.MappingTables.Any(it => it.EntityName == entityName)) + //{ + // this.Context.MappingTables.Add(this.Context.MappingTables.First(it => it.EntityName == entityName).DbTableName, tableName); + //} + //this.Context.MappingTables.Add(entityName, tableName); + this.DeleteBuilder.AsName = tableName; + return this; ; + } + public IDeleteable EnableDiffLogEventIF(bool isEnableDiffLogEvent, object businessData = null) + { + if (isEnableDiffLogEvent) + { + return EnableDiffLogEvent(businessData); + } + else + { + return this; + } + } + public IDeleteable EnableDiffLogEvent(object businessData = null) + { + + diffModel = new DiffLogModel(); + this.IsEnableDiffLogEvent = true; + diffModel.BusinessData = businessData; + diffModel.DiffType = DiffType.delete; + return this; + } + + public IDeleteable Where(List deleteObjs) + { + this.DeleteObjects = deleteObjs; + if (deleteObjs == null || deleteObjs.Count == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + DataAop(deleteObjs); + string tableName = this.Context.EntityMaintenance.GetTableName(); + var primaryFields = this.GetPrimaryKeys(); + var isSinglePrimaryKey = primaryFields.Count == 1; + Check.Exception(primaryFields.IsNullOrEmpty(), string.Format("Table {0} with no primarykey", tableName)); + if (isSinglePrimaryKey) + { + List primaryKeyValues = new List(); + var primaryField = primaryFields.Single(); + foreach (var deleteObj in deleteObjs) + { + var entityPropertyName = this.Context.EntityMaintenance.GetPropertyName(primaryField); + var columnInfo = EntityInfo.Columns.Single(it => it.PropertyName.Equals(entityPropertyName, StringComparison.CurrentCultureIgnoreCase)); + var value = columnInfo.PropertyInfo.GetValue(deleteObj, null); + value = UtilMethods.GetConvertValue(value); + if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true && + columnInfo.SqlParameterDbType == null && + columnInfo.PropertyInfo.PropertyType.IsEnum()) + { + value = Convert.ToInt64(value); + } + primaryKeyValues.Add(value); + } + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle && primaryKeyValues.Count >= 1000) + { + List inItems = new List(); + this.Context.Utilities.PageEach(primaryKeyValues, 999, pageItems => + { + var inValueString = pageItems.ToArray().ToJoinSqlInVals(); + var whereItem = string.Format(DeleteBuilder.WhereInTemplate, SqlBuilder.GetTranslationColumnName(primaryFields.Single()), inValueString); + inItems.Add(whereItem); + }); + Where($"({string.Join(" OR ", inItems)})"); + } + else if (primaryKeyValues.Count < 10000) + { + var inValueString = primaryKeyValues.ToArray().ToJoinSqlInVals(); + Where(string.Format(DeleteBuilder.WhereInTemplate, SqlBuilder.GetTranslationColumnName(primaryFields.Single()), inValueString)); + } + else + { + if (DeleteBuilder.BigDataInValues == null) + DeleteBuilder.BigDataInValues = new List(); + DeleteBuilder.BigDataInValues.AddRange(primaryKeyValues); + DeleteBuilder.BigDataFiled = primaryField; + } + } + else + { + StringBuilder whereInSql = new StringBuilder(); + foreach (var deleteObj in deleteObjs) + { + StringBuilder orString = new StringBuilder(); + var isFirst = deleteObjs.IndexOf(deleteObj) == 0; + if (!isFirst) + { + orString.Append(DeleteBuilder.WhereInOrTemplate + UtilConstants.Space); + } + int i = 0; + StringBuilder andString = new StringBuilder(); + foreach (var primaryField in primaryFields) + { + if (i != 0) + andString.Append(DeleteBuilder.WhereInAndTemplate + UtilConstants.Space); + //var entityPropertyName = this.EntityInfo.Columns.Single(it=>it.PropertyName.EqualCase(primaryField)||it.DbColumnName.EqualCase(primaryField)).PropertyName; + var columnInfo = EntityInfo.Columns.Single(t => t.PropertyName.EqualCase(primaryField) || t.DbColumnName.EqualCase(primaryField)); + var entityValue = columnInfo.PropertyInfo.GetValue(deleteObj, null); + if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true && + columnInfo.SqlParameterDbType == null && + columnInfo.PropertyInfo.PropertyType.IsEnum()) + { + entityValue = Convert.ToInt64(entityValue); + } + var tempequals = DeleteBuilder.WhereInEqualTemplate; + if (this.Context.CurrentConnectionConfig.MoreSettings?.DisableNvarchar == true) + { + tempequals = $"{SqlBuilder.SqlTranslationLeft}{{0}}{SqlBuilder.SqlTranslationRight}='{{1}}' "; + } + if (SqlBuilder.SqlParameterKeyWord == ":") + { + var isAutoToUpper = this.Context.CurrentConnectionConfig?.MoreSettings?.IsAutoToUpper ?? true; + if (entityValue != null && UtilMethods.GetUnderType(entityValue.GetType()) == UtilConstants.DateType) + { + andString.AppendFormat("\"{0}\"={1} ", primaryField.ToUpper(isAutoToUpper), "to_date('" + entityValue.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "); + } + else + { + andString.AppendFormat(tempequals.Replace("N", "") + " ", primaryField.ToUpper(isAutoToUpper), entityValue); + } + } + else if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL && (this.Context.CurrentConnectionConfig.MoreSettings == null || this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLower == true)) + { + andString.AppendFormat("\"{0}\"={1} ", primaryField.ToLower(), new PostgreSQLExpressionContext().GetValue(entityValue)); + } + else if (entityValue != null && UtilMethods.IsNumber(UtilMethods.GetUnderType(entityValue.GetType()).Name)) + { + andString.AppendFormat("{0}={1} ", this.SqlBuilder.GetTranslationColumnName(primaryField), $"{entityValue}"); + } + else if (entityValue != null && UtilMethods.GetUnderType(entityValue.GetType()) == UtilConstants.DateType) + { + andString.AppendFormat("{0}={1} ", this.SqlBuilder.GetTranslationColumnName(primaryField), this.DeleteBuilder.LambdaExpressions.DbMehtods.ToDate(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs() + { + IsMember=false, + MemberName="'"+entityValue.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff")+"'" + } + } + })); ; + } + else + { + if ((columnInfo.SqlParameterDbType.ObjToString() == System.Data.DbType.AnsiString.ObjToString()) || !(entityValue is string) || this.Context.CurrentConnectionConfig?.MoreSettings?.DisableNvarchar == true) + { + tempequals = tempequals.Replace("=N'", "='"); + } + else + { + tempequals = SqlBuilder.RemoveN(tempequals); + } + entityValue = UtilMethods.GetConvertValue(entityValue); + andString.AppendFormat(tempequals, primaryField, entityValue); + } + ++i; + } + orString.AppendFormat(DeleteBuilder.WhereInAreaTemplate, andString); + whereInSql.Append(orString); + } + Where(string.Format(DeleteBuilder.WhereInAreaTemplate, whereInSql.ToString())); + } + return this; + } + public IDeleteable WhereIF(bool isWhere, Expression> expression) + { + if (DeleteBuilder.WhereInfos.Count != 0 != true) + { + Check.ExceptionEasy(!StaticConfig.EnableAllWhereIF, "Need to program startup configuration StaticConfig. EnableAllWhereIF = true; Tip: This operation is very risky if there are no conditions it is easy to update the entire table", " 需要程序启动时配置StaticConfig.EnableAllWhereIF=true; 提示:该操作存在很大的风险如果没有条件很容易将整个表全部更新"); + } + if (isWhere) + { + return Where(expression); + } + return this; + } + public IDeleteable Where(Expression> expression) + { + var expResult = DeleteBuilder.GetExpressionValue(expression, ResolveExpressType.WhereSingle); + var whereString = expResult.GetResultString(); + if (expression.ToString().Contains("Subqueryable()")) + { + var entityTableName = this.EntityInfo.DbTableName; + if (this.DeleteBuilder.AsName.HasValue()) + { + entityTableName = this.DeleteBuilder.AsName; + } + if (ExpressionTool.GetParameters(expression).First().Type == typeof(T)) + { + var tableName = this.SqlBuilder.GetTranslationColumnName(entityTableName); + whereString = whereString.Replace(tableName, $"( SELECT * FROM {tableName}) "); + } + whereString = whereString.Replace(this.SqlBuilder.GetTranslationColumnName(expression.Parameters.First().Name) + ".", this.SqlBuilder.GetTranslationTableName(entityTableName) + "."); + } + else if (expResult.IsNavicate) + { + var entityTableName2 = this.EntityInfo.DbTableName; + if (this.DeleteBuilder.AsName.HasValue()) + { + entityTableName2 = this.DeleteBuilder.AsName; + } + whereString = whereString.Replace(expression.Parameters.First().Name + ".", this.SqlBuilder.GetTranslationTableName(entityTableName2) + "."); + whereString = whereString.Replace(this.SqlBuilder.GetTranslationColumnName(expression.Parameters.First().Name) + ".", this.SqlBuilder.GetTranslationTableName(entityTableName2) + "."); + + } + DeleteBuilder.WhereInfos.Add(whereString); + return this; + } + + public IDeleteable Where(T deleteObj) + { + Check.Exception(GetPrimaryKeys().IsNullOrEmpty(), "Where(entity) Primary key required"); + Where(new List() { deleteObj }); + return this; + } + + public IDeleteable Where(string whereString, object parameters = null) + { + DeleteBuilder.WhereInfos.Add(whereString); + if (parameters != null) + { + if (DeleteBuilder.Parameters == null) + { + DeleteBuilder.Parameters = new List(); + } + DeleteBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + } + return this; + } + + public IDeleteable Where(string whereString, SugarParameter parameter) + { + DeleteBuilder.WhereInfos.Add(whereString); + if (DeleteBuilder.Parameters == null) + { + DeleteBuilder.Parameters = new List(); + } + DeleteBuilder.Parameters.Add(parameter); + return this; + } + public IDeleteable Where(string whereString, SugarParameter[] parameters) + { + DeleteBuilder.WhereInfos.Add(whereString); + if (DeleteBuilder.Parameters == null) + { + DeleteBuilder.Parameters = new List(); + } + DeleteBuilder.Parameters.AddRange(parameters); + return this; + } + public IDeleteable Where(string whereString, List parameters) + { + DeleteBuilder.WhereInfos.Add(whereString); + if (DeleteBuilder.Parameters == null) + { + DeleteBuilder.Parameters = new List(); + } + DeleteBuilder.Parameters.AddRange(parameters); + return this; + } + public IDeleteable Where(List conditionalModels, bool isWrap) + { + if (conditionalModels.Count == 0) + { + return Where("1=2"); + } + var sql = this.Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + var result = this; + if (isWrap) + { + result.Where($"({sql.Key})", sql.Value); + } + else + { + result.Where(sql.Key, sql.Value); + } + return result; + } + public IDeleteable Where(List conditionalModels) + { + if (conditionalModels.Count == 0) + { + return Where("1=2"); + } + var sql = this.Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + var result = this; + result.Where(sql.Key, sql.Value); + return result; + } + public IDeleteable WhereColumns(T data, Expression> columns) + { + return WhereColumns(new List() { data }, columns); + } + public IDeleteable WhereColumns(List list, Expression> columns) + { + if (columns != null) + { + tempPrimaryKeys = DeleteBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + } + //else if (columns != null && tempPrimaryKeys.IsNullOrEmpty()) + //{ + // tempPrimaryKeys = DeleteBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + //} + this.Where(list); + + return this; + } + public IDeleteable WhereColumns(List> list) + { + List conditionalModels = new List(); + foreach (var model in list) + { + int i = 0; + var clist = new List>(); + foreach (var item in model.Keys) + { + clist.Add(new KeyValuePair(i == 0 ? WhereType.Or : WhereType.And, new ConditionalModel() + { + FieldName = item, + ConditionalType = ConditionalType.Equal, + FieldValue = model[item].ObjToStringNoTrim(), + CSharpTypeName = model[item] == null ? null : model[item].GetType().Name + })); + i++; + } + conditionalModels.Add(new ConditionalCollections() + { + ConditionalList = clist + }); + } + return this.Where(conditionalModels); + } + public IDeleteable RemoveDataCache() + { + this.RemoveCacheFunc = () => + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + CacheSchemeMain.RemoveCache(cacheService, this.Context.EntityMaintenance.GetTableName()); + }; + return this; + } + public IDeleteable EnableQueryFilter() + { + var queryable = this.Context.Queryable(); + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 1000; + var sqlable = queryable.ToSql(); + var whereInfos = Regex.Split(sqlable.Key, " Where ", RegexOptions.IgnoreCase); + if (whereInfos.Length > 1) + { + this.Where(whereInfos.Last(), sqlable.Value); + } + return this; + } + public IDeleteable EnableQueryFilter(Type type) + { + var queryable = this.Context.Queryable().Filter(type); + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 1000; + var sqlable = queryable.ToSql(); + var whereInfos = Regex.Split(sqlable.Key, " Where ", RegexOptions.IgnoreCase); + if (whereInfos.Length > 1) + { + this.Where(whereInfos.Last(), sqlable.Value); + } + return this; + } + public SplitTableDeleteProvider SplitTable(Func, IEnumerable> getTableNamesFunc) + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + this.Context.MappingTables.Add(this.EntityInfo.EntityName, this.EntityInfo.DbTableName); + SplitTableDeleteProvider result = new SplitTableDeleteProvider(); + result.Context = this.Context; + SplitTableContext helper = new SplitTableContext((SqlSugarProvider)Context) + { + EntityInfo = this.EntityInfo + }; + var tables = getTableNamesFunc(helper.GetTables()); + result.Tables = tables; + result.deleteobj = this; + return result; + } + public SplitTableDeleteByObjectProvider SplitTable() + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + SplitTableDeleteByObjectProvider result = new SplitTableDeleteByObjectProvider(); + result.Context = this.Context; + Check.ExceptionEasy(this.DeleteObjects == null, "SplitTable() +0 only List can be deleted", "SplitTable()无参数重载只支持根据实体集合删除"); + result.deleteObjects = this.DeleteObjects.ToArray(); + SplitTableContext helper = new SplitTableContext((SqlSugarProvider)Context) + { + EntityInfo = this.EntityInfo + }; + result.deleteobj = this; + return result; + } + public LogicDeleteProvider IsLogic() + { + LogicDeleteProvider result = new LogicDeleteProvider(); + result.DeleteBuilder = this.DeleteBuilder; + result.Deleteable = this; + return result; + } + public IDeleteable RemoveDataCache(string likeString) + { + this.RemoveCacheFunc = () => + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + CacheSchemeMain.RemoveCacheByLike(cacheService, likeString); + }; + return this; + } + public IDeleteable In(List primaryKeyValues) + { + if (primaryKeyValues == null || primaryKeyValues.Count == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + return In(primaryKeyValues.ToArray()); + } + + public IDeleteable In(PkType[] primaryKeyValues) + { + if (primaryKeyValues == null || primaryKeyValues.Length == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + string tableName = this.Context.EntityMaintenance.GetTableName(); + string primaryField = null; + primaryField = GetPrimaryKeys().FirstOrDefault(); + Check.ArgumentNullException(primaryField, "Table " + tableName + " with no primarykey"); + if (primaryKeyValues.Length < 10000) + { + Where(string.Format(DeleteBuilder.WhereInTemplate, SqlBuilder.GetTranslationColumnName(primaryField), primaryKeyValues.ToJoinSqlInVals())); + } + else + { + if (DeleteBuilder.BigDataInValues == null) + DeleteBuilder.BigDataInValues = new List(); + DeleteBuilder.BigDataInValues.AddRange(primaryKeyValues.Select(it => (object)it)); + DeleteBuilder.BigDataFiled = primaryField; + } + return this; + } + + public IDeleteable In(PkType primaryKeyValue) + { + if (typeof(PkType).FullName.IsCollectionsList()) + { + var newValues = new List(); + foreach (var item in primaryKeyValue as IEnumerable) + { + newValues.Add(item); + } + return In(newValues); + } + + + In(new PkType[] { primaryKeyValue }); + return this; + } + + public IDeleteable In(Expression> inField, PkType primaryKeyValue) + { + var lamResult = DeleteBuilder.GetExpressionValue(inField, ResolveExpressType.FieldSingle); + var fieldName = lamResult.GetResultString(); + tempPrimaryKeys = new List() { fieldName }; + var result = In(primaryKeyValue); + tempPrimaryKeys = null; + return this; + } + public IDeleteable In(Expression> inField, PkType[] primaryKeyValues) + { + var lamResult = DeleteBuilder.GetExpressionValue(inField, ResolveExpressType.FieldSingle); + var fieldName = lamResult.GetResultString(); + tempPrimaryKeys = new List() { fieldName }; + var result = In(primaryKeyValues); + tempPrimaryKeys = null; + return this; + } + public IDeleteable In(Expression> inField, List primaryKeyValues) + { + var lamResult = DeleteBuilder.GetExpressionValue(inField, ResolveExpressType.FieldSingle); + var fieldName = lamResult.GetResultString(); + tempPrimaryKeys = new List() { fieldName }; + var result = In(primaryKeyValues); + tempPrimaryKeys = null; + return this; + } + + public IDeleteable In(Expression> inField, ISugarQueryable childQueryExpression) + { + var lamResult = DeleteBuilder.GetExpressionValue(inField, ResolveExpressType.FieldSingle); + var fieldName = lamResult.GetResultString(); + var sql = childQueryExpression.ToSql(); + Where($" {fieldName} IN ( SELECT {fieldName} FROM ( {sql.Key} ) SUBDEL) ", sql.Value); + return this; + } + public IDeleteable In(string inField, List primaryKeyValues) + { + tempPrimaryKeys = new List() { inField }; + var result = In(primaryKeyValues); + tempPrimaryKeys = null; + return this; + } + + public DeleteablePage PageSize(int pageSize) + { + Check.ExceptionEasy(this.DeleteObjects == null, "PageSize can only be deleted as a List entity collection", "Deleteable.PageSize()只能是List实体集合方式删除,并且集合不能为null"); + DeleteablePage result = new DeleteablePage(); + result.DataList = this.DeleteObjects.ToArray(); + result.Context = this.Context; + result.DiffModel = this.diffModel; + result.IsEnableDiffLogEvent = this.IsEnableDiffLogEvent; + result.TableName = this.DeleteBuilder.AsName; + result.PageSize = pageSize; + return result; + } + public IDeleteable With(string lockString) + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + DeleteBuilder.TableWithString = lockString; + return this; + } + public virtual string ToSqlString() + { + var sqlObj = this.ToSql(); + var result = sqlObj.Key; + if (result == null) return null; + result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig, sqlObj); + return result; + } + public KeyValuePair> ToSql() + { + DeleteBuilder.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + string sql = DeleteBuilder.ToSqlString(); + var paramters = DeleteBuilder.Parameters == null ? null : DeleteBuilder.Parameters.ToList(); + RestoreMapping(); + return new KeyValuePair>(sql, paramters); + } + + private List GetPrimaryKeys() + { + if (tempPrimaryKeys.HasValue()) + { + return tempPrimaryKeys; + } + else + { + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + } + private void _ExecuteCommand(out string sql, out SugarParameter[] paramters) + { + DeleteBuilder.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + sql = DeleteBuilder.ToSqlString(); + paramters = DeleteBuilder.Parameters == null ? null : DeleteBuilder.Parameters.ToArray(); + RestoreMapping(); + AutoRemoveDataCache(); + Before(sql); + } + + protected virtual List GetIdentityKeys() + { + + return this.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); + } + + private void RestoreMapping() + { + if (IsAs) + { + this.Context.MappingTables = OldMappingTableList; + } + } + + //private void TaskStart(Task result) + //{ + // if (this.Context.CurrentConnectionConfig.IsShardSameThread) + // { + // Check.Exception(true, "IsShardSameThread=true can't be used async method"); + // } + // result.Start(); + //} + + private void AutoRemoveDataCache() + { + var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (moreSetts?.IsAutoRemoveDataCache == true && extService?.DataInfoCacheService != null) + { + this.RemoveDataCache(); + } + } + + + protected virtual void After(string sql) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = DeleteBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.AfterData = null; + diffModel.Time = this.Context.Ado.SqlExecutionTime; + if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) + this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + if (this.RemoveCacheFunc != null) + { + this.RemoveCacheFunc(); + } + DataChangesAop(this.DeleteObjects); + } + + protected virtual void Before(string sql) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = DeleteBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.BeforeData = GetDiffTable(sql, parameters); + diffModel.Sql = sql; + diffModel.Parameters = parameters.ToArray(); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + } + + protected virtual List GetDiffTable(string sql, List parameters) + { + List result = new List(); + var whereSql = Regex.Replace(sql, ".* WHERE ", "", RegexOptions.Singleline); + var dt = this.Context.Queryable().AS(this.DeleteBuilder.AsName).Filter(null, true).Where(whereSql).AddParameters(parameters).ToDataTable(); + if (dt.Rows?.Count > 0) + { + foreach (DataRow row in dt.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt.Columns) + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; + addItem.ColumnDescription = sugarColumn.ColumnDescription; + item.Columns.Add(addItem); + } + result.Add(item); + } + } + return result; + } + protected virtual void DataAop(object deleteObj) + { + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (deleteObj != null && dataEvent != null) + { + var model = new DataFilterModel() + { + OperationType = DataFilterType.DeleteByObject, + EntityValue = deleteObj, + EntityColumnInfo = this.EntityInfo.Columns.FirstOrDefault() + }; + dataEvent(deleteObj, model); + } + } + protected virtual void DataChangesAop(List deleteObjs) + { + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataChangesExecuted; + if (dataEvent != null && deleteObjs != null) + { + foreach (var deleteObj in deleteObjs) + { + if (deleteObj != null) + { + var model = new DataFilterModel() + { + OperationType = DataFilterType.DeleteByObject, + EntityValue = deleteObj, + EntityColumnInfo = this.EntityInfo.Columns.FirstOrDefault() + }; + dataEvent(deleteObj, model); + } + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/LogicDeleteProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/LogicDeleteProvider.cs new file mode 100644 index 000000000..af8f06e75 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/LogicDeleteProvider.cs @@ -0,0 +1,162 @@ +namespace SqlSugar +{ + public class LogicDeleteProvider where T : class, new() + { + public DeleteableProvider Deleteable { get; set; } + public DeleteBuilder DeleteBuilder { get; set; } + public int ExecuteCommand(string LogicFieldName = null, object deleteValue = null, string deleteTimeFieldName = null) + { + ISqlSugarClient db; + List pars; + string where; + var isAutoDelFilter = + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true && + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoUpdateQueryFilter == true; + if (isAutoDelFilter) + { + DeleteBuilder.Context.CurrentConnectionConfig.MoreSettings.IsAutoUpdateQueryFilter = false; + } + LogicFieldName = _ExecuteCommand(LogicFieldName, out db, out where, out pars); + if (deleteValue == null) + { + deleteValue = true; + } + var updateable = db.Updateable().SetColumns(LogicFieldName, deleteValue); + if (deleteTimeFieldName != null) + { + updateable.SetColumns(deleteTimeFieldName, DateTime.Now); + } + if (pars != null) + updateable.UpdateBuilder.Parameters.AddRange(pars); + Convert(updateable as UpdateableProvider); + var result = updateable.Where(where).ExecuteCommand(); + if (isAutoDelFilter) + { + DeleteBuilder.Context.CurrentConnectionConfig.MoreSettings.IsAutoUpdateQueryFilter = true; + } + return result; + } + public int ExecuteCommand(string LogicFieldName, object deleteValue, string deleteTimeFieldName, string userNameFieldName, object userNameValue) + { + ISqlSugarClient db; + List pars; + string where; + var isAutoDelFilter = + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true && + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoUpdateQueryFilter == true; + if (isAutoDelFilter) + { + DeleteBuilder.Context.CurrentConnectionConfig.MoreSettings.IsAutoUpdateQueryFilter = false; + } + LogicFieldName = _ExecuteCommand(LogicFieldName, out db, out where, out pars); + var updateable = db.Updateable(); + updateable.UpdateBuilder.LambdaExpressions.ParameterIndex = 1000; + updateable.SetColumns(LogicFieldName, deleteValue); + updateable.SetColumns(deleteTimeFieldName, DateTime.Now); + updateable.SetColumns(userNameFieldName, userNameValue); + if (pars != null) + updateable.UpdateBuilder.Parameters.AddRange(pars); + Convert(updateable as UpdateableProvider); + var result = updateable.Where(where).ExecuteCommand(); + return result; + } + public async Task ExecuteCommandAsync(string LogicFieldName, object deleteValue, string deleteTimeFieldName, string userNameFieldName, object userNameValue) + { + ISqlSugarClient db; + List pars; + string where; + var isAutoDelFilter = + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true && + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoUpdateQueryFilter == true; + if (isAutoDelFilter) + { + DeleteBuilder.Context.CurrentConnectionConfig.MoreSettings.IsAutoUpdateQueryFilter = false; + } + LogicFieldName = _ExecuteCommand(LogicFieldName, out db, out where, out pars); + var updateable = db.Updateable(); + updateable.UpdateBuilder.LambdaExpressions.ParameterIndex = 1000; + updateable.SetColumns(LogicFieldName, deleteValue); + updateable.SetColumns(deleteTimeFieldName, DateTime.Now); + updateable.SetColumns(userNameFieldName, userNameValue); + if (pars != null) + updateable.UpdateBuilder.Parameters.AddRange(pars); + Convert(updateable as UpdateableProvider); + var result = await updateable.Where(where).ExecuteCommandAsync().ConfigureAwait(false); + return result; + } + public async Task ExecuteCommandAsync(string LogicFieldName = null, object deleteValue = null, string deleteTimeFieldName = null) + { + ISqlSugarClient db; + List pars; + string where; + var isAutoDelFilter = + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true && + DeleteBuilder.Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoUpdateQueryFilter == true; + if (isAutoDelFilter) + { + DeleteBuilder.Context.CurrentConnectionConfig.MoreSettings.IsAutoUpdateQueryFilter = false; + } + LogicFieldName = _ExecuteCommand(LogicFieldName, out db, out where, out pars); + if (deleteValue == null) + { + deleteValue = true; + } + var updateable = db.Updateable().SetColumns(LogicFieldName, deleteValue); + if (deleteTimeFieldName != null) + { + updateable.SetColumns(deleteTimeFieldName, DateTime.Now); + } + if (pars != null) + updateable.UpdateBuilder.Parameters.AddRange(pars); + Convert(updateable as UpdateableProvider); + var result = await updateable.Where(where).ExecuteCommandAsync().ConfigureAwait(false); + if (isAutoDelFilter) + { + DeleteBuilder.Context.CurrentConnectionConfig.MoreSettings.IsAutoUpdateQueryFilter = true; + } + return result; + } + + private void Convert(UpdateableProvider updateable) + { + updateable.IsEnableDiffLogEvent = Deleteable.IsEnableDiffLogEvent; + updateable.diffModel = Deleteable.diffModel; + updateable.UpdateBuilder.TableWithString = DeleteBuilder.TableWithString; + updateable.RemoveCacheFunc = Deleteable.RemoveCacheFunc; + } + + private string _ExecuteCommand(string LogicFieldName, out ISqlSugarClient db, out string where, out List pars) + { + var entityInfo = Deleteable.EntityInfo; + db = Deleteable.Context; + if (DeleteBuilder.BigDataInValues?.Count > 0) + { + var sql = db.Queryable().Select("1").AS(nameof(T)).In(DeleteBuilder.BigDataInValues.ToArray()).ToSqlString(); + var whereIndex = sql.IndexOf(" WHERE "); + var whereItem = sql.Substring(whereIndex + 7); + this.DeleteBuilder.WhereInfos.Add(whereItem); + } + + Check.ExceptionEasy(DeleteBuilder.GetWhereString == null, "Logical Delete requires a Where condition", "逻辑删除需要加Where条件"); + + where = DeleteBuilder.GetWhereString.Substring(5); + pars = DeleteBuilder.Parameters; + if (LogicFieldName.IsNullOrEmpty()) + { + var column = entityInfo.Columns.FirstOrDefault(it => + it.PropertyName.EqualCase("isdelete") || + it.PropertyName.EqualCase("isdeleted") || + it.DbColumnName.EqualCase("isdelete") || + it.DbColumnName.EqualCase("isdeleted")); + if (column != null) + { + LogicFieldName = column.DbColumnName; + } + } + Check.Exception(LogicFieldName == null, ErrorMessage.GetThrowMessage( + $"{entityInfo.EntityName} is not isdelete or isdeleted" + , $"{entityInfo.EntityName} 没有IsDelete或者IsDeleted 的属性, 你也可以用 IsLogic().ExecuteCommand(\"列名\")")); + return LogicFieldName; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/SplitTableDeleteByObjectProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/SplitTableDeleteByObjectProvider.cs new file mode 100644 index 000000000..18f4c3439 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/SplitTableDeleteByObjectProvider.cs @@ -0,0 +1,56 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class SplitTableDeleteByObjectProvider where T : class, new() + { + public ISqlSugarClient Context; + public DeleteableProvider deleteobj; + public T[] deleteObjects { get; set; } + + public int ExecuteCommand() + { + List groupModels; + int result; + GroupDataList(deleteObjects, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + result += this.Context.Deleteable().Where(addList).AS(item.Key).ExecuteCommand(); + } + return result; + } + public async Task ExecuteCommandAsync() + { + List groupModels; + int result; + GroupDataList(deleteObjects, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + result += await Context.Deleteable().Where(addList).AS(item.Key).ExecuteCommandAsync().ConfigureAwait(false); + } + return result; + } + + private void GroupDataList(T[] datas, out List groupModels, out int result) + { + var attribute = typeof(T).GetCustomAttribute() as SplitTableAttribute; + Check.Exception(attribute == null, $"{typeof(T).Name} need SplitTableAttribute"); + groupModels = new List(); + var db = this.Context; + foreach (var item in datas) + { + var value = db.SplitHelper().GetValue(attribute.SplitType, item); + var tableName = db.SplitHelper().GetTableName(attribute.SplitType, value); + groupModels.Add(new GroupModel() { GroupName = tableName, Item = item }); + } + result = 0; + } + internal class GroupModel + { + public string GroupName { get; set; } + public T Item { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/SplitTableDeleteProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/SplitTableDeleteProvider.cs new file mode 100644 index 000000000..1bf93a6db --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DeleteProvider/SplitTableDeleteProvider.cs @@ -0,0 +1,93 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SplitTableDeleteProvider where T : class, new() + { + public ISqlSugarClient Context; + public DeleteableProvider deleteobj; + + public IEnumerable Tables { get; set; } + public int ExecuteCommand() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = _ExecuteCommand(); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return _ExecuteCommand(); + } + } + public async Task ExecuteCommandAsync() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = await _ExecuteCommandAsync().ConfigureAwait(false); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return await _ExecuteCommandAsync().ConfigureAwait(false); + } + } + internal int _ExecuteCommand() + { + var result = 0; + var sqlobj = deleteobj.ToSql(); + + foreach (var item in Tables) + { + var newsqlobj = GetSqlObj(sqlobj, item.TableName); + result += this.Context.Ado.ExecuteCommand(newsqlobj.Key, newsqlobj.Value); + } + return result; + } + + internal async Task _ExecuteCommandAsync() + { + var result = 0; + var sqlobj = deleteobj.ToSql(); + foreach (var item in Tables) + { + var newsqlobj = GetSqlObj(sqlobj, item.TableName); + result += await Context.Ado.ExecuteCommandAsync(newsqlobj.Key, newsqlobj.Value).ConfigureAwait(false); + } + return result; + } + + private KeyValuePair> GetSqlObj(KeyValuePair> keyValuePair, string asName) + { + List pars = new List(); + string sql = keyValuePair.Key; + if (keyValuePair.Value != null) + { + pars = keyValuePair.Value.Select(it => new SugarParameter(it.ParameterName, it.Value)).ToList(); + } + sql = Regex.Replace(sql, deleteobj.EntityInfo.DbTableName, asName, RegexOptions.IgnoreCase); + return new KeyValuePair>(sql, pars); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/CommonMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/CommonMethodInfo.cs new file mode 100644 index 000000000..e359c956b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/CommonMethodInfo.cs @@ -0,0 +1,90 @@ +namespace SqlSugar +{ + public class CommonMethodInfo + { + internal object Context { get; set; } + + public int ExecuteReturnIdentity() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteReturnIdentity", 0).Invoke(Context, Array.Empty()); + return (int)result; + } + public async Task ExecuteReturnIdentityAsync() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteReturnIdentityAsync", 0).Invoke(Context, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public int ExecuteCommand() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteCommand", 0).Invoke(Context, Array.Empty()); + return (int)result; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(Context, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + } + public class SplitMethodInfo + { + internal object Context { get; set; } + + public int ExecuteCommand() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteCommand", 0).Invoke(Context, Array.Empty()); + return (int)result; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(Context, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + } + public class UpdateCommonMethodInfo + { + internal object Context { get; set; } + + public int ExecuteCommand() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteCommand", 0).Invoke(Context, Array.Empty()); + return (int)result; + } + public UpdateCommonMethodInfo WhereColumns(params string[] columns) + { + var result = Context.GetType().GetMyMethod("WhereColumns", 1, typeof(string[])).Invoke(Context, new object[] { columns }); + UpdateCommonMethodInfo updateCommonMethod = new UpdateCommonMethodInfo(); + updateCommonMethod.Context = result; + return updateCommonMethod; + } + public UpdateCommonMethodInfo UpdateColumns(params string[] columns) + { + var result = Context.GetType().GetMyMethod("UpdateColumns", 1, typeof(string[])).Invoke(Context, new object[] { columns }); + UpdateCommonMethodInfo updateCommonMethod = new UpdateCommonMethodInfo(); + updateCommonMethod.Context = result; + return updateCommonMethod; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var result = Context.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(Context, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public UpdateCommonMethodInfo SplitTable() + { + var newMethod = this.Context.GetType().GetMyMethod("SplitTable", 0); + var result = newMethod.Invoke(Context, Array.Empty()); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicBuilderHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicBuilderHelper.cs new file mode 100644 index 000000000..b571408b7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicBuilderHelper.cs @@ -0,0 +1,77 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace SqlSugar +{ + public static class DynamicBuilderHelper + { + public static Type CreateDynamicClass(string className, List properties, TypeAttributes attributes = TypeAttributes.Public, List classCustomAttributes = null, Type baseType = null, Type[] interfaces = null) + { + TypeBuilder typeBuilder = EmitTool.CreateTypeBuilder(className, attributes, baseType, interfaces); + + if (classCustomAttributes != null) + { + foreach (var attributeBuilder in classCustomAttributes) + { + typeBuilder.SetCustomAttribute(attributeBuilder); + } + } + + foreach (PropertyMetadata property in properties) + { + var type = property.Type; + if (type == typeof(DynamicOneselfType)) + { + type = typeBuilder; + } + else if (type == typeof(DynamicOneselfTypeList)) + { + type = typeof(List<>).MakeGenericType(typeBuilder); + } + EmitTool.CreateProperty(typeBuilder, property.Name, type, property.CustomAttributes); + } + + Type dynamicType = typeBuilder.CreateTypeInfo().AsType(); + + return dynamicType; + } + + public static Type CreateDynamicClass(TypeBuilder typeBuilder, TypeBuilder typeBuilderChild, List properties, List classCustomAttributes = null) + { + + if (classCustomAttributes != null) + { + foreach (var attributeBuilder in classCustomAttributes) + { + typeBuilder.SetCustomAttribute(attributeBuilder); + } + } + + foreach (PropertyMetadata property in properties) + { + var type = property.Type; + if (type == typeof(DynamicOneselfType)) + { + type = typeBuilder; + } + else if (type == typeof(DynamicOneselfTypeList)) + { + type = typeof(List<>).MakeGenericType(typeBuilder); + } + else if (type == typeof(NestedObjectType)) + { + type = typeBuilderChild; + } + else if (type == typeof(NestedObjectTypeList)) + { + type = typeof(List<>).MakeGenericType(typeBuilderChild); + } + EmitTool.CreateProperty(typeBuilder, property.Name, type, property.CustomAttributes); + } + + Type dynamicType = typeBuilder.CreateTypeInfo().AsType(); + + return dynamicType; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicOneselfType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicOneselfType.cs new file mode 100644 index 000000000..4a5c63111 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicOneselfType.cs @@ -0,0 +1,28 @@ +namespace SqlSugar +{ + /// + /// Dynamically construct Type, the property is self, with this type + /// + public class DynamicOneselfType + { + + } + /// + /// Dynamically construct Type, the property is List self , with this type + /// + public class DynamicOneselfTypeList + { + + } + + + public class NestedObjectType + { + + } + + public class NestedObjectTypeList + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicProperyBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicProperyBuilder.cs new file mode 100644 index 000000000..4474cd5fb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/DynamicProperyBuilder.cs @@ -0,0 +1,129 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace SqlSugar +{ + + public class DynamicProperyBuilder + { + private bool IsCache = false; + public static DynamicProperyBuilder CopyNew() + { + return new DynamicProperyBuilder(); + } + public DynamicBuilder baseBuilder; + public DynamicProperyBuilder CreateProperty(string propertyName, Type properyType, SugarColumn column = null, bool isSplitField = false, Navigate navigate = null) + { + if (column == null) + { + column = new SugarColumn() + { + ColumnName = propertyName + }; + } + PropertyMetadata addItem = new PropertyMetadata(); + addItem.Name = propertyName; + addItem.Type = properyType; + addItem.CustomAttributes = new List() { baseBuilder.GetProperty(column) }; + if (navigate != null) + { + addItem.CustomAttributes.Add(BuildNavigateAttribute(navigate)); + } + baseBuilder.propertyAttr.Add(addItem); + if (isSplitField) + { + addItem.CustomAttributes.Add(baseBuilder.GetSplitFieldAttr(new SplitFieldAttribute())); + } + return this; + } + public DynamicProperyBuilder WithCache(bool isCache = true) + { + IsCache = isCache; + return this; + } + public Type BuilderType() + { + if (IsCache) + { + var key = baseBuilder.entityName + string.Join("_", baseBuilder.propertyAttr.Select(it => it.Name + it.Type.Name)); + return new ReflectionInoCacheService().GetOrCreate(key, () => + { + var result = DynamicBuilderHelper.CreateDynamicClass(baseBuilder.entityName, baseBuilder.propertyAttr, TypeAttributes.Public, baseBuilder.entityAttr, baseBuilder.baseType, baseBuilder.interfaces); + return result; + }); + } + else + { + var result = DynamicBuilderHelper.CreateDynamicClass(baseBuilder.entityName, baseBuilder.propertyAttr, TypeAttributes.Public, baseBuilder.entityAttr, baseBuilder.baseType, baseBuilder.interfaces); + return result; + } + } + + #region BuilderTypes + public Tuple BuilderTypes(DynamicProperyBuilder dynamicBuilderB) + { + if (IsCache) + { + var key1 = baseBuilder.entityName + string.Join("_", baseBuilder.propertyAttr.Select(it => it.Name + it.Type.Name)); + var key2 = dynamicBuilderB.baseBuilder.entityName + string.Join("_", dynamicBuilderB.baseBuilder.propertyAttr.Select(it => it.Name + it.Type.Name)); + return new ReflectionInoCacheService().GetOrCreate(key1 + key2, () => + { + Tuple result = GetBuilderTypes(dynamicBuilderB); + return result; + }); + } + else + { + Tuple result = GetBuilderTypes(dynamicBuilderB); + return result; + } + } + private Tuple GetBuilderTypes(DynamicProperyBuilder dynamicBuilderB) + { + DynamicProperyBuilder dynamicBuilderA = this; + TypeBuilder typeBuilderA = EmitTool.CreateTypeBuilder(dynamicBuilderA.baseBuilder.entityName, TypeAttributes.Public, dynamicBuilderA.baseBuilder.baseType, dynamicBuilderA.baseBuilder.interfaces); + TypeBuilder typeBuilderB = EmitTool.CreateTypeBuilder(dynamicBuilderB.baseBuilder.entityName, TypeAttributes.Public, dynamicBuilderB.baseBuilder.baseType, dynamicBuilderB.baseBuilder.interfaces); + DynamicBuilderHelper.CreateDynamicClass(typeBuilderA, typeBuilderB, dynamicBuilderA.baseBuilder.propertyAttr, dynamicBuilderA.baseBuilder.entityAttr); + DynamicBuilderHelper.CreateDynamicClass(typeBuilderB, typeBuilderA, dynamicBuilderB.baseBuilder.propertyAttr, dynamicBuilderB.baseBuilder.entityAttr); + return new Tuple(typeBuilderB.CreateTypeInfo().AsType(), typeBuilderA.CreateTypeInfo().AsType()); + } + #endregion + + public CustomAttributeBuilder BuildNavigateAttribute(Navigate navigate) + { + NavigateType navigatType = navigate.NavigatType; + string name = navigate.Name; + string name2 = navigate.Name2; + string whereSql = navigate.WhereSql; + Type mappingTableType = navigate.MappingType; + string typeAiD = navigate.MappingAId; + string typeBId = navigate.MappingBId; + ConstructorInfo constructor; + object[] constructorArgs; + + if (mappingTableType != null && typeAiD != null && typeBId != null) + { + constructor = typeof(Navigate).GetConstructor(new Type[] { typeof(Type), typeof(string), typeof(string), typeof(string) }); + constructorArgs = new object[] { mappingTableType, typeAiD, typeBId, whereSql }; + } + else if (!string.IsNullOrEmpty(whereSql)) + { + constructor = typeof(Navigate).GetConstructor(new Type[] { typeof(NavigateType), typeof(string), typeof(string), typeof(string) }); + constructorArgs = new object[] { navigatType, name, name2, whereSql }; + } + else if (!string.IsNullOrEmpty(name2)) + { + constructor = typeof(Navigate).GetConstructor(new Type[] { typeof(NavigateType), typeof(string), typeof(string) }); + constructorArgs = new object[] { navigatType, name, name2 }; + } + else + { + constructor = typeof(Navigate).GetConstructor(new Type[] { typeof(NavigateType), typeof(string) }); + constructorArgs = new object[] { navigatType, name }; + } + + return new CustomAttributeBuilder(constructor, constructorArgs); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/EmitTool.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/EmitTool.cs new file mode 100644 index 000000000..3a36e3c7b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/EmitTool.cs @@ -0,0 +1,62 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace SqlSugar +{ + internal static class EmitTool + { + internal static ModuleBuilder CreateModuleBuilder() + { + AssemblyBuilder assemblyBuilder = CreateAssembly(); + ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule"); + return moduleBuilder; + } + + internal static AssemblyBuilder CreateAssembly() + { + AssemblyName assemblyName = new AssemblyName($"DynamicAssembly_{Guid.NewGuid():N}"); + AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect); + return assemblyBuilder; + } + + internal static TypeBuilder CreateTypeBuilder(string className, TypeAttributes attributes, Type baseType, Type[] interfaces) + { + ModuleBuilder moduleBuilder = EmitTool.CreateModuleBuilder(); + TypeBuilder typeBuilder = moduleBuilder.DefineType(className, attributes, baseType, interfaces); + return typeBuilder; + } + internal static PropertyBuilder CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType, IEnumerable propertyCustomAttributes = null) + { + FieldBuilder fieldBuilder = typeBuilder.DefineField($"_{propertyName}", propertyType, FieldAttributes.Private); + + PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null); + + MethodBuilder getterBuilder = typeBuilder.DefineMethod($"get_{propertyName}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); + ILGenerator getterIL = getterBuilder.GetILGenerator(); + getterIL.Emit(OpCodes.Ldarg_0); + getterIL.Emit(OpCodes.Ldfld, fieldBuilder); + getterIL.Emit(OpCodes.Ret); + + MethodBuilder setterBuilder = typeBuilder.DefineMethod($"set_{propertyName}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); + ILGenerator setterIL = setterBuilder.GetILGenerator(); + setterIL.Emit(OpCodes.Ldarg_0); + setterIL.Emit(OpCodes.Ldarg_1); + setterIL.Emit(OpCodes.Stfld, fieldBuilder); + setterIL.Emit(OpCodes.Ret); + + propertyBuilder.SetGetMethod(getterBuilder); + propertyBuilder.SetSetMethod(setterBuilder); + + if (propertyCustomAttributes != null) + { + foreach (var attributeBuilder in propertyCustomAttributes) + { + propertyBuilder.SetCustomAttribute(attributeBuilder); + } + } + + return propertyBuilder; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/Helper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/Helper.cs new file mode 100644 index 000000000..2b7f0e98e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/Helper.cs @@ -0,0 +1,115 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace SqlSugar +{ + public partial class DynamicBuilder + { + internal CustomAttributeBuilder GetSplitEntityAttr(SplitTableAttribute sugarTable) + { + Type attributeType = typeof(SplitTableAttribute); + ConstructorInfo attributeCtor = attributeType.GetConstructor(new Type[] { typeof(SplitType) }); + CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeCtor, new object[] { sugarTable.SplitType }, + new PropertyInfo[] { + attributeType.GetProperty(nameof(SplitTableAttribute.SplitType)), + } + , new object[] { + sugarTable.SplitType + }); + return attributeBuilder; + } + internal CustomAttributeBuilder GetSplitFieldAttr(SplitFieldAttribute fieldAttribute) + { + Type attributeType = typeof(SplitFieldAttribute); + ConstructorInfo attributeCtor = attributeType.GetConstructor(Array.Empty()); + CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeCtor, Array.Empty()); + return attributeBuilder; + } + internal CustomAttributeBuilder GetEntity(SugarTable sugarTable) + { + Type attributeType = typeof(SugarTable); + ConstructorInfo attributeCtor = attributeType.GetConstructor(new Type[] { typeof(string) }); + CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeCtor, new object[] { "" }, + new PropertyInfo[] { + attributeType.GetProperty(nameof(SugarTable.TableName)), + attributeType.GetProperty(nameof(SugarTable.TableDescription)) , + attributeType.GetProperty(nameof(SugarTable.IsDisabledUpdateAll)) , + attributeType.GetProperty(nameof(SugarTable.IsDisabledDelete)), + attributeType.GetProperty(nameof(SugarTable.IsCreateTableFiledSort)), + attributeType.GetProperty(nameof(SugarTable.Discrimator)) + } + , new object[] { + sugarTable.TableName, + sugarTable.TableDescription , + sugarTable.IsDisabledUpdateAll, + sugarTable.IsDisabledDelete, + sugarTable.IsCreateTableFiledSort, + sugarTable.Discrimator + }); + return attributeBuilder; + } + internal CustomAttributeBuilder GetProperty(SugarColumn sugarTable) + { + Type attributeType = typeof(SugarColumn); + ConstructorInfo attributeCtor = attributeType.GetConstructor(Array.Empty()); + CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeCtor, Array.Empty(), + new PropertyInfo[] { + attributeType.GetProperty(nameof(SugarColumn.IsPrimaryKey)), + attributeType.GetProperty(nameof(SugarColumn.IsIdentity)), + attributeType.GetProperty(nameof(SugarColumn.DefaultValue)), + attributeType.GetProperty(nameof(SugarColumn.Length)), + attributeType.GetProperty(nameof(SugarColumn.DecimalDigits)), + attributeType.GetProperty(nameof(SugarColumn.ColumnDataType)), + attributeType.GetProperty(nameof(SugarColumn.IsNullable)), + attributeType.GetProperty(nameof(SugarColumn.ColumnDescription)), + attributeType.GetProperty(nameof(SugarColumn.OracleSequenceName)), + attributeType.GetProperty(nameof(SugarColumn.IsIgnore)), + attributeType.GetProperty(nameof(SugarColumn.IsJson)), + attributeType.GetProperty(nameof(SugarColumn.IsOnlyIgnoreInsert)), + attributeType.GetProperty(nameof(SugarColumn.IsOnlyIgnoreUpdate)), + attributeType.GetProperty(nameof(SugarColumn.OldColumnName)), + attributeType.GetProperty(nameof(SugarColumn.SqlParameterDbType)), + attributeType.GetProperty(nameof(SugarColumn.SqlParameterSize)), + attributeType.GetProperty(nameof(SugarColumn.IsArray)), + attributeType.GetProperty(nameof(SugarColumn.ColumnName)), + attributeType.GetProperty(nameof(SugarColumn.InsertSql)), + attributeType.GetProperty(nameof(SugarColumn.UpdateSql)), + attributeType.GetProperty(nameof(SugarColumn.ExtendedAttribute)), + attributeType.GetProperty(nameof(SugarColumn.IsDisabledAlterColumn)), + attributeType.GetProperty(nameof(SugarColumn.IsOwnsOne)), + attributeType.GetProperty(nameof(SugarColumn.InsertServerTime)), + attributeType.GetProperty(nameof(SugarColumn.UpdateServerTime)), + attributeType.GetProperty(nameof(SugarColumn.QuerySql)) + } + , new object[] { + sugarTable.IsPrimaryKey, + sugarTable.IsIdentity, + sugarTable.DefaultValue, + sugarTable.Length, + sugarTable.DecimalDigits, + sugarTable.ColumnDataType, + sugarTable.IsNullable, + sugarTable.ColumnDescription, + sugarTable.OracleSequenceName, + sugarTable.IsIgnore, + sugarTable.IsJson, + sugarTable.IsOnlyIgnoreInsert, + sugarTable.IsOnlyIgnoreUpdate, + sugarTable.OldColumnName, + sugarTable.SqlParameterDbType, + sugarTable.SqlParameterSize, + sugarTable.IsArray, + sugarTable.ColumnName, + sugarTable.InsertSql, + sugarTable.UpdateSql, + sugarTable.ExtendedAttribute, + sugarTable.IsDisabledAlterColumn, + sugarTable.IsOwnsOne, + sugarTable.InsertServerTime, + sugarTable.UpdateServerTime, + sugarTable.QuerySql + }); + return attributeBuilder; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/Master.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/Master.cs new file mode 100644 index 000000000..af5883d00 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/DynamicBuilder/Master.cs @@ -0,0 +1,70 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace SqlSugar +{ + public partial class DynamicBuilder + { + internal List propertyAttr = new List(); + internal List entityAttr = new List(); + internal string entityName { get; set; } + internal Type baseType = null; + internal Type[] interfaces = null; + internal SqlSugarProvider context; + + public DynamicBuilder(SqlSugarProvider context) + { + this.context = context; + } + + public DynamicProperyBuilder CreateClass(string entityName, SugarTable table = null, Type baseType = null, Type[] interfaces = null, SplitTableAttribute splitTableAttribute = null) + { + this.baseType = baseType; + this.interfaces = interfaces; + this.entityName = entityName; + if (table == null) + { + table = new SugarTable() { TableName = entityName }; + } + this.entityAttr = new List() { GetEntity(table) }; + if (splitTableAttribute != null) + { + this.entityAttr.Add(GetSplitEntityAttr(splitTableAttribute)); + } + return new DynamicProperyBuilder() { baseBuilder = this }; + } + + public object CreateObjectByType(Type type, Dictionary dict) + { + // 创建一个默认的空对象 + object obj = Activator.CreateInstance(type); + + // 遍历字典中的每个 key-value 对 + foreach (KeyValuePair pair in dict) + { + // 获取对象中的属性 + PropertyInfo propertyInfo = type.GetProperty(pair.Key); + + if (propertyInfo == null) + { + propertyInfo = type.GetProperties().FirstOrDefault(it => it.Name.EqualCase(pair.Key)); + } + + propertyInfo?.SetValue(obj, UtilMethods.ChangeType2(pair.Value, propertyInfo.PropertyType)); + } + + // 返回创建的对象 + return obj; + } + + public List CreateObjectByType(Type type, List> dictList) + { + List result = new List(); + foreach (var item in dictList) + { + result.Add(CreateObjectByType(type, item)); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/EntityMaintenance/EntityColumnExtension.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/EntityMaintenance/EntityColumnExtension.cs new file mode 100644 index 000000000..2f34ffb88 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/EntityMaintenance/EntityColumnExtension.cs @@ -0,0 +1,63 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public static class EntityColumnExtension + { + public static EntityColumnable IfTable(this EntityColumnInfo entityColumnInfo) + { + EntityColumnable result = new EntityColumnable(); + result.entityColumnInfo = entityColumnInfo; + result.IsTable = entityColumnInfo.EntityName == typeof(T).Name; + return result; + } + } + + public class EntityColumnable + { + public EntityColumnInfo entityColumnInfo { get; set; } + + public bool IsTable { get; set; } + + public EntityColumnable UpdateProperty(Expression> propertyExpression, Action updateAction) + { + var name = ExpressionTool.GetMemberName(propertyExpression); + if (entityColumnInfo.PropertyName == name && IsTable) + { + updateAction(entityColumnInfo); + } + return this; + } + public EntityColumnable OneToOne(Expression> propertyExpression, string firstName, string lastName = null) + { + var name = ExpressionTool.GetMemberName(propertyExpression); + if (entityColumnInfo.PropertyName == name && IsTable) + { + entityColumnInfo.Navigat = new Navigate(NavigateType.OneToOne, firstName, lastName); + entityColumnInfo.IsIgnore = true; + } + return this; + } + public EntityColumnable OneToMany(Expression> propertyExpression, string firstName, string lastName) + { + var name = ExpressionTool.GetMemberName(propertyExpression); + if (entityColumnInfo.PropertyName == name && IsTable) + { + entityColumnInfo.Navigat = new Navigate(NavigateType.OneToMany, firstName, lastName); + entityColumnInfo.IsIgnore = true; + } + return this; + } + + public EntityColumnable ManyToMany(Expression> propertyExpression, Type mapppingType, string mapppingTypeAid, string mapppingTypeBid) + { + var name = ExpressionTool.GetMemberName(propertyExpression); + if (entityColumnInfo.PropertyName == name && IsTable) + { + entityColumnInfo.Navigat = new Navigate(mapppingType, mapppingTypeAid, mapppingTypeBid); + entityColumnInfo.IsIgnore = true; + } + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/EntityMaintenance/EntityMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/EntityMaintenance/EntityMaintenance.cs new file mode 100644 index 000000000..03869db56 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/EntityMaintenance/EntityMaintenance.cs @@ -0,0 +1,483 @@ +using SqlSugar.DbConvert; + +using System.Reflection; +using System.Xml.Linq; + +namespace SqlSugar +{ + public class EntityMaintenance + { + public SqlSugarProvider Context { get; set; } + + public EntityInfo GetEntityInfo() + { + return GetEntityInfo(typeof(T)); + } + public EntityInfo GetEntityInfoWithAttr(Type type) + { + return GetEntityInfo(type); + } + public EntityInfo GetEntityInfo(Type type) + { + var attr = type?.GetCustomAttribute(); + if (attr == null) + { + return _GetEntityInfo(type); + } + else if (attr.configId.ObjToString() == this.Context?.CurrentConnectionConfig?.ConfigId + "") + { + return _GetEntityInfo(type); + } + else if (this.Context.Root == null) + { + return _GetEntityInfo(type); + } + else if (!this.Context.Root.IsAnyConnection(attr.configId)) + { + return _GetEntityInfo(type); + } + else + { + return this.Context.Root.GetConnection(attr.configId).EntityMaintenance._GetEntityInfo(type); + } + } + + private EntityInfo _GetEntityInfo(Type type) + { + string cacheKey = "GetEntityInfo" + type.GetHashCode() + type.FullName + this.Context?.CurrentConnectionConfig?.ConfigId; + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + return GetEntityInfoNoCache(type); + }); + } + + public EntityInfo GetEntityInfoNoCache(Type type) + { + EntityInfo result = new EntityInfo(); + var sugarAttributeInfo = type.GetTypeInfo().GetCustomAttributes(typeof(SugarTable), false).Where(it => it is SugarTable).SingleOrDefault(); + if (sugarAttributeInfo.HasValue()) + { + var sugarTable = (SugarTable)sugarAttributeInfo; + result.DbTableName = sugarTable.TableName; + result.TableDescription = sugarTable.TableDescription.ToSqlFilter(); + result.IsDisabledUpdateAll = sugarTable.IsDisabledUpdateAll; + result.IsDisabledDelete = sugarTable.IsDisabledDelete; + result.IsCreateTableFiledSort = sugarTable.IsCreateTableFiledSort; + result.Discrimator = sugarTable.Discrimator; + } + var indexs = type.GetCustomAttributes(typeof(SugarIndexAttribute)); + if (indexs?.Any() == true) + { + result.Indexs = indexs.Select(it => it as SugarIndexAttribute).ToList(); + } + if (result.TableDescription.IsNullOrEmpty()) result.TableDescription = GetTableAnnotation(type); + if (this.Context.CurrentConnectionConfig.ConfigureExternalServices?.EntityNameService != null) + { + if (result.DbTableName == null) + { + result.DbTableName = type.Name; + } + this.Context.CurrentConnectionConfig.ConfigureExternalServices.EntityNameService(type, result); + } + result.Type = type; + result.EntityName = result.Type.Name; + result.Columns = new List(); + SetColumns(result); + return result; + } + + public string GetTableName() + { + return GetTableName(typeof(T)); + } + public string GetTableName(Type entityType) + { + var typeName = entityType.Name; + if (this.Context.MappingTables == null || this.Context.MappingTables.Count == 0 || !this.Context.MappingTables.Any(it => it.EntityName == typeName)) + { + var entity = this.GetEntityInfo(entityType); + if (entity.DbTableName.HasValue()) return entity.DbTableName; + else return entity.EntityName; + } + else + { + var mappingInfo = this.Context.MappingTables.SingleOrDefault(it => it.EntityName == typeName); + return mappingInfo == null ? typeName : mappingInfo.DbTableName; + } + } + public string GetTableName(string entityName) + { + var typeName = entityName; + if (this.Context.MappingTables == null || this.Context.MappingTables.Count == 0) return typeName; + else + { + var mappingInfo = this.Context.MappingTables.SingleOrDefault(it => it.EntityName == typeName); + return mappingInfo == null ? typeName : mappingInfo.DbTableName; + } + } + public string GetEntityName(string tableName) + { + if (this.Context.MappingTables == null || this.Context.MappingTables.Count == 0) return tableName; + else + { + var mappingInfo = this.Context.MappingTables.SingleOrDefault(it => it.DbTableName == tableName); + return mappingInfo == null ? tableName : mappingInfo.EntityName; + } + } + public string GetEntityName() + { + return this.Context.EntityMaintenance.GetEntityInfo().EntityName; + } + public string GetEntityName(Type type) + { + return this.Context.EntityMaintenance.GetEntityInfo(type).EntityName; + } + public string GetDbColumnName(string propertyName) + { + return GetDbColumnName(propertyName, typeof(T)); + } + public string GetDbColumnName(string propertyName, Type entityType) + { + var isAny = this.GetEntityInfo(entityType).Columns.Any(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + Check.Exception(!isAny, "Property " + propertyName + " is Invalid"); + var typeName = entityType.Name; + if (this.Context.MappingColumns == null || this.Context.MappingColumns.Count == 0 || !this.Context.MappingColumns.Any(it => it.EntityName == typeName && it.PropertyName == propertyName)) + { + var column = this.GetEntityInfo(entityType).Columns.First(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + if (column.DbColumnName.HasValue()) return column.DbColumnName; + else return column.PropertyName; + } + else + { + var mappingInfo = this.Context.MappingColumns.SingleOrDefault(it => it.EntityName == typeName && it.PropertyName == propertyName); + return mappingInfo == null ? propertyName : mappingInfo.DbColumnName; + } + } + public string GetPropertyName(string dbColumnName) + { + var columnInfo = this.Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(dbColumnName)); + if (columnInfo != null) + { + return columnInfo.PropertyName; + } + var typeName = typeof(T).Name; + if (this.Context.MappingColumns == null || this.Context.MappingColumns.Count == 0) return dbColumnName; + else + { + var mappingInfo = this.Context.MappingColumns.SingleOrDefault(it => it.EntityName == typeName && it.DbColumnName.Equals(dbColumnName, StringComparison.CurrentCultureIgnoreCase)); + return mappingInfo == null ? dbColumnName : mappingInfo.PropertyName; + } + } + public string GetPropertyName(string dbColumnName, Type entityType) + { + var columnInfo = this.Context.EntityMaintenance.GetEntityInfo(entityType).Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(dbColumnName)); + if (columnInfo != null) + { + return columnInfo.PropertyName; + } + var typeName = entityType.Name; + if (this.Context.MappingColumns == null || this.Context.MappingColumns.Count == 0) return dbColumnName; + else + { + var mappingInfo = this.Context.MappingColumns.SingleOrDefault(it => it.EntityName == typeName && it.DbColumnName.Equals(dbColumnName, StringComparison.CurrentCultureIgnoreCase)); + return mappingInfo == null ? dbColumnName : mappingInfo.PropertyName; + } + } + public PropertyInfo GetProperty(string dbColumnName) + { + var propertyName = GetPropertyName(dbColumnName); + return typeof(T).GetProperties().First(it => it.Name == propertyName); + } + /// + /// Gets the text contents of this XML element node + /// + /// entity type + /// The value of the name attribute of the XML node + /// the text contents of this XML element node + public string GetXElementNodeValue(Type entityType, string nodeAttributeName) + { + + try + { + + if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsNoReadXmlDescription == true) + { + return ""; + } + if (entityType.Assembly.IsDynamic && entityType.Assembly.FullName.StartsWith("Dynamic")) + { + return null; + } + if (entityType.Assembly.FullName.StartsWith("System.Linq.Dynamic.Core.DynamicClasses")) + { + return null; + } + var path = entityType.Assembly.Location; + if (string.IsNullOrEmpty(path)) + { + return null; + } + FileInfo file = new FileInfo(path); + string xmlPath = entityType.Assembly.Location.Replace(file.Extension, ".xml"); + if (!File.Exists(xmlPath)) + { + return string.Empty; + } + XElement xe = new ReflectionInoCacheService().GetOrCreate("EntityXml_" + xmlPath, () => XElement.Load(xmlPath)); + if (xe == null) + { + return string.Empty; + } + var xeNode = xe.Element("members").Elements("member").Where(ele => ele.Attribute("name").Value == nodeAttributeName).FirstOrDefault(); + if (xeNode == null) + { + return string.Empty; + } + var summary = xeNode.Element("summary"); + if (summary != null) + { + return summary.Value.ToSqlFilter().Trim(); + } + else + { + var summaryValue = xeNode.Elements().Where(x => x.Name.ToString().EqualCase("summary")).Select(it => it.Value).FirstOrDefault(); + if (summaryValue == null) + return string.Empty; + else + return summaryValue.ToSqlFilter().Trim() ?? ""; + } + + } + catch + { + Check.ExceptionEasy("ORM error reading entity class XML, check entity XML or disable reading XML: MoreSettings IsNoReadXmlDescription set to true (same place to set DbType)", "ORM读取实体类的XML出现错误,检查实体XML或者禁用读取XML: MoreSettings里面的IsNoReadXmlDescription设为true (设置DbType的同一个地方)"); + throw; + } + } + /// + /// Gets the code annotation for the database table + /// + /// entity type + /// the code annotation for the database table + public string GetTableAnnotation(Type entityType) + { + if (entityType.IsClass() == false) + { + return null; + } + var result = GetXElementNodeValue(entityType, $"T:{entityType.FullName}"); + if (string.IsNullOrEmpty(result)) + { + return null; + } + else + { + return result; + } + } + /// + /// Gets the code annotation for the field + /// + /// entity type + /// column name + /// the code annotation for the field + public string GetPropertyAnnotation(Type entityType, string dbColumnName) + { + if (entityType.IsClass() == false || entityType == typeof(object)) + { + return null; + } + + var result = GetXElementNodeValue(entityType, $"P:{entityType.FullName}.{dbColumnName}"); + if (string.IsNullOrEmpty(result)) + { + return GetPropertyAnnotation(entityType.BaseType, dbColumnName); + } + else + { + return result; + } + } + + #region Primary key + private void SetColumns(EntityInfo result) + { + foreach (var property in result.Type.GetProperties()) + { + EntityColumnInfo column = new EntityColumnInfo(); + //var isVirtual = property.GetGetMethod().IsVirtual; + //if (isVirtual) continue; + var navigat = property.GetCustomAttribute(typeof(Navigate)); + if (navigat != null) + { + column.IsIgnore = true; + column.Navigat = navigat as Navigate; + } + var sugarColumn = property.GetCustomAttributes(typeof(SugarColumn), true) + .Where(it => it is SugarColumn) + .Select(it => (SugarColumn)it) + .FirstOrDefault(); + column.ExtendedAttribute = sugarColumn?.ExtendedAttribute; + column.DbTableName = result.DbTableName; + column.EntityName = result.EntityName; + column.PropertyName = property.Name; + column.PropertyInfo = property; + column.UnderType = UtilMethods.GetUnderType(column.PropertyInfo.PropertyType); + if (sugarColumn?.IsOwnsOne == true) + { + SetValueObjectColumns(result, property, column); + } + if (sugarColumn.IsNullOrEmpty()) + { + column.DbColumnName = property.Name; + } + else + { + + if (sugarColumn.IsIgnore == false) + { + column.DbColumnName = sugarColumn.ColumnName.IsNullOrEmpty() ? property.Name : sugarColumn.ColumnName; + column.IsPrimarykey = sugarColumn.IsPrimaryKey; + column.IsIdentity = sugarColumn.IsIdentity; + column.ColumnDescription = sugarColumn.ColumnDescription.ToSqlFilter(); + column.IsNullable = sugarColumn.IsNullable; + column.Length = sugarColumn.Length; + column.OldDbColumnName = sugarColumn.OldColumnName; + column.DataType = sugarColumn.ColumnDataType; + column.DecimalDigits = sugarColumn.DecimalDigits; + column.OracleSequenceName = sugarColumn.OracleSequenceName; + column.IsOnlyIgnoreInsert = sugarColumn.IsOnlyIgnoreInsert; + column.IsEnableUpdateVersionValidation = sugarColumn.IsEnableUpdateVersionValidation; + column.IsTranscoding = sugarColumn.IsTranscoding; + column.SerializeDateTimeFormat = sugarColumn.SerializeDateTimeFormat; + column.IsJson = sugarColumn.IsJson; + column.NoSerialize = sugarColumn.NoSerialize; + column.DefaultValue = sugarColumn.DefaultValue; + column.IndexGroupNameList = sugarColumn.IndexGroupNameList; + column.UIndexGroupNameList = sugarColumn.UniqueGroupNameList; + column.IsOnlyIgnoreUpdate = sugarColumn.IsOnlyIgnoreUpdate; + column.IsArray = sugarColumn.IsArray; + column.IsTreeKey = sugarColumn.IsTreeKey; + column.SqlParameterDbType = sugarColumn.SqlParameterDbType; + column.SqlParameterSize = sugarColumn.SqlParameterSize; + column.CreateTableFieldSort = sugarColumn.CreateTableFieldSort; + column.InsertServerTime = sugarColumn.InsertServerTime; + column.InsertSql = sugarColumn.InsertSql; + column.UpdateServerTime = sugarColumn.UpdateServerTime; + column.UpdateSql = sugarColumn.UpdateSql; + column.IsDisabledAlterColumn = sugarColumn.IsDisabledAlterColumn; + column.QuerySql = sugarColumn.QuerySql; + if (sugarColumn.IsJson && String.IsNullOrEmpty(sugarColumn.ColumnDataType)) + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + column.DataType = "json"; + } + else if (column.Length > 0) + { + column.DataType = "varchar"; + } + else + { + column.DataType = "varchar(4000)"; + } + } + else if (typeof(Nvarchar2PropertyConvert).Equals(sugarColumn.SqlParameterDbType) && column.DataType == null) + { + column.DataType = "nvarchar2"; + if (column.Length == 0) + { + column.Length = 200; + } + } + if (column.IsPrimarykey && column.IsOnlyIgnoreUpdate) + { + column.IsOnlyIgnoreUpdate = false; + } + } + else + { + column.IsIgnore = true; + column.NoSerialize = sugarColumn.NoSerialize; + column.ColumnDescription = sugarColumn.ColumnDescription; + column.IsJson = sugarColumn.IsJson; + column.IsArray = sugarColumn.IsArray; + } + } + if (column.ColumnDescription.IsNullOrEmpty()) column.ColumnDescription = GetPropertyAnnotation(result.Type, column.PropertyName); + if (this.Context.MappingColumns.HasValue()) + { + var golbalMappingInfo = this.Context.MappingColumns.FirstOrDefault(it => it.EntityName.Equals(result.EntityName, StringComparison.CurrentCultureIgnoreCase) && it.PropertyName == column.PropertyName); + if (golbalMappingInfo != null) + column.DbColumnName = golbalMappingInfo.DbColumnName; + } + if (this.Context.IgnoreColumns.HasValue()) + { + var golbalMappingInfo = this.Context.IgnoreColumns.FirstOrDefault(it => it.EntityName.Equals(result.EntityName, StringComparison.CurrentCultureIgnoreCase) && it.PropertyName == column.PropertyName); + if (golbalMappingInfo != null) + column.IsIgnore = true; + } + if (this.Context.CurrentConnectionConfig.ConfigureExternalServices?.EntityService != null) + { + if (!column.EntityName.ObjToString().StartsWith("<>f__AnonymousType") + && column.PropertyInfo?.ReflectedType != typeof(DbTableInfo)) + { + var isOldOwnsOne = column.IsOwnsOne; + this.Context.CurrentConnectionConfig.ConfigureExternalServices.EntityService(property, column); + if (column.IsOwnsOne == true && isOldOwnsOne == false) + { + SetValueObjectColumns(result, property, column); + continue; + } + } + } + if (column.PropertyInfo.DeclaringType != null + && column.PropertyInfo.DeclaringType != result.Type + && result.Columns.Any(x => x.PropertyName == column.PropertyName)) + { + continue; + } + if (column.DataType == null && property?.PropertyType.Name.IsIn("TimeOnly") == true) + { + column.DataType = "time"; + } + if (column.DataType == null && property?.PropertyType.Name.IsIn("DateOnly") == true) + { + column.DataType = "date"; + } + if (column.DataType == null && column.UnderType == typeof(TimeSpan)) + { + column.DataType = "time"; + column.Length = 0; + column.DecimalDigits = 0; + } + if (column.OracleSequenceName.HasValue() && + this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true) + { + column.OracleSequenceName = null; + } + result.Columns.Add(column); + } + } + + private void SetValueObjectColumns(EntityInfo result, PropertyInfo property, EntityColumnInfo column) + { + column.IsIgnore = true; + column.IsOwnsOne = true; + Check.ExceptionEasy(property.PropertyType.IsClass() == false, column.PropertyName + " IsOwnsOne必须用在类上面", column.PropertyName + "IsOwnsOne must be used on the class"); + Check.ExceptionEasy(property.PropertyType.FullName.IsCollectionsList() == true, column.PropertyName + " IsOwnsOne必须用在类上面", column.PropertyName + "IsOwnsOne must be used on the class"); + var ownsOne = this.GetEntityInfoNoCache(property.PropertyType); + foreach (var item in ownsOne.Columns) + { + if (result.Columns.Any(it => it.PropertyName.EqualCase(item.PropertyName) || it.DbColumnName.EqualCase(item.DbColumnName))) + { + Check.ExceptionEasy($" {result.EntityName} " + item.PropertyName + " 存在重复定义 (IsOwnsOne) ", $" {result.EntityName} " + item.PropertyName + " Duplicate definition exists (IsOwnsOne)"); + } + item.ForOwnsOnePropertyInfo = column.PropertyInfo; + result.Columns.Add(item); + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavManyToMany.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavManyToMany.cs new file mode 100644 index 000000000..f725bd57b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavManyToMany.cs @@ -0,0 +1,81 @@ +namespace SqlSugar +{ + public partial class DeleteNavProvider where T : class, new() where Root : class, new() + { + private void DeleteManyToMany(string name, EntityColumnInfo nav) where TChild : class, new() + { + var parentEntity = _ParentEntity; + var parentList = _ParentList.Cast().ToList(); + var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + Check.ExceptionEasy(thisPkColumn == null, $"{thisPkColumn.EntityName} need primary key", $"{thisPkColumn.EntityName}需要主键"); + Check.ExceptionEasy(parentPkColumn == null, $"{parentPkColumn.EntityName} need primary key", $"{parentPkColumn.EntityName}需要主键"); + var mappingType = parentNavigateProperty.Navigat.MappingType; + var mappingEntity = this._Context.EntityMaintenance.GetEntityInfo(mappingType); + var mappingA = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingAId); + var mappingB = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingBId); + Check.ExceptionEasy(mappingA == null || mappingB == null, $"Navigate property {name} error ", $"导航属性{name}配置错误"); + var mappingPk = mappingEntity.Columns + .Where(it => it.PropertyName != mappingA.PropertyName) + .Where(it => it.PropertyName != mappingB.PropertyName) + .Where(it => it.IsPrimarykey && !it.IsIdentity && it.OracleSequenceName.IsNullOrEmpty()).FirstOrDefault(); + + if (IsDeleteA()) + { + if (!_IsDeletedParant) + SetContext(() => this._Context.Deleteable(parentList) + .EnableDiffLogEventIF(_RootOptions?.IsDiffLogEvent == true, _RootOptions?.DiffLogBizData) + .ExecuteCommand()); + } + + var aids = _ParentList.Select(it => parentPkColumn.PropertyInfo.GetValue(it)).ToList(); + var bids = _Context.Queryable().Filter(mappingEntity.Type).AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, aids) + .Select(mappingB.DbColumnName).ToDataTable() + .Rows.Cast().Select(it => it[0]).ToList(); + + + var childList = GetChildList().In(thisPkColumn.DbColumnName, bids).ToList(); + if (_WhereList.HasValue()) + { + bids = childList.Select(it => thisPkColumn.PropertyInfo.GetValue(it)).ToList(); + } + + + if (IsDeleteB()) + { + SetContext(() => _Context.Deleteable(childList).ExecuteCommand()); + } + + this._ParentList = childList.Cast().ToList(); + this._ParentPkColumn = thisPkColumn; + this._IsDeletedParant = true; + + + if (_WhereList.HasValue()) + { + SetContext(() => _Context.Deleteable().AS(mappingEntity.DbTableName) + .In(mappingA.DbColumnName, aids) + .In(mappingB.DbColumnName, bids) + .ExecuteCommand()); + } + else + { + SetContext(() => _Context.Deleteable().AS(mappingEntity.DbTableName).In( + mappingA.DbColumnName, aids + ).ExecuteCommand()); + } + + } + + private bool IsDeleteA() + { + return deleteNavOptions?.ManyToManyIsDeleteA == true; + } + private bool IsDeleteB() + { + return deleteNavOptions?.ManyToManyIsDeleteB == true; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavOneToMany.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavOneToMany.cs new file mode 100644 index 000000000..52e0bcd82 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavOneToMany.cs @@ -0,0 +1,106 @@ +namespace SqlSugar +{ + public partial class DeleteNavProvider where T : class, new() where Root : class, new() + { + + private void DeleteOneToMany(string name, EntityColumnInfo nav) where TChild : class, new() + { + var parentEntity = _ParentEntity; + var prentList = _ParentList.Cast().ToList(); + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = GetPkColumnByNav(thisEntity, nav); + var thisFkColumn = GetFKColumnByNav(thisEntity, nav); + EntityColumnInfo parentPkColumn = GetParentPkColumn(); + EntityColumnInfo parentNavColumn = GetParentPkNavColumn(nav); + if (parentNavColumn != null) + { + parentPkColumn = parentNavColumn; + } + + if (!_IsDeletedParant) + SetContext(() => this._Context.Deleteable(prentList) + .EnableDiffLogEventIF(_RootOptions?.IsDiffLogEvent == true, _RootOptions?.DiffLogBizData) + .ExecuteCommand()); + + var ids = _ParentList.Select(it => parentPkColumn.PropertyInfo.GetValue(it)).ToList(); + var childList = GetChildList().In(thisFkColumn.DbColumnName, ids).ToList(); + + this._ParentList = childList.Cast().ToList(); + this._ParentPkColumn = thisPkColumn; + this._IsDeletedParant = true; + + SetContext(() => this._Context.Deleteable(childList).ExecuteCommand()); + } + + private ISugarQueryable GetChildList() where TChild : class, new() + { + var queryable = this._Context.Queryable(); + if (_WhereList.HasValue()) + { + foreach (var item in _WhereList) + { + queryable.Where(item); + } + queryable.AddParameters(_Parameters); + } + return queryable; + } + + private void SetContext(Action action) + { + var key = "_DeleteNavTask"; + if (this._Context.TempItems == null) + { + this._Context.TempItems = new Dictionary(); + } + if (!this._Context.TempItems.TryGetValue(key, out object? oldTask)) + { + oldTask = null; + this._Context.TempItems.Add(key, oldTask); + } + + var newTask = new List(); + if (oldTask != null) + { + newTask = (List)oldTask; + } + newTask.Add(action); + this._Context.TempItems[key] = newTask; + } + + private EntityColumnInfo GetParentPkColumn() + { + EntityColumnInfo parentPkColumn = _ParentPkColumn; + if (_ParentPkColumn == null) + { + parentPkColumn = _ParentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + return parentPkColumn; + } + private EntityColumnInfo GetParentPkNavColumn(EntityColumnInfo nav) + { + EntityColumnInfo result = null; + if (nav.Navigat.Name2.HasValue()) + { + result = _ParentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + } + return result; + } + + private EntityColumnInfo GetPkColumnByNav(EntityInfo entity, EntityColumnInfo nav) + { + var pkColumn = entity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + if (nav.Navigat.Name2.HasValue()) + { + pkColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + } + return pkColumn; + } + private EntityColumnInfo GetFKColumnByNav(EntityInfo entity, EntityColumnInfo nav) + { + var fkColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + return fkColumn; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavOneToOne.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavOneToOne.cs new file mode 100644 index 000000000..8174a1a78 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavOneToOne.cs @@ -0,0 +1,33 @@ +namespace SqlSugar +{ + public partial class DeleteNavProvider where T : class, new() where Root : class, new() + { + private void DeleteOneToOne(string name, EntityColumnInfo nav) where TChild : class, new() + { + var parentEntity = _ParentEntity; + var parentList = _ParentList.Cast().ToList(); + var parentColumn = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + EntityColumnInfo thisPkColumn = GetPkColumnByNav(thisEntity, nav); + Check.Exception(thisPkColumn == null, $" Navigate {parentEntity.EntityName} : {name} is error ", $"导航实体 {parentEntity.EntityName} 属性 {name} 配置错误"); + + + if (!_IsDeletedParant) + SetContext(() => this._Context.Deleteable(parentList) + .EnableDiffLogEventIF(_RootOptions?.IsDiffLogEvent == true, _RootOptions?.DiffLogBizData) + .ExecuteCommand()); + + Check.ExceptionEasy(parentColumn == null, "The one-to-one navigation configuration is incorrect", "一对一导航配置错误"); + var ids = _ParentList.Select(it => parentColumn.PropertyInfo.GetValue(it)).ToList(); + List childList = this._Context.Queryable().In(thisPkColumn.DbColumnName, ids).ToList(); + + this._ParentList = childList.Cast().ToList(); + this._ParentPkColumn = thisPkColumn; + this._IsDeletedParant = true; + + SetContext(() => this._Context.Deleteable(childList).ExecuteCommand()); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavProvider.cs new file mode 100644 index 000000000..f091bf81e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavProvider.cs @@ -0,0 +1,167 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class DeleteNavProvider where T : class, new() where Root : class, new() + { + internal DeleteNavOptions deleteNavOptions; + public List _Roots { get; set; } + public List _ParentList { get; set; } + public List _RootList { get; set; } + public EntityInfo _ParentEntity { get; set; } + public EntityColumnInfo _ParentPkColumn { get; set; } + public SqlSugarProvider _Context { get; set; } + internal DeleteNavRootOptions _RootOptions { get; set; } + public bool _IsDeletedParant { get; set; } + public List _WhereList = new List(); + public List _Parameters = new List(); + public DeleteNavProvider ThenInclude(Expression> expression) + where TChild : class, new() + { + this._Context.InitMappingInfo(); + InitParentList(); + Expression newExp = GetMamber(expression); + var name = ExpressionTool.GetMemberName(expression); + var nav = this._ParentEntity.Columns.FirstOrDefault(x => x.PropertyName == name); + if (nav.Navigat == null) + { + Check.ExceptionEasy($"{name} no navigate attribute", $"{this._ParentEntity.EntityName}的属性{name}没有导航属性"); + } + if (nav.Navigat.NavigatType == NavigateType.OneToOne || nav.Navigat.NavigatType == NavigateType.ManyToOne) + { + DeleteOneToOne(name, nav); + } + else if (nav.Navigat.NavigatType == NavigateType.OneToMany) + { + DeleteOneToMany(name, nav); + } + else + { + DeleteManyToMany(name, nav); + } + return GetResult(); + } + + public DeleteNavProvider ThenInclude(Expression>> expression) + where TChild : class, new() + { + this._Context.InitMappingInfo(); + InitParentList(); + Expression newExp = GetMamber(expression); + var name = ExpressionTool.GetMemberName(newExp); + var nav = this._ParentEntity.Columns.FirstOrDefault(x => x.PropertyName == name); + if (nav.Navigat == null) + { + Check.ExceptionEasy($"{name} no navigate attribute", $"{this._ParentEntity.EntityName}的属性{name}没有导航属性"); + } + if (nav.Navigat.NavigatType == NavigateType.OneToOne || nav.Navigat.NavigatType == NavigateType.ManyToOne) + { + DeleteOneToOne(name, nav); + } + else if (nav.Navigat.NavigatType == NavigateType.OneToMany) + { + DeleteOneToMany(name, nav); + } + else + { + DeleteManyToMany(name, nav); + } + return GetResult(); + } + + private Expression GetMamber(Expression expression) + { + int i = 0; + Expression newExp = ExpressionTool.GetLambdaExpressionBody(expression); + while (newExp is MethodCallExpression) + { + var callMethod = (newExp as MethodCallExpression); + ActionMethodCallExpression(callMethod); + newExp = callMethod.Arguments[0]; + i++; + Check.Exception(i > 10000, expression + " is error"); + } + return newExp; + } + + + private void ActionMethodCallExpression(MethodCallExpression method) + { + var queryBuilder = GetQueryBuilder(); + NavigatManager navigatManager = new NavigatManager() + { + Context = this._Context + }; + if (method.Method.Name == "ToList") + { + + } + else if (method.Method.Name == "Where") + { + navigatManager.CheckHasRootShortName(method.Arguments[0], method.Arguments[1]); + var exp = method.Arguments[1]; + _WhereList.Add(" " + queryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()); + } + else if (method.Method.Name == "WhereIF") + { + var isOk = LambdaExpression.Lambda(method.Arguments[1]).Compile().DynamicInvoke(); + if (isOk.ObjToBool()) + { + var exp = method.Arguments[2]; + navigatManager.CheckHasRootShortName(method.Arguments[1], method.Arguments[2]); + _WhereList.Add(" " + queryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()); + } + } + if (queryBuilder.Parameters != null) + { + _Parameters.AddRange(queryBuilder.Parameters); + } + } + + private QueryBuilder GetQueryBuilder() + { + return this._Context.Queryable().QueryBuilder; + } + + private DeleteNavProvider GetResult() where TChild : class, new() + { + return new DeleteNavProvider() + { + _Context = this._Context, + _ParentEntity = this._ParentEntity, + _ParentList = this._ParentList, + _Roots = this._Roots, + _ParentPkColumn = this._ParentPkColumn, + _RootList = this._RootList, + _IsDeletedParant = this._IsDeletedParant + }; + } + public DeleteNavProvider AsNav() + { + return new DeleteNavProvider + { + _Context = _Context, + _ParentEntity = null, + _ParentList = null, + _Roots = _Roots, + _IsDeletedParant = this._IsDeletedParant, + _ParentPkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.First(it => it.IsPrimarykey) + }; + } + private void InitParentList() + { + this._ParentEntity = this._Context.EntityMaintenance.GetEntityInfo(); + if (_RootList == null) + { + _RootList = _ParentList = _Roots.Cast().ToList(); + } + else if (_ParentList == null) + { + _ParentList = _RootList; + var pkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(it => it.IsPrimarykey); + this._ParentPkColumn = pkColumn; + } + + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavTask.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavTask.cs new file mode 100644 index 000000000..910abaee3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/DeleteNavTask.cs @@ -0,0 +1,175 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class DeleteNavTaskInit where T : class, new() where Root : class, new() + { + internal List Roots { get; set; } + internal SqlSugarProvider Context { get; set; } + internal DeleteNavProvider deleteNavProvider { get; set; } + public DeleteNavMethodInfo IncludesAllFirstLayer(params string[] ignoreColumns) + { + if (ignoreColumns == null) + { + ignoreColumns = Array.Empty(); + } + this.Context = deleteNavProvider._Context; + var navColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !ignoreColumns.Contains(it.PropertyName) || !ignoreColumns.Any(z => z.EqualCase(it.DbColumnName))).Where(it => it.Navigat != null).ToList(); + var updateNavs = this; + DeleteNavMethodInfo methodInfo = updateNavs.IncludeByNameString(navColumns[0].PropertyName); + foreach (var item in navColumns.Skip(1)) + { + methodInfo = methodInfo.IncludeByNameString(item.PropertyName); + } + return methodInfo; + } + public DeleteNavTask Include(Expression> expression) where TChild : class, new() + { + this.Context = deleteNavProvider._Context; + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => deleteNavProvider.ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public DeleteNavMethodInfo IncludeByNameString(string navMemberName, DeleteNavOptions deleteNavOptions = null) + { + DeleteNavMethodInfo result = new DeleteNavMethodInfo(); + result.Context = deleteNavProvider._Context; + var entityInfo = result.Context.EntityMaintenance.GetEntityInfo(); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.GetType().GetMyMethod("Include", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this, new object[] { exp, deleteNavOptions }); + result.MethodInfos = obj; + return result; + } + public DeleteNavTask Include(Expression>> expression) where TChild : class, new() + { + this.Context = deleteNavProvider._Context; + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => deleteNavProvider.ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public DeleteNavTask Include(Expression>> expression, DeleteNavOptions deleteNavOptions) where TChild : class, new() + { + var result = Include(expression); + deleteNavProvider.deleteNavOptions = deleteNavOptions; + return result; + } + } + public class DeleteNavTask where T : class, new() where Root : class, new() + { + public SqlSugarProvider Context { get; set; } + public Func> PreFunc { get; set; } + public DeleteNavTask ThenInclude(Expression> expression) where TChild : class, new() + { + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => PreFunc().ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public DeleteNavTask ThenInclude(Expression> expression, DeleteNavOptions deleteNavOptions) where TChild : class, new() + { + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => + { + var dev = PreFunc(); + dev.deleteNavOptions = deleteNavOptions; + return dev.ThenInclude(expression); + }; + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public DeleteNavTask ThenInclude(Expression>> expression) where TChild : class, new() + { + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => PreFunc().ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public DeleteNavTask ThenInclude(Expression>> expression, DeleteNavOptions deleteNavOptions) where TChild : class, new() + { + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => + { + var dev = PreFunc(); + dev.deleteNavOptions = deleteNavOptions; + return dev.ThenInclude(expression); + }; + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public DeleteNavTask Include(Expression> expression) where TChild : class, new() + { + return AsNav().ThenInclude(expression); + } + public DeleteNavTask Include(Expression> expression, DeleteNavOptions options) where TChild : class, new() + { + return AsNav().ThenInclude(expression, options); + } + public DeleteNavTask Include(Expression>> expression) where TChild : class, new() + { + return AsNav().ThenInclude(expression); + } + public DeleteNavTask Include(Expression>> expression, DeleteNavOptions options) where TChild : class, new() + { + return AsNav().ThenInclude(expression, options); + } + public bool ExecuteCommand() + { + PreFunc(); + + var hasTran = this.Context.Ado.Transaction != null; + if (hasTran) + { + ExecTasks(); + } + else + { + this.Context.Ado.UseTran(() => + { + ExecTasks(); + + }, ex => throw ex); + } + return true; + } + public async Task ExecuteCommandAsync() + { + await Task.Run(async () => + { + ExecuteCommand(); + await Task.Delay(0).ConfigureAwait(false); + }).ConfigureAwait(false); + return true; + } + + private DeleteNavTask AsNav() + { + DeleteNavTask result = new DeleteNavTask(); + Func> func = () => PreFunc().AsNav(); + result.PreFunc = func; + result.Context = this.Context; + return result; + } + private void ExecTasks() + { + var tasks = (List)this.Context.TempItems["_DeleteNavTask"]; + tasks.Reverse(); + foreach (var task in tasks) + { + task(); + } + this.Context.TempItems.Remove("_DeleteNavTask"); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProvider.cs new file mode 100644 index 000000000..7c39cde97 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProvider.cs @@ -0,0 +1,145 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class InsertNavProvider where T : class, new() where Root : class, new() + { + public InsertNavRootOptions _RootOptions { get; set; } + public List _Roots { get; set; } + public List _ParentList { get; set; } + public List _RootList { get; set; } + public EntityInfo _ParentEntity { get; set; } + public EntityColumnInfo _ParentPkColumn { get; set; } + public SqlSugarProvider _Context { get; set; } + public NavigateType? _NavigateType { get; set; } + public bool IsFirst { get; set; } + public InsertNavOptions _navOptions { get; set; } + public bool IsNav { get; internal set; } + internal NavContext NavContext { get; set; } + + public InsertNavProvider AsNav() + { + return new InsertNavProvider + { + _Context = _Context, + _ParentEntity = null, + _ParentList = null, + _Roots = _Roots, + _ParentPkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.First(it => it.IsPrimarykey) + }; + } + + public InsertNavProvider ThenInclude(Expression> expression, InsertNavOptions options) where TChild : class, new() + { + _navOptions = options; + return _ThenInclude(expression); + } + public InsertNavProvider ThenInclude(Expression>> expression, InsertNavOptions options) where TChild : class, new() + { + _navOptions = options; + return _ThenInclude(expression); + } + + public InsertNavProvider ThenInclude(Expression> expression) where TChild : class, new() + { + return _ThenInclude(expression); + } + public InsertNavProvider ThenInclude(Expression>> expression) where TChild : class, new() + { + return _ThenInclude(expression); + } + + + + private InsertNavProvider _ThenInclude(Expression> expression) where TChild : class, new() + { + var name = ExpressionTool.GetMemberName(expression); + var isRoot = false; + if (this._ParentEntity == null) + { + this._ParentEntity = this._Context.EntityMaintenance.GetEntityInfo(); + this.IsFirst = true; + isRoot = true; + } + var nav = this._ParentEntity.Columns.FirstOrDefault(x => x.PropertyName == name); + if (nav.Navigat == null) + { + Check.ExceptionEasy($"{name} no navigate attribute", $"{this._ParentEntity.EntityName}的属性{name}没有导航属性"); + } + if (nav.Navigat.NavigatType == NavigateType.OneToOne || nav.Navigat.NavigatType == NavigateType.ManyToOne) + { + InitParentList(); + InsertOneToOne(name, nav); + } + else if (nav.Navigat.NavigatType == NavigateType.OneToMany) + { + _NavigateType = NavigateType.OneToMany; + InitParentList(); + InsertOneToMany(name, nav); + } + else + { + InitParentList(); + InsertManyToMany(name, nav); + } + AddContextInfo(name, isRoot); + return GetResult(); + } + + private InsertNavProvider _ThenInclude(Expression>> expression) where TChild : class, new() + { + var name = ExpressionTool.GetMemberName(expression); + if (name == null) + { + name = ExpressionTool.GetMemberNameByMethod(expression, name); + } + var isRoot = false; + if (this._ParentEntity == null) + { + this._ParentEntity = this._Context.EntityMaintenance.GetEntityInfo(); + IsFirst = true; + isRoot = true; + } + var nav = this._ParentEntity.Columns.FirstOrDefault(x => x.PropertyName == name); + if (nav.Navigat == null) + { + Check.ExceptionEasy($"{name} no navigate attribute", $"{this._ParentEntity.EntityName}的属性{name}没有导航属性"); + } + if (nav.Navigat.NavigatType == NavigateType.OneToOne || nav.Navigat.NavigatType == NavigateType.ManyToOne) + { + InitParentList(); + InsertOneToOne(name, nav); + } + else if (nav.Navigat.NavigatType == NavigateType.OneToMany) + { + _NavigateType = NavigateType.OneToMany; + InitParentList(); + InsertOneToMany(name, nav); + } + else + { + InitParentList(); + InsertManyToMany(name, nav); + } + AddContextInfo(name, isRoot); + return GetResult(); + } + + private void AddContextInfo(string name, bool isRoot) + { + if (IsNav || isRoot) + { + if (this.NavContext?.Items != null) + { + this.NavContext.Items.Add(new NavContextItem() { Level = 0, RootName = name }); + } + } + } + private bool NotAny(string name) + { + if (IsFirst) return true; + if (this.NavContext == null) return true; + return this.NavContext?.Items?.Any(it => it.RootName == name) == false; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderHelper.cs new file mode 100644 index 000000000..b527ffc32 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderHelper.cs @@ -0,0 +1,206 @@ +namespace SqlSugar +{ + public partial class InsertNavProvider where T : class, new() where Root : class, new() + { + + private static bool IsDefaultValue(object pvValue) + { + return pvValue?.Equals(UtilMethods.GetDefaultValue(pvValue.GetType())) != false; + } + private void InitParentList() + { + if (_RootList == null) + { + _RootList = _ParentList = GetRootList(_Roots).Cast().ToList(); + } + else if (_ParentList == null) + { + _ParentList = _RootList; + var pkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(it => it.IsPrimarykey); + this._ParentPkColumn = pkColumn; + } + IsFirst = false; + } + + private InsertNavProvider GetResult() where TChild : class, new() + { + return new InsertNavProvider() + { + _Context = this._Context, + _ParentEntity = this._ParentEntity, + _ParentList = this._ParentList, + _Roots = this._Roots, + _ParentPkColumn = this._ParentPkColumn, + _RootList = this._RootList + }; + } + + private List GetRootList(List datas) where Type : class, new() + { + List result = new List(); + this._Context.InitMappingInfo(); + var entity = this._Context.EntityMaintenance.GetEntityInfo(); + var pkColumn = entity.Columns.FirstOrDefault(it => it.IsPrimarykey); + InsertDatas(datas, pkColumn); + this._ParentEntity = entity; + result = datas; + return result; + } + + private void InsertIdentity(List datas) where Type : class, new() + { + foreach (var item in datas) + { + if (IsFirst && _RootOptions != null) + { + this._Context.Insertable(item) + .IgnoreColumns(_RootOptions.IgnoreColumns) + .InsertColumns(_RootOptions.InsertColumns) + .EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData) + .ExecuteCommandIdentityIntoEntity(); + } + else + { + this._Context.Insertable(item).ExecuteCommandIdentityIntoEntity(); + } + } + } + + private EntityColumnInfo GetPkColumnByNav(EntityInfo entity, EntityColumnInfo nav) + { + var pkColumn = entity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + if (nav.Navigat.Name2.HasValue()) + { + pkColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + } + return pkColumn; + } + private EntityColumnInfo GetPkColumnByNav2(EntityInfo entity, EntityColumnInfo nav) + { + var pkColumn = entity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + return pkColumn; + } + private EntityColumnInfo GetFKColumnByNav(EntityInfo entity, EntityColumnInfo nav) + { + var fkColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + return fkColumn; + } + private void InsertDatas(List children, EntityColumnInfo pkColumn, EntityColumnInfo NavColumn = null) where TChild : class, new() + { + children = children.Distinct().ToList(); + if (pkColumn == null) + { + Check.ExceptionEasy($"{typeof(TChild).Name} need primary key ", $"{typeof(TChild).Name}需要主键"); + } + var x = this._Context.Storageable(children).WhereColumns(new string[] { pkColumn.PropertyName }).GetStorageableResult(); + var insertData = children = x.InsertList.Select(it => it.Item).ToList(); + var IsNoExistsNoInsert = _navOptions?.OneToManyIfExistsNoInsert == true; + if (_NavigateType == NavigateType.OneToMany && IsFirst == false && IsNoExistsNoInsert == false) + { + var updateData = x.UpdateList.Select(it => it.Item).ToList(); + ClearPk(updateData, pkColumn); + insertData.AddRange(updateData); + } + else if (_NavigateType == NavigateType.OneToMany && IsNoExistsNoInsert == true) + { + children = new List(); + children.AddRange(x.InsertList.Select(it => it.Item).ToList()); + var updateData = x.UpdateList.Select(it => it.Item).ToList(); + children.AddRange(updateData); + } + Check.ExceptionEasy(pkColumn == null && NavColumn == null, $"The entity is invalid", $"实体错误无法使用导航"); + InitData(pkColumn, insertData); + this._ParentList = children.Cast().ToList(); + } + + private void ClearPk(List updateData, EntityColumnInfo pkColumn) where TChild : class, new() + { + foreach (var child in updateData) + { + var defaultValue = UtilMethods.DefaultForType(pkColumn.PropertyInfo.PropertyType); + pkColumn.PropertyInfo.SetValue(child, defaultValue); + } + } + + private void InitData(EntityColumnInfo pkColumn, List insertData) where TChild : class, new() + { + if (pkColumn.IsIdentity || pkColumn.OracleSequenceName.HasValue()) + { + InsertIdentity(insertData); + } + else if (pkColumn.UnderType == UtilConstants.LongType) + { + SetValue(pkColumn, insertData, () => SnowFlakeSingle.Instance.NextId()); + } + else if (pkColumn.UnderType == UtilConstants.GuidType) + { + SetValue(pkColumn, insertData, () => Guid.NewGuid()); + } + else if (pkColumn.UnderType == UtilConstants.StringType) + { + SetValue(pkColumn, insertData, () => Guid.NewGuid().ToString()); + } + else + { + SetError(pkColumn, insertData); + } + } + + private void SetValue(EntityColumnInfo pkColumn, List insertData, Func value) where TChild : class, new() + { + foreach (var child in insertData) + { + if (IsDefaultValue(pkColumn.PropertyInfo.GetValue(child))) + { + pkColumn.PropertyInfo.SetValue(child, value()); + } + } + if (IsFirst && _RootOptions != null) + { + this._Context.Insertable(insertData) + .IgnoreColumns(_RootOptions.IgnoreColumns) + .InsertColumns(_RootOptions.InsertColumns) + .EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData) + .ExecuteCommand(); + } + else + { + this._Context.Insertable(insertData).ExecuteCommand(); + } + } + private void SetError(EntityColumnInfo pkColumn, List insertData) where TChild : class, new() + { + foreach (var child in insertData) + { + if (IsDefaultValue(pkColumn.PropertyInfo.GetValue(child))) + { + var name = pkColumn.EntityName + " " + pkColumn.DbColumnName; + Check.ExceptionEasy($"The field {name} is not an autoassignment type and requires an assignment", $"字段{name}不是可自动赋值类型需要赋值(并且不能是已存在值) , 可赋值类型有 自增、long、Guid、string"); + } + } + if (IsFirst && _RootOptions != null) + { + this._Context.Insertable(insertData) + .IgnoreColumns(_RootOptions.IgnoreColumns) + .InsertColumns(_RootOptions.InsertColumns) + .EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData) + .ExecuteCommand(); + } + else + { + var isIdentity = this._Context.EntityMaintenance.GetEntityInfo(typeof(TChild)).Columns.Any(it => it.IsIdentity); + if (isIdentity) + { + foreach (var item in insertData) + { + this._Context.Insertable(insertData).ExecuteCommandIdentityIntoEntity(); + } + } + else + { + this._Context.Insertable(insertData).ExecuteCommand(); + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderManyToMany.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderManyToMany.cs new file mode 100644 index 000000000..c0cd44460 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderManyToMany.cs @@ -0,0 +1,165 @@ +using Newtonsoft.Json; +namespace SqlSugar +{ + public partial class InsertNavProvider where T : class, new() where Root : class, new() + { + private void InsertManyToMany(string name, EntityColumnInfo nav) where TChild : class, new() + { + ; + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + Check.ExceptionEasy(thisPkColumn == null, $"{thisPkColumn.EntityName} need primary key", $"{thisPkColumn.EntityName}需要主键"); + Check.ExceptionEasy(parentPkColumn == null, $"{parentPkColumn.EntityName} need primary key", $"{parentPkColumn.EntityName}需要主键"); + var mappingType = parentNavigateProperty.Navigat.MappingType; + var mappingEntity = this._Context.EntityMaintenance.GetEntityInfo(mappingType); + var mappingA = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingAId); + var mappingB = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingBId); + Check.ExceptionEasy(mappingA == null || mappingB == null, $"Navigate property {name} error ", $"导航属性{name}配置错误"); + var mappingPk = mappingEntity.Columns + .Where(it => it.PropertyName != mappingA.PropertyName) + .Where(it => it.PropertyName != mappingB.PropertyName) + .Where(it => it.IsPrimarykey && !it.IsIdentity && it.OracleSequenceName.IsNullOrEmpty()).FirstOrDefault(); + var mappingOthers = mappingEntity.Columns + .Where(it => it.PropertyName != mappingA.PropertyName) + .Where(it => it.PropertyName != mappingB.PropertyName) + .Where(it => !it.IsIdentity) + .Where(it => !it.IsOnlyIgnoreInsert) + .Where(it => !it.IsIgnore) + .Where(it => !it.IsPrimarykey); + List> mappgingTables = new List>(); + foreach (var item in parentList) + { + var items = parentNavigateProperty.PropertyInfo.GetValue(item); + if (items == null) + { + continue; + } + var children = ((List)items); + InsertDatas(children, thisPkColumn); + var parentId = parentPkColumn.PropertyInfo.GetValue(item); + foreach (var child in children) + { + var chidId = thisPkColumn.PropertyInfo.GetValue(child); + Dictionary keyValuePairs = new Dictionary(); + keyValuePairs.Add(mappingA.DbColumnName, parentId); + keyValuePairs.Add(mappingB.DbColumnName, chidId); + if (mappingOthers != null) + { + foreach (var pair in mappingOthers) + { + if (!keyValuePairs.ContainsKey(pair.DbColumnName)) + { + if (pair.UnderType == UtilConstants.DateType) + { + keyValuePairs.Add(pair.DbColumnName, DateTime.Now); + } + else if (pair.UnderType == UtilConstants.StringType) + { + keyValuePairs.Add(pair.DbColumnName, UtilConstants.Space); + } + else + { + keyValuePairs.Add(pair.DbColumnName, UtilMethods.GetDefaultValue(pair.UnderType)); + } + } + } + } + if (mappingPk != null) + { + SetMappingTableDefaultValue(mappingPk, keyValuePairs); + } + mappgingTables.Add(keyValuePairs); + } + } + var ids = mappgingTables.Select(x => x[mappingA.DbColumnName]).ToList(); + if (_navOptions?.ManyToManyNoDeleteMap == true) + { + //The reserved + } + else + { + this._Context.Deleteable().AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, ids).ExecuteCommand(); + } + if (HasMappingTemplate(mappingEntity)) + { + InertMappingWithTemplate(mappingEntity, mappingA, mappingB, mappgingTables); + } + else + { + this._Context.Insertable(mappgingTables).AS(mappingEntity.DbTableName).ExecuteCommand(); + } + SetNewParent(thisEntity, thisPkColumn); + } + + private void InertMappingWithTemplate(EntityInfo mappingEntity, EntityColumnInfo mappingA, EntityColumnInfo mappingB, List> mappgingTables) + { + var template = this._navOptions?.ManyToManySaveMappingTemplate; + List mappingObjects = new List(); + foreach (var item in mappgingTables) + { + // 序列化模板对象 + var serializedTemplate = JsonConvert.SerializeObject(template); + + // 反序列化模板对象,创建新的映射对象 + var mappingObject = JsonConvert.DeserializeObject(serializedTemplate, template.GetType()); + + // 获取映射对象的所有字段 + var fields = mappingEntity.Columns; + + // 遍历字典中的键值对,并将值赋给映射对象的对应字段 + foreach (var kvp in item) + { + var fieldName = kvp.Key; + var fieldValue = kvp.Value; + + // 查找与字段名匹配的字段 + var field = fields.FirstOrDefault(f => f.DbColumnName.EqualCase(fieldName)); + // 如果字段存在且值的类型与字段类型匹配,则赋值给字段 + if (field != null) + { + var isSetValue = field.IsPrimarykey + || field.DbColumnName == mappingA.DbColumnName + || field.DbColumnName == mappingB.DbColumnName; + if (isSetValue) + field.PropertyInfo.SetValue(mappingObject, fieldValue); + } + } + + // 将映射对象添加到列表中 + mappingObjects.Add(mappingObject); + } + this._Context.InsertableByObject(mappingObjects).ExecuteCommand(); + } + + private bool HasMappingTemplate(EntityInfo mappingEntity) + { + return this._navOptions?.ManyToManySaveMappingTemplate?.GetType() == mappingEntity.Type; + } + + private void SetMappingTableDefaultValue(EntityColumnInfo mappingPk, Dictionary keyValuePairs) + { + if (mappingPk.UnderType == UtilConstants.LongType) + { + keyValuePairs.Add(mappingPk.DbColumnName, SnowFlakeSingle.Instance.NextId()); + } + else if (mappingPk.UnderType == UtilConstants.GuidType) + { + keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid()); + } + else if (mappingPk.UnderType == UtilConstants.StringType) + { + keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid() + ""); + } + else + { + var name = mappingPk.EntityName + " " + mappingPk.DbColumnName; + Check.ExceptionEasy($"The field {name} is not an autoassignment type and requires an assignment", + $" 中间表主键字段{name}不是可自动赋值类型, 可赋值类型有 自增、long、Guid、string。你也可以删掉主键 用双主键"); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderOneToMany.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderOneToMany.cs new file mode 100644 index 000000000..394383807 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderOneToMany.cs @@ -0,0 +1,104 @@ +using System.Collections; +namespace SqlSugar +{ + public partial class InsertNavProvider where T : class, new() where Root : class, new() + { + + private void InsertOneToMany(string name, EntityColumnInfo nav) where TChild : class, new() + { + List children = new List(); + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = GetPkColumnByNav2(thisEntity, nav); + var thisFkColumn = GetFKColumnByNav(thisEntity, nav); + EntityColumnInfo parentPkColumn = GetParentPkColumn(); + EntityColumnInfo parentNavColumn = GetParentPkNavColumn(nav); + if (parentNavColumn != null) + { + parentPkColumn = parentNavColumn; + } + if (ParentIsPk(parentNavigateProperty)) + { + parentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + foreach (var item in parentList) + { + var parentValue = parentPkColumn.PropertyInfo.GetValue(item); + var childs = parentNavigateProperty.PropertyInfo.GetValue(item) as List; + if (childs != null) + { + foreach (var child in childs) + { + thisFkColumn.PropertyInfo.SetValue(child, parentValue, null); + } + children.AddRange(childs); + } + else if (childs == null && parentNavigateProperty.PropertyInfo.GetValue(item) is IList ilist && ilist?.Count > 0) + { + childs = GetIChildsBylList(children, thisFkColumn, parentValue, ilist); + } + } + var isTreeChild = GetIsTreeChild(parentEntity, thisEntity); + Check.ExceptionEasy(thisPkColumn == null, $"{thisEntity.EntityName}need primary key", $"实体{thisEntity.EntityName}需要主键"); + if (NotAny(name) || isTreeChild) + { + InsertDatas(children, thisPkColumn); + } + else + { + this._ParentList = children.Cast().ToList(); + } + SetNewParent(thisEntity, thisPkColumn); + } + + private static List GetIChildsBylList(List children, EntityColumnInfo thisFkColumn, object parentValue, IList ilist) where TChild : class, new() + { + List childs = ilist.Cast().ToList(); + foreach (var child in childs) + { + thisFkColumn.PropertyInfo.SetValue(child, parentValue, null); + } + children.AddRange(childs); + return childs; + } + + private bool GetIsTreeChild(EntityInfo parentEntity, EntityInfo thisEntity) + { + return this.NavContext?.Items?.Count > 0 && parentEntity.Type == thisEntity.Type; + } + + private static bool ParentIsPk(EntityColumnInfo parentNavigateProperty) + { + return parentNavigateProperty?.Navigat != null && + parentNavigateProperty.Navigat.NavigatType == NavigateType.OneToMany && + parentNavigateProperty.Navigat.Name2 == null; + } + + private EntityColumnInfo GetParentPkColumn() + { + EntityColumnInfo parentPkColumn = _ParentPkColumn; + if (_ParentPkColumn == null) + { + parentPkColumn = _ParentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + return parentPkColumn; + } + private EntityColumnInfo GetParentPkNavColumn(EntityColumnInfo nav) + { + EntityColumnInfo result = null; + if (nav.Navigat.Name2.HasValue()) + { + result = _ParentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + } + return result; + } + + private void SetNewParent(EntityInfo entityInfo, EntityColumnInfo entityColumnInfo) where TChild : class, new() + { + this._ParentEntity = entityInfo; + this._ParentPkColumn = entityColumnInfo; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderOneToOne.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderOneToOne.cs new file mode 100644 index 000000000..08e28905a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavProviderOneToOne.cs @@ -0,0 +1,59 @@ +namespace SqlSugar +{ + public partial class InsertNavProvider where T : class, new() where Root : class, new() + { + private void InsertOneToOne(string name, EntityColumnInfo nav) where TChild : class, new() + { + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentColumn = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + EntityColumnInfo thisPkColumn = GetPkColumnByNav(thisEntity, nav); + Check.ExceptionEasy(thisPkColumn == null, $" Navigate {parentEntity.EntityName} : {name} is error ", $"导航实体 {parentEntity.EntityName} 属性 {name} 配置错误"); + Check.ExceptionEasy(nav.Navigat.WhereSql.HasValue(), $" {name} Navigate(NavType,WhereSql) no support insert ", $"导航一对一 {name} 配置了 Sql变量 不支持插入"); + List childList = new List(); + foreach (var parent in parentList) + { + var navPropertyValue = parentColumn.PropertyInfo.GetValue(parent); + var childItem = (TChild)nav.PropertyInfo.GetValue(parent); + if (childItem != null) + { + if (IsDefaultValue(navPropertyValue)) + { + var pkValue = thisPkColumn.PropertyInfo.GetValue(childItem); + if (IsDefaultValue(navPropertyValue)) + { + navPropertyValue = pkValue; + } + + } + if (!IsDefaultValue(navPropertyValue) && parentColumn.IsPrimarykey == false) + { + this._Context.Updateable + ().AS(parentEntity.DbTableName) + .SetColumns(parentColumn.DbColumnName, navPropertyValue) + .Where(parentPkColumn.DbColumnName, "=", parentPkColumn.PropertyInfo.GetValue(parent)).ExecuteCommand(); + } + if (IsDefaultValue(navPropertyValue)) + { + InsertDatas(new List() { childItem }, thisPkColumn); + navPropertyValue = thisPkColumn.PropertyInfo.GetValue(childItem); + parentColumn.PropertyInfo.SetValue(parent, navPropertyValue); + this._Context.Updateable + ().AS(parentEntity.DbTableName) + .SetColumns(parentColumn.DbColumnName, navPropertyValue) + .Where(parentPkColumn.DbColumnName, "=", parentPkColumn.PropertyInfo.GetValue(parent)).ExecuteCommand(); + } + + thisPkColumn.PropertyInfo.SetValue(childItem, navPropertyValue); + childList.Add(childItem); + } + } + InsertDatas(childList, thisPkColumn); + this._ParentList = childList.Cast().ToList(); + SetNewParent(thisEntity, thisPkColumn); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavTask.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavTask.cs new file mode 100644 index 000000000..6c2bccdb6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/InsertNavTask.cs @@ -0,0 +1,249 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class InsertNavTaskInit where T : class, new() where Root : class, new() + { + + internal SqlSugarProvider Context { get; set; } + internal InsertNavProvider insertNavProvider { get; set; } + internal NavContext NavContext { get; set; } + public InsertNavMethodInfo IncludeByNameString(string navMemberName, InsertNavOptions insertNavOptions = null) + { + InsertNavMethodInfo result = new InsertNavMethodInfo(); + result.Context = insertNavProvider._Context; + var entityInfo = result.Context.EntityMaintenance.GetEntityInfo(); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.GetType().GetMyMethod("Include", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this, new object[] { exp, insertNavOptions }); + result.MethodInfos = obj; + return result; + } + public InsertNavMethodInfo IncludesAllFirstLayer(params string[] ignoreColumns) + { + if (ignoreColumns == null) + { + ignoreColumns = Array.Empty(); + } + this.Context = insertNavProvider._Context; + var navColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !ignoreColumns.Contains(it.PropertyName) || !ignoreColumns.Any(z => z.EqualCase(it.DbColumnName))).Where(it => it.Navigat != null).ToList(); + var updateNavs = this; + InsertNavMethodInfo methodInfo = updateNavs.IncludeByNameString(navColumns[0].PropertyName); + foreach (var item in navColumns.Skip(1)) + { + methodInfo = methodInfo.IncludeByNameString(item.PropertyName); + } + return methodInfo; + } + public InsertNavMethodInfo IncludesAllFirstLayer(InsertNavOptions insertNavOptions, params string[] ignoreColumns) + { + if (ignoreColumns == null) + { + ignoreColumns = Array.Empty(); + } + this.Context = insertNavProvider._Context; + var navColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !ignoreColumns.Contains(it.PropertyName) || !ignoreColumns.Any(z => z.EqualCase(it.DbColumnName))).Where(it => it.Navigat != null).ToList(); + var updateNavs = this; + InsertNavMethodInfo methodInfo = updateNavs.IncludeByNameString(navColumns[0].PropertyName); + foreach (var item in navColumns.Skip(1)) + { + methodInfo = methodInfo.IncludeByNameString(item.PropertyName, insertNavOptions); + } + return methodInfo; + } + public InsertNavTask Include(Expression> expression) where TChild : class, new() + { + Check.ExceptionEasy(typeof(TChild).FullName.Contains("System.Collections.Generic.List`"), " need where T: class, new() ", "需要Class,new()约束,并且类属性中不能有required修饰符"); + this.Context = insertNavProvider._Context; + insertNavProvider.NavContext = this.NavContext; + InsertNavTask result = new InsertNavTask(); + Func> func = () => insertNavProvider.ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public InsertNavTask Include(Expression>> expression) where TChild : class, new() + { + this.Context = insertNavProvider._Context; + insertNavProvider.NavContext = this.NavContext; + InsertNavTask result = new InsertNavTask(); + Func> func = () => insertNavProvider.ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + + public InsertNavTask Include(Expression> expression, InsertNavOptions options) where TChild : class, new() + { + Check.ExceptionEasy(typeof(TChild).FullName.Contains("System.Collections.Generic.List`"), " need where T: class, new() ", "需要Class,new()约束,并且类属性中不能有required修饰符"); + this.Context = insertNavProvider._Context; + insertNavProvider.NavContext = this.NavContext; + InsertNavTask result = new InsertNavTask(); + Func> func = () => insertNavProvider.ThenInclude(expression, options); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public InsertNavTask Include(Expression>> expression, InsertNavOptions options) where TChild : class, new() + { + this.Context = insertNavProvider._Context; + insertNavProvider.NavContext = this.NavContext; + InsertNavTask result = new InsertNavTask(); + Func> func = () => insertNavProvider.ThenInclude(expression, options); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + } + public class InsertNavTask where T : class, new() where Root : class, new() + { + public SqlSugarProvider Context { get; set; } + public Func> PreFunc { get; set; } + internal NavContext NavContext { get; set; } + + public InsertNavTask ThenInclude(Expression> expression) where TChild : class, new() + { + InsertNavTask result = new InsertNavTask(); + Func> func = () => + { + var nav = PreFunc().ThenInclude(expression); + nav.NavContext = this.NavContext; + return nav; + }; + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public InsertNavTask ThenInclude(Expression>> expression) where TChild : class, new() + { + InsertNavTask result = new InsertNavTask(); + Func> func = () => + { + var nav = PreFunc().ThenInclude(expression); + nav.NavContext = this.NavContext; + return nav; + }; + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public InsertNavTask Include(Expression> expression) where TChild : class, new() + { + return AsNav().ThenInclude(expression); + } + public InsertNavTask Include(Expression>> expression) where TChild : class, new() + { + return AsNav().ThenInclude(expression); + } + + + + public InsertNavTask ThenInclude(Expression> expression, InsertNavOptions options) where TChild : class, new() + { + InsertNavTask result = new InsertNavTask(); + Func> func = () => PreFunc().ThenInclude(expression, options); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public InsertNavTask ThenInclude(Expression>> expression, InsertNavOptions options) where TChild : class, new() + { + InsertNavTask result = new InsertNavTask(); + Func> func = () => PreFunc().ThenInclude(expression, options); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public InsertNavTask Include(Expression> expression, InsertNavOptions options) where TChild : class, new() + { + return AsNav().ThenInclude(expression, options); + } + public InsertNavTask Include(Expression>> expression, InsertNavOptions options) where TChild : class, new() + { + return AsNav().ThenInclude(expression, options); + } + + public Root ExecuteReturnEntity() + { + var hasTran = this.Context.Ado.Transaction != null; + if (hasTran) + { + return (Root)PreFunc()?._RootList?.FirstOrDefault(); + } + else + { + Root result = null; + this.Context.Ado.UseTran(() => + { + result = (Root)PreFunc()?._RootList?.FirstOrDefault(); + }, ex => throw ex); + return result; + } + } + public async Task ExecuteReturnEntityAsync() + { + Root result = null; + await Task.Run(async () => + { + result = ExecuteReturnEntity(); + await Task.Delay(0).ConfigureAwait(false); + }).ConfigureAwait(false); + return result; + } + + public bool ExecuteCommand() + { + var hasTran = this.Context.Ado.Transaction != null; + if (hasTran) + { + PreFunc(); + } + else + { + this.Context.Ado.UseTran(() => + { + PreFunc(); + }, ex => throw ex); + } + return true; + } + public async Task ExecuteCommandAsync() + { + await Task.Run(async () => + { + ExecuteCommand(); + await Task.Delay(0).ConfigureAwait(false); + }).ConfigureAwait(false); + return true; + } + + private InsertNavTask AsNav() + { + InsertNavTask result = new InsertNavTask(); + Func> func = () => + { + + var navas = PreFunc().AsNav(); + navas.NavContext = this.NavContext; + navas.IsNav = true; + return navas; + }; + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/NavContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/NavContext.cs new file mode 100644 index 000000000..3d83a582b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/NavContext.cs @@ -0,0 +1,12 @@ +namespace SqlSugar +{ + internal class NavContext + { + public List Items { get; set; } + } + internal class NavContextItem + { + public int Level { get; set; } + public string RootName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavManyToMany.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavManyToMany.cs new file mode 100644 index 000000000..4d8f8b47b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavManyToMany.cs @@ -0,0 +1,194 @@ +using Newtonsoft.Json; +namespace SqlSugar +{ + public partial class UpdateNavProvider where T : class, new() where Root : class, new() + { + private void UpdateManyToMany(string name, EntityColumnInfo nav) where TChild : class, new() + { + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + Check.ExceptionEasy(thisPkColumn == null, $"{thisPkColumn.EntityName} need primary key", $"{thisPkColumn.EntityName}需要主键"); + Check.ExceptionEasy(parentPkColumn == null, $"{parentPkColumn.EntityName} need primary key", $"{parentPkColumn.EntityName}需要主键"); + var mappingType = parentNavigateProperty.Navigat.MappingType; + var mappingEntity = this._Context.EntityMaintenance.GetEntityInfo(mappingType); + var mappingA = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingAId); + var mappingB = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingBId); + Check.ExceptionEasy(mappingA == null || mappingB == null, $"Navigate property {name} error ", $"导航属性{name}配置错误"); + var mappingPk = mappingEntity.Columns + .Where(it => it.PropertyName != mappingA.PropertyName) + .Where(it => it.PropertyName != mappingB.PropertyName) + .Where(it => it.IsPrimarykey && !it.IsIdentity && it.OracleSequenceName.IsNullOrEmpty()).FirstOrDefault(); + var mappingOthers = mappingEntity.Columns + .Where(it => it.PropertyName != mappingA.PropertyName) + .Where(it => it.PropertyName != mappingB.PropertyName) + .Where(it => !it.IsIdentity) + .Where(it => !it.IsPrimarykey) + .Where(it => !it.IsOnlyIgnoreInsert) + .Where(it => !it.IsIgnore); + List> mappgingTables = new List>(); + var ids = new List(); + foreach (var item in parentList) + { + var items = parentNavigateProperty.PropertyInfo.GetValue(item); + if (items == null) + { + continue; + } + var children = ((List)items); + if (this._Options?.ManyToManyIsUpdateB == true) + { + InsertDatas(children, thisPkColumn); + } + else + { + _ParentList = children.Cast().ToList(); + } + var parentId = parentPkColumn.PropertyInfo.GetValue(item); + if (!ids.Contains(parentId)) + { + ids.Add(parentId); + } + foreach (var child in children) + { + var chidId = thisPkColumn.PropertyInfo.GetValue(child); + Dictionary keyValuePairs = new Dictionary(); + keyValuePairs.Add(mappingA.DbColumnName, parentId); + keyValuePairs.Add(mappingB.DbColumnName, chidId); + if (mappingOthers != null) + { + foreach (var pair in mappingOthers) + { + if (pair.UnderType == UtilConstants.DateType) + { + keyValuePairs.Add(pair.DbColumnName, DateTime.Now); + } + else if (pair.UnderType == UtilConstants.StringType) + { + keyValuePairs.Add(pair.DbColumnName, UtilConstants.Space); + } + else + { + keyValuePairs.Add(pair.DbColumnName, UtilMethods.GetDefaultValue(pair.UnderType)); + } + } + } + if (mappingPk != null) + { + SetMappingTableDefaultValue(mappingPk, keyValuePairs); + } + mappgingTables.Add(keyValuePairs); + } + } + if (this._Options?.ManyToManyEnableLogicDelete == true) + { + var locgicColumn = thisEntity.Columns.FirstOrDefault(it => it.PropertyName.EqualCase("IsDeleted") || it.PropertyName.EqualCase("IsDelete")); + Check.ExceptionEasy( + locgicColumn == null, + thisEntity.EntityName + "Logical deletion requires the entity to have the IsDeleted property", + thisEntity.EntityName + "假删除需要实体有IsDeleted属性"); + List conditionalModels = new List(); + conditionalModels.Add(new ConditionalModel() + { + FieldName = mappingA.DbColumnName, + FieldValue = string.Join(",", ids.Distinct()), + ConditionalType = ConditionalType.In, + CSharpTypeName = mappingA?.PropertyInfo?.PropertyType?.Name + }); + var sqlObj = _Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + this._Context.Updateable() + .AS(mappingEntity.DbTableName) + .Where(sqlObj.Key, sqlObj.Value) + .SetColumns(locgicColumn.DbColumnName, true) + .ExecuteCommand(); + } + else if (_Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true) + { + this._Context.Deleteable().AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, ids).EnableQueryFilter(mappingEntity.Type).ExecuteCommand(); + } + else + { + this._Context.Deleteable().AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, ids).ExecuteCommand(); + } + if (HasMappingTemplate(mappingEntity)) + { + InertMappingWithTemplate(mappingEntity, mappingA, mappingB, mappgingTables); + } + else + { + this._Context.Insertable(mappgingTables).AS(mappingEntity.DbTableName).ExecuteCommand(); + } + _ParentEntity = thisEntity; + } + + private bool HasMappingTemplate(EntityInfo mappingEntity) + { + return this._Options?.ManyToManySaveMappingTemplate?.GetType() == mappingEntity.Type; + } + + private void InertMappingWithTemplate(EntityInfo mappingEntity, EntityColumnInfo mappingA, EntityColumnInfo mappingB, List> mappgingTables) + { + var template = this._Options?.ManyToManySaveMappingTemplate; + List mappingObjects = new List(); + foreach (var item in mappgingTables) + { + // 序列化模板对象 + var serializedTemplate = JsonConvert.SerializeObject(template); + + // 反序列化模板对象,创建新的映射对象 + var mappingObject = JsonConvert.DeserializeObject(serializedTemplate, template.GetType()); + + // 获取映射对象的所有字段 + var fields = mappingEntity.Columns; + + // 遍历字典中的键值对,并将值赋给映射对象的对应字段 + foreach (var kvp in item) + { + var fieldName = kvp.Key; + var fieldValue = kvp.Value; + + // 查找与字段名匹配的字段 + var field = fields.FirstOrDefault(f => f.DbColumnName.EqualCase(fieldName)); + // 如果字段存在且值的类型与字段类型匹配,则赋值给字段 + if (field != null) + { + var isSetValue = field.IsPrimarykey + || field.DbColumnName == mappingA.DbColumnName + || field.DbColumnName == mappingB.DbColumnName; + if (isSetValue) + field.PropertyInfo.SetValue(mappingObject, fieldValue); + } + } + + // 将映射对象添加到列表中 + mappingObjects.Add(mappingObject); + } + this._Context.InsertableByObject(mappingObjects).ExecuteCommand(); + } + + private void SetMappingTableDefaultValue(EntityColumnInfo mappingPk, Dictionary keyValuePairs) + { + if (mappingPk.UnderType == UtilConstants.LongType) + { + keyValuePairs.Add(mappingPk.DbColumnName, SnowFlakeSingle.Instance.NextId()); + } + else if (mappingPk.UnderType == UtilConstants.GuidType) + { + keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid()); + } + else if (mappingPk.UnderType == UtilConstants.StringType) + { + keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid() + ""); + } + else + { + var name = mappingPk.EntityName + " " + mappingPk.DbColumnName; + Check.ExceptionEasy($"The field {name} is not an autoassignment type and requires an assignment", + $" 中间表主键字段{name}不是可自动赋值类型, 可赋值类型有 自增、long、Guid、string。你也可以删掉主键 用双主键"); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs new file mode 100644 index 000000000..1920997c1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs @@ -0,0 +1,338 @@ +using System.Collections; +namespace SqlSugar +{ + public partial class UpdateNavProvider where T : class, new() where Root : class, new() + { + public NavigateType? _NavigateType { get; set; } + private void UpdateOneToMany(string name, EntityColumnInfo nav) where TChild : class, new() + { + if (_Options?.OneToManyInsertOrUpdate == true) + { + InsertOrUpdate(name, nav); + } + else + { + DeleteInsert(name, nav); + } + } + private void InsertOrUpdate(string name, EntityColumnInfo nav) where TChild : class, new() + { + List children = new List(); + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = GetPkColumnByNav2(thisEntity, nav); + var thisFkColumn = GetFKColumnByNav(thisEntity, nav); + EntityColumnInfo parentPkColumn = GetParentPkColumn(); + EntityColumnInfo parentNavColumn = GetParentPkNavColumn(nav); + if (parentNavColumn != null) + { + parentPkColumn = parentNavColumn; + } + if (ParentIsPk(parentNavigateProperty)) + { + parentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + var ids = new List(); + foreach (var item in parentList) + { + var parentValue = parentPkColumn.PropertyInfo.GetValue(item); + var childs = parentNavigateProperty.PropertyInfo.GetValue(item) as List; + if (childs != null) + { + foreach (var child in childs) + { + thisFkColumn.PropertyInfo.SetValue(child, parentValue, null); + } + children.AddRange(childs); + } + ids.Add(parentValue); + if (_Options?.OneToManyNoDeleteNull == true && childs == null) + { + ids.Remove(parentValue); + } + } + if (NotAny(name)) + { + DeleteMany(thisEntity, ids, thisFkColumn.DbColumnName); + if (this._Options?.OneToManyEnableLogicDelete == true) + { + var locgicColumn = thisEntity.Columns.FirstOrDefault(it => it.PropertyName.EqualCase("IsDeleted") || it.PropertyName.EqualCase("IsDelete")); + Check.ExceptionEasy( + locgicColumn == null, + thisEntity.EntityName + "Logical deletion requires the entity to have the IsDeleted property", + thisEntity.EntityName + "假删除需要实体有IsDeleted属性"); + List conditionalModels = new List(); + conditionalModels.Add(new ConditionalModel() + { + FieldName = thisFkColumn.DbColumnName, + FieldValue = string.Join(",", ids.Distinct()), + ConditionalType = ConditionalType.In, + CSharpTypeName = thisFkColumn?.PropertyInfo?.PropertyType?.Name + }); + var sqlObj = _Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + this._Context.Updateable() + .AS(thisEntity.DbTableName) + .Where(sqlObj.Key, sqlObj.Value) + .SetColumns(locgicColumn.DbColumnName, true) + .ExecuteCommand(); + } + else + { + var list = this._Context.Queryable() + .AS(thisEntity.DbTableName) + .In(thisFkColumn.DbColumnName, ids.Distinct().ToList()) + .ToList(); + List result = GetNoExistsId(list, children, thisPkColumn.PropertyName); + if (result.Count != 0) + { + this._Context.Deleteable(result).ExecuteCommand(); + } + } + _NavigateType = NavigateType.OneToMany; + InsertDatas(children, thisPkColumn); + } + else + { + this._ParentList = children.Cast().ToList(); + } + _NavigateType = null; + SetNewParent(thisEntity, thisPkColumn); + } + private void DeleteInsert(string name, EntityColumnInfo nav) where TChild : class, new() + { + List children = new List(); + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = GetPkColumnByNav2(thisEntity, nav); + var thisFkColumn = GetFKColumnByNav(thisEntity, nav); + EntityColumnInfo parentPkColumn = GetParentPkColumn(); + EntityColumnInfo parentNavColumn = GetParentPkNavColumn(nav); + if (parentNavColumn != null) + { + parentPkColumn = parentNavColumn; + } + if (ParentIsPk(parentNavigateProperty)) + { + parentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + var ids = new List(); + foreach (var item in parentList) + { + var parentValue = parentPkColumn.PropertyInfo.GetValue(item); + var childs = parentNavigateProperty.PropertyInfo.GetValue(item) as List; + if (childs != null) + { + foreach (var child in childs) + { + thisFkColumn.PropertyInfo.SetValue(child, parentValue, null); + } + children.AddRange(childs); + } + else if (childs == null && parentNavigateProperty.PropertyInfo.GetValue(item) is IList ilist && ilist?.Count > 0) + { + childs = GetIChildsBylList(children, thisFkColumn, parentValue, ilist); + } + ids.Add(parentValue); + if (_Options?.OneToManyNoDeleteNull == true && childs == null) + { + ids.Remove(parentValue); + } + } + if (NotAny(name)) + { + DeleteMany(thisEntity, ids, thisFkColumn.DbColumnName); + if (this._Options?.OneToManyEnableLogicDelete == true) + { + var locgicColumn = thisEntity.Columns.FirstOrDefault(it => it.PropertyName.EqualCase("IsDeleted") || it.PropertyName.EqualCase("IsDelete")); + Check.ExceptionEasy( + locgicColumn == null, + thisEntity.EntityName + "Logical deletion requires the entity to have the IsDeleted property", + thisEntity.EntityName + "假删除需要实体有IsDeleted属性"); + List conditionalModels = new List(); + conditionalModels.Add(new ConditionalModel() + { + FieldName = thisFkColumn.DbColumnName, + FieldValue = string.Join(",", ids.Distinct()), + ConditionalType = ConditionalType.In, + CSharpTypeName = thisFkColumn?.PropertyInfo?.PropertyType?.Name + }); + var sqlObj = _Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + this._Context.Updateable() + .AS(thisEntity.DbTableName) + .Where(sqlObj.Key, sqlObj.Value) + .SetColumns(locgicColumn.DbColumnName, true) + .ExecuteCommand(); + } + else + { + if (this._Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true) + { + this._Context.Deleteable() + .AS(thisEntity.DbTableName) + .EnableQueryFilter(thisEntity.Type) + .In(thisFkColumn.DbColumnName, ids.Distinct().ToList()).ExecuteCommand(); + } + else + { + this._Context.Deleteable() + .AS(thisEntity.DbTableName) + .In(thisFkColumn.DbColumnName, ids.Distinct().ToList()).ExecuteCommand(); + } + } + _NavigateType = NavigateType.OneToMany; + InsertDatas(children, thisPkColumn); + } + else + { + this._ParentList = children.Cast().ToList(); + } + _NavigateType = null; + SetNewParent(thisEntity, thisPkColumn); + } + private static List GetIChildsBylList(List children, EntityColumnInfo thisFkColumn, object parentValue, IList ilist) where TChild : class, new() + { + List childs = ilist.Cast().ToList(); + foreach (var child in childs) + { + thisFkColumn.PropertyInfo.SetValue(child, parentValue, null); + } + children.AddRange(childs); + return childs; + } + + private static bool ParentIsPk(EntityColumnInfo parentNavigateProperty) + { + return parentNavigateProperty?.Navigat != null && + parentNavigateProperty.Navigat.NavigatType == NavigateType.OneToMany && + parentNavigateProperty.Navigat.Name2 == null; + } + private void DeleteMany(EntityInfo thisEntity, List ids, string fkName) + { + if (_Options == null || _Options.OneToManyDeleteAll == false) + { + return; + } + var oneToManys = thisEntity.Columns.Where(it => it.Navigat != null && it.Navigat.NavigatType == NavigateType.OneToMany).ToList(); + foreach (var oneToMany in oneToManys) + { + var fkFieldName = oneToMany.Navigat.Name2 ?? thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey).PropertyName; + var fkDbColumnName = thisEntity.Columns.FirstOrDefault(it => it.PropertyName == fkFieldName).DbColumnName; + var fks = this._Context.Queryable() + .AS(thisEntity.DbTableName) + .In(fkName, ids.Distinct().ToList()).Select(fkDbColumnName).ToDataTable().Rows.Cast().Select(x => x[0]).ToArray(); + + var type = oneToMany.PropertyInfo.PropertyType.GenericTypeArguments[0]; + var entity = this._Context.EntityMaintenance.GetEntityInfo(type); + var id = oneToMany.Navigat.Name; + var column = entity.Columns.FirstOrDefault(it => it.PropertyName == id).DbColumnName; + + DeleteChild(fks, entity, column); + + this._Context.Deleteable() + .AS(entity.DbTableName) + .In(column, fks.Distinct().ToList()).ExecuteCommand(); + } + } + + private void DeleteChild(object[] fks, EntityInfo entity, string column) + { + var childs = entity.Columns.Where(it => it.Navigat != null && it.Navigat?.NavigatType == NavigateType.OneToMany).ToList(); + if (childs.Count != 0) + { + var pkColumn = entity.Columns.First(it => it.IsPrimarykey); + var pkIds = this._Context.Queryable() + .AS(entity.DbTableName) + .In(column, fks.Distinct().ToList()) + .Select(pkColumn.DbColumnName).ToDataTable().Rows + .Cast().Select(it => it[0]).ToList(); + DeleteChildChild(pkIds, childs); + } + } + + int childIndex = 0; + private void DeleteChildChild(List ids, List childs) + { + childIndex++; + if (childIndex > 4) + { + Check.ExceptionEasy("Removing too many levels", "安全机制限制删除脏数据层级不能超过7层"); + } + foreach (var columnInfo in childs) + { + var navigat = columnInfo.Navigat; + var type = columnInfo.PropertyInfo.PropertyType.GenericTypeArguments[0]; + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(type); + var fkColumn = thisEntity.Columns.FirstOrDefault(it => navigat.Name.EqualCase(it.PropertyName)); + var thisPkColumn = thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + var childs2 = thisEntity.Columns.Where(it => it.Navigat != null && it.Navigat?.NavigatType == NavigateType.OneToMany).ToList(); ; + if (childs2.Count != 0) + { + var pkIds = _Context.Queryable().AS(thisEntity.DbTableName) + .In(fkColumn.DbColumnName, ids) + .Select(thisPkColumn.DbColumnName).ToDataTable().Rows + .Cast().Select(it => it[0]).ToList(); + + DeleteChildChild(pkIds, childs2); + } + _Context.Deleteable().AS(thisEntity.DbTableName).In(fkColumn.DbColumnName, ids).ExecuteCommand(); + } + } + + private EntityColumnInfo GetParentPkColumn() + { + EntityColumnInfo parentPkColumn = _ParentPkColumn; + if (_ParentPkColumn == null) + { + parentPkColumn = _ParentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + return parentPkColumn; + } + private EntityColumnInfo GetParentPkNavColumn(EntityColumnInfo nav) + { + EntityColumnInfo result = null; + if (nav.Navigat.Name2.HasValue()) + { + result = _ParentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + } + return result; + } + + private void SetNewParent(EntityInfo entityInfo, EntityColumnInfo entityColumnInfo) where TChild : class, new() + { + this._ParentEntity = entityInfo; + this._ParentPkColumn = entityColumnInfo; + } + + public List GetNoExistsId(List old, List newList, string pkName) + { + List result = new List(); + + // 将newList中的主键属性转换为字符串集合 + var newIds = newList.Select(item => GetPropertyValueAsString(item, pkName)).ToList(); + + // 获取在old中但不在newList中的主键属性值 + result = old.Where(item => !newIds.Contains(GetPropertyValueAsString(item, pkName))) + .ToList(); + + return result; + } + + // 获取对象的属性值 + private string GetPropertyValueAsString(TChild item, string propertyName) + { + var property = item.GetType().GetProperty(propertyName); + if (property != null) + { + return property.GetValue(item, null) + ""; + } + else + { + throw new ArgumentException($"Property '{propertyName}' not found on type {item.GetType().Name}"); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavOneToOne.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavOneToOne.cs new file mode 100644 index 000000000..74ca0750d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavOneToOne.cs @@ -0,0 +1,68 @@ +namespace SqlSugar +{ + public partial class UpdateNavProvider where T : class, new() where Root : class, new() + { + protected bool IsDeleted { get; set; } + private void UpdateOneToOne(string name, EntityColumnInfo nav) where TChild : class, new() + { + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var isManyPk = parentEntity.Columns.Count(it => it.IsPrimarykey) > 1; + var parentColumn = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + IsDeleted = thisEntity.Columns.Any(it => it.PropertyName.EqualCase("isdeleted") || it.PropertyName.EqualCase("isdelete")); + EntityColumnInfo thisPkColumn = GetPkColumnByNav(thisEntity, nav); + Check.ExceptionEasy(thisPkColumn == null, $" Navigate {parentEntity.EntityName} : {name} is error ", $"导航实体 {parentEntity.EntityName} 属性 {name} 配置错误"); + Check.ExceptionEasy(nav.Navigat.WhereSql.HasValue(), $" {name} Navigate(NavType,WhereSql) no support update ", $"导航一对一 {name} 配置了 Sql变量 不支持更新"); + List childList = new List(); + foreach (var parent in parentList) + { + var navPropertyValue = parentColumn.PropertyInfo.GetValue(parent); + var childItem = (TChild)nav.PropertyInfo.GetValue(parent); + if (childItem != null) + { + if (IsDefaultValue(navPropertyValue)) + { + var pkValue = thisPkColumn.PropertyInfo.GetValue(childItem); + if (IsDefaultValue(navPropertyValue)) + { + if (parentColumn.IsPrimarykey == false && isManyPk == false && parentColumn.IsIdentity == false) + { + this._Context.Updateable().AS(parentEntity.DbTableName) + .SetColumns(parentColumn.DbColumnName, pkValue) + .Where(parentPkColumn.DbColumnName, "=", parentPkColumn.PropertyInfo.GetValue(parent)).ExecuteCommand(); + } + navPropertyValue = pkValue; + } + + } + if (!IsDefaultValue(navPropertyValue) && isManyPk == false && parentPkColumn.IsIdentity == false) + { + this._Context.Updateable + ().AS(parentEntity.DbTableName) + .SetColumns(parentColumn.DbColumnName, navPropertyValue) + .Where(parentPkColumn.DbColumnName, "=", parentPkColumn.PropertyInfo.GetValue(parent)).ExecuteCommand(); + } + if (IsDefaultValue(navPropertyValue)) + { + InsertDatas(new List() { childItem }, thisPkColumn); + navPropertyValue = thisPkColumn.PropertyInfo.GetValue(childItem); + parentColumn.PropertyInfo.SetValue(parent, navPropertyValue); + this._Context.Updateable + ().AS(parentEntity.DbTableName) + .SetColumns(parentColumn.DbColumnName, navPropertyValue) + .Where(parentPkColumn.DbColumnName, "=", parentPkColumn.PropertyInfo.GetValue(parent)).ExecuteCommand(); + } + + thisPkColumn.PropertyInfo.SetValue(childItem, navPropertyValue); + childList.Add(childItem); + } + } + InsertDatas(childList, thisPkColumn); + this._ParentList = childList.Cast().ToList(); + SetNewParent(thisEntity, thisPkColumn); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavProvider.cs new file mode 100644 index 000000000..27e82e2cf --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavProvider.cs @@ -0,0 +1,230 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class UpdateNavProvider where T : class, new() where Root : class, new() + { + internal UpdateNavRootOptions _RootOptions { get; set; } + public List _Roots { get; set; } + public List _ParentList { get; set; } + public List _RootList { get; set; } + public EntityInfo _ParentEntity { get; set; } + public EntityColumnInfo _ParentPkColumn { get; set; } + public SqlSugarProvider _Context { get; set; } + + public UpdateNavOptions _Options { get; set; } + public bool IsFirst { get; set; } + public bool IsAsNav { get; set; } + internal NavContext NavContext { get; set; } + + public UpdateNavProvider AsNav() + { + return new UpdateNavProvider + { + _Context = _Context, + _ParentEntity = null, + _ParentList = null, + _Roots = _Roots, + _ParentPkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.First(it => it.IsPrimarykey) + }; + } + public UpdateNavProvider ThenInclude(Expression> expression) where TChild : class, new() + { + return _ThenInclude(expression); + } + + public UpdateNavProvider ThenInclude(Expression>> expression) where TChild : class, new() + { + return _ThenInclude(expression); + } + + public UpdateNavProvider ThenInclude(Expression> expression, UpdateNavOptions options) where TChild : class, new() + { + _Options = options; + return _ThenInclude(expression); + } + + public UpdateNavProvider ThenInclude(Expression>> expression, UpdateNavOptions options) where TChild : class, new() + { + _Options = options; + return _ThenInclude(expression); + } + + private UpdateNavProvider _ThenInclude(Expression> expression) where TChild : class, new() + { + var isRoot = _RootList == null; + IsFirst = isRoot && this._ParentList == null; + InitParentList(); + var name = ExpressionTool.GetMemberName(expression); + var nav = this._ParentEntity.Columns.FirstOrDefault(x => x.PropertyName == name); + if (nav.Navigat == null) + { + Check.ExceptionEasy($"{name} no navigate attribute", $"{this._ParentEntity.EntityName}的属性{name}没有导航属性"); + } + if (_RootOptions?.IsDisableUpdateRoot == true) + { + //Future + } + else + { + + UpdateRoot(isRoot, nav); + } + IsFirst = false; + if (nav.Navigat.NavigatType == NavigateType.OneToOne || nav.Navigat.NavigatType == NavigateType.ManyToOne) + { + UpdateOneToOne(name, nav); + } + else if (nav.Navigat.NavigatType == NavigateType.OneToMany) + { + UpdateOneToMany(name, nav); + } + else + { + UpdateManyToMany(name, nav); + } + AddContextInfo(name, isRoot); + return GetResult(); + } + private UpdateNavProvider _ThenInclude(Expression>> expression) where TChild : class, new() + { + var isRoot = _RootList == null; + IsFirst = isRoot && this._ParentList == null; + InitParentList(); + var name = ExpressionTool.GetMemberName(expression); + if (name == null) + { + name = ExpressionTool.GetMemberNameByMethod(expression, name); + } + var nav = this._ParentEntity.Columns.FirstOrDefault(x => x.PropertyName == name); + if (nav.Navigat == null) + { + Check.ExceptionEasy($"{name} no navigate attribute", $"{this._ParentEntity.EntityName}的属性{name}没有导航属性"); + } + UpdateRoot(isRoot, nav); + IsFirst = false; + if (nav.Navigat.NavigatType == NavigateType.OneToOne || nav.Navigat.NavigatType == NavigateType.ManyToOne) + { + UpdateOneToOne(name, nav); + } + else if (nav.Navigat.NavigatType == NavigateType.OneToMany) + { + UpdateOneToMany(name, nav); + } + else + { + UpdateManyToMany(name, nav); + } + AddContextInfo(name, isRoot); + return GetResult(); + } + private void UpdateRoot(bool isRoot, EntityColumnInfo nav) + { + if (isRoot && nav.Navigat.NavigatType != NavigateType.ManyToMany && _RootOptions?.IsDisableUpdateRoot != true) + { + UpdateRoot(); + } + else if (isRoot && _RootOptions?.IsInsertRoot == true && nav.Navigat.NavigatType == NavigateType.ManyToMany) + { + UpdateRoot(); + } + else + { + if (_Options?.ManyToManyIsUpdateA == true) + { + UpdateRoot(); + } + } + } + + private void UpdateRoot() + { + if (IsAsNav) + { + return; + } + if (_Options?.RootFunc != null) + { + var updateable = this._Context.Updateable(_Roots); + var exp = _Options.RootFunc as Expression>>; + Check.ExceptionEasy(exp == null, "UpdateOptions.RootFunc is error", "UpdateOptions.RootFunc"); + var com = exp.Compile(); + com(updateable); + updateable.ExecuteCommand(); + } + else if (IsFirst && _RootOptions != null) + { + var isInsert = _RootOptions.IsInsertRoot; + if (isInsert) + { + var newRoots = new List(); + foreach (var item in _Roots) + { + var x = this._Context.Storageable(item).ToStorage(); + if (x.InsertList.HasValue()) + { + newRoots.Add(x.AsInsertable.IgnoreColumns(_RootOptions.IgnoreInsertColumns).EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData).ExecuteReturnEntity()); + } + else + { + x.AsUpdateable + .EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData) + .UpdateColumns(_RootOptions.UpdateColumns) + .IgnoreColumns(_RootOptions.IgnoreColumns) + .IgnoreNullColumns(_RootOptions.IsIgnoreAllNullColumns) + .ExecuteCommandWithOptLockIF(_RootOptions?.IsOptLock, _RootOptions?.IsOptLock); + newRoots.Add(item); + } + } + _ParentList = _RootList = newRoots.Cast().ToList(); + } + else + { + if (_Roots.Count == 1 && _RootOptions?.IsOptLock == true) + { + this._Context.Updateable(_Roots.First()) + .EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData) + .UpdateColumns(_RootOptions.UpdateColumns) + .IgnoreColumns(_RootOptions.IgnoreColumns) + .IgnoreNullColumns(_RootOptions.IsIgnoreAllNullColumns) + .ExecuteCommandWithOptLockIF(_RootOptions?.IsOptLock, _RootOptions?.IsOptLock); + } + else + { + this._Context.Updateable(_Roots) + .EnableDiffLogEventIF(_RootOptions.IsDiffLogEvent, _RootOptions.DiffLogBizData) + .UpdateColumns(_RootOptions.UpdateColumns) + .IgnoreColumns(_RootOptions.IgnoreColumns) + .IgnoreNullColumns(_RootOptions.IsIgnoreAllNullColumns) + .ExecuteCommandWithOptLockIF(_RootOptions?.IsOptLock, _RootOptions?.IsOptLock); + } + } + } + else if (_RootOptions != null && _RootOptions?.IsDiffLogEvent == true) + { + this._Context.Updateable(_Roots).EnableDiffLogEvent(_RootOptions.DiffLogBizData).ExecuteCommand(); + } + else + { + this._Context.Updateable(_Roots).ExecuteCommand(); + } + } + + private void AddContextInfo(string name, bool isRoot) + { + if (IsAsNav || isRoot) + { + if (this.NavContext?.Items != null) + { + this.NavContext.Items.Add(new NavContextItem() { Level = 0, RootName = name }); + } + } + } + private bool NotAny(string name) + { + if (IsFirst) return true; + if (this.NavContext == null) return true; + return this.NavContext?.Items?.Any(it => it.RootName == name) == false; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavProviderHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavProviderHelper.cs new file mode 100644 index 000000000..a12f57594 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavProviderHelper.cs @@ -0,0 +1,198 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class UpdateNavProvider where T : class, new() where Root : class, new() + { + + private static bool IsDefaultValue(object pvValue) + { + return pvValue?.Equals(UtilMethods.GetDefaultValue(pvValue.GetType())) != false; + } + private void InitParentList() + { + if (_RootList == null) + { + _RootList = _ParentList = _Roots.Cast().ToList(); + _ParentEntity = this._Context.EntityMaintenance.GetEntityInfo(); + } + else if (_ParentList == null) + { + _ParentList = _RootList; + var pkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(it => it.IsPrimarykey); + this._ParentPkColumn = pkColumn; + } + } + + private UpdateNavProvider GetResult() where TChild : class, new() + { + return new UpdateNavProvider() + { + _Context = this._Context, + _ParentEntity = this._ParentEntity, + _ParentList = this._ParentList, + _Roots = this._Roots, + _ParentPkColumn = this._ParentPkColumn, + _RootList = this._RootList + }; + } + + + private void InsertIdentity(List datas) where Type : class, new() + { + foreach (var item in datas) + { + this._Context.Insertable(item).ExecuteCommandIdentityIntoEntity(); + } + } + + private EntityColumnInfo GetPkColumnByNav(EntityInfo entity, EntityColumnInfo nav) + { + var pkColumn = entity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + if (nav.Navigat.Name2.HasValue()) + { + pkColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + } + return pkColumn; + } + private EntityColumnInfo GetPkColumnByNav2(EntityInfo entity, EntityColumnInfo nav) + { + var pkColumn = entity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + return pkColumn; + } + private EntityColumnInfo GetFKColumnByNav(EntityInfo entity, EntityColumnInfo nav) + { + var fkColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + return fkColumn; + } + private void InsertDatas(List children, EntityColumnInfo pkColumn, EntityColumnInfo NavColumn = null) where TChild : class, new() + { + children = children.Distinct().ToList(); + Check.ExceptionEasy(pkColumn == null, typeof(TChild).Name + " has no primary key", typeof(TChild).Name + "没有主键"); + var whereName = pkColumn.PropertyName; + if (_Options?.OneToOneSaveByPrimaryKey == true && pkColumn.IsPrimarykey == false) + { + var newPkColumn = this._Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(it => it.IsPrimarykey); + if (newPkColumn != null) + { + whereName = newPkColumn.PropertyName; + } + } +; var x = this._Context.Storageable(children).WhereColumns(new string[] { whereName }).ToStorage(); + var insertData = x.InsertList.Select(it => it.Item).ToList(); + var updateData = x.UpdateList.Select(it => it.Item).ToList(); + Check.ExceptionEasy(pkColumn == null && NavColumn == null, $"The entity is invalid", $"实体错误无法使用导航"); + if (_Options?.CurrentFunc != null) + { + var updateable = x.AsUpdateable; + var exp = _Options.CurrentFunc as Expression>>; + Check.ExceptionEasy(exp == null, "UpdateOptions.CurrentFunc is error", "UpdateOptions.CurrentFunc参数设置错误"); + var com = exp.Compile(); + com(updateable); + if (IsDeleted) + { + updateable.PageSize(1).EnableQueryFilter().ExecuteCommand(); + } + else + { + updateable.ExecuteCommand(); + } + } + else if (pkColumn.IsPrimarykey == false) + { + var pk = this._Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey); + List ignoreColumns = new List(); + if (_Options?.IgnoreColumns != null) + { + ignoreColumns.AddRange(_Options.IgnoreColumns); + } + if (pk.Any()) + { + ignoreColumns.AddRange(pk.Select(it => it.PropertyName)); + } + if (_Options?.OneToOneSaveByPrimaryKey == true) + { + ignoreColumns = ignoreColumns.Where(it => it != whereName).ToList(); + } + if (IsDeleted) + { + x.AsUpdateable.IgnoreColumns(ignoreColumns.ToArray()).PageSize(1).EnableQueryFilter().ExecuteCommand(); + } + else + { + x.AsUpdateable.IgnoreColumns(ignoreColumns.ToArray()).ExecuteCommand(); + } + } + else + { + var ignoreColumns = _Options?.IgnoreColumns; + var isIgnoreNull = _Options?.IgnoreNullColumns == true; + if (IsDeleted) + { + x.AsUpdateable.IgnoreNullColumns(isIgnoreNull).IgnoreColumns(ignoreColumns?.ToArray()).PageSize(1).EnableQueryFilter().ExecuteCommand(); + } + else + { + x.AsUpdateable.IgnoreNullColumns(isIgnoreNull).IgnoreColumns(ignoreColumns?.ToArray()).ExecuteCommand(); + } + } + InitData(pkColumn, insertData); + if (_NavigateType == NavigateType.OneToMany) + { + this._ParentList = children.Cast().ToList(); + } + else + { + this._ParentList = insertData.Union(updateData).Cast().ToList(); + } + } + + private void InitData(EntityColumnInfo pkColumn, List UpdateData) where TChild : class, new() + { + if (pkColumn.IsIdentity || pkColumn.OracleSequenceName.HasValue()) + { + InsertIdentity(UpdateData); + } + else if (pkColumn.UnderType == UtilConstants.LongType) + { + SetValue(pkColumn, UpdateData, () => SnowFlakeSingle.Instance.NextId()); + } + else if (pkColumn.UnderType == UtilConstants.GuidType) + { + SetValue(pkColumn, UpdateData, () => Guid.NewGuid()); + } + else if (pkColumn.UnderType == UtilConstants.StringType) + { + SetValue(pkColumn, UpdateData, () => Guid.NewGuid().ToString()); + } + else + { + SetError(pkColumn, UpdateData); + } + } + + private void SetValue(EntityColumnInfo pkColumn, List UpdateData, Func value) where TChild : class, new() + { + foreach (var child in UpdateData) + { + if (IsDefaultValue(pkColumn.PropertyInfo.GetValue(child))) + { + pkColumn.PropertyInfo.SetValue(child, value()); + } + } + this._Context.Insertable(UpdateData).ExecuteCommand(); + } + private void SetError(EntityColumnInfo pkColumn, List UpdateData) where TChild : class, new() + { + foreach (var child in UpdateData) + { + if (IsDefaultValue(pkColumn.PropertyInfo.GetValue(child))) + { + var name = pkColumn.EntityName + " " + pkColumn.DbColumnName; + Check.ExceptionEasy($"The field {name} is not an autoassignment type and requires an assignment", $"字段{name}不是可自动赋值类型,需要赋值 , 可赋值类型有 自增、long、Guid、string"); + } + } + this._Context.Insertable(UpdateData).ExecuteCommand(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavTask.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavTask.cs new file mode 100644 index 000000000..751600b3d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExecuteNavProvider/UpdateNavTask.cs @@ -0,0 +1,226 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class UpdateNavTaskInit where T : class, new() where Root : class, new() + { + + internal SqlSugarProvider Context { get; set; } + internal UpdateNavProvider UpdateNavProvider { get; set; } + internal NavContext NavContext { get; set; } + + public UpdateNavTask Include(Expression> expression) where TChild : class, new() + { + this.Context = UpdateNavProvider._Context; + UpdateNavProvider.NavContext = this.NavContext; + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => UpdateNavProvider.ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public UpdateNavTask Include(Expression>> expression) where TChild : class, new() + { + this.Context = UpdateNavProvider._Context; + UpdateNavProvider.NavContext = this.NavContext; + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => UpdateNavProvider.ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = UpdateNavProvider.NavContext; + return result; + } + + public UpdateNavTask Include(Expression> expression, UpdateNavOptions options) where TChild : class, new() + { + this.Context = UpdateNavProvider._Context; + UpdateNavProvider.NavContext = this.NavContext; + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => UpdateNavProvider.ThenInclude(expression, options); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = UpdateNavProvider.NavContext; + return result; + } + public UpdateNavTask Include(Expression>> expression, UpdateNavOptions options) where TChild : class, new() + { + this.Context = UpdateNavProvider._Context; + UpdateNavProvider.NavContext = this.NavContext; + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => UpdateNavProvider.ThenInclude(expression, options); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = UpdateNavProvider.NavContext; + return result; + } + public UpdateNavMethodInfo IncludesAllFirstLayer(params string[] ignoreColumns) + { + if (ignoreColumns == null) + { + ignoreColumns = Array.Empty(); + } + this.Context = UpdateNavProvider._Context; + var navColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !ignoreColumns.Contains(it.PropertyName) || !ignoreColumns.Any(z => z.EqualCase(it.DbColumnName))).Where(it => it.Navigat != null).ToList(); + var updateNavs = this; + UpdateNavMethodInfo methodInfo = updateNavs.IncludeByNameString(navColumns[0].PropertyName); + foreach (var item in navColumns.Skip(1)) + { + methodInfo = methodInfo.IncludeByNameString(item.PropertyName); + } + return methodInfo; + } + + public UpdateNavMethodInfo IncludesAllFirstLayer(UpdateNavOptions updateNavOptions, params string[] ignoreColumns) + { + if (ignoreColumns == null) + { + ignoreColumns = Array.Empty(); + } + this.Context = UpdateNavProvider._Context; + var navColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !ignoreColumns.Contains(it.PropertyName) || !ignoreColumns.Any(z => z.EqualCase(it.DbColumnName))).Where(it => it.Navigat != null).ToList(); + var updateNavs = this; + UpdateNavMethodInfo methodInfo = updateNavs.IncludeByNameString(navColumns[0].PropertyName); + foreach (var item in navColumns.Skip(1)) + { + methodInfo = methodInfo.IncludeByNameString(item.PropertyName, updateNavOptions); + } + return methodInfo; + } + public UpdateNavMethodInfo IncludeByNameString(string navMemberName, UpdateNavOptions updateNavOptions = null) + { + UpdateNavMethodInfo result = new UpdateNavMethodInfo(); + result.Context = UpdateNavProvider._Context; + var entityInfo = result.Context.EntityMaintenance.GetEntityInfo(); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.GetType().GetMyMethod("Include", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this, new object[] { exp, updateNavOptions }); + result.MethodInfos = obj; + return result; + } + + + } + public class UpdateNavTask where T : class, new() where Root : class, new() + { + public SqlSugarProvider Context { get; set; } + public Func> PreFunc { get; set; } + internal NavContext NavContext { get; set; } + + + #region +1 + public UpdateNavTask ThenInclude(Expression> expression) where TChild : class, new() + { + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => PreFunc().ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public UpdateNavTask ThenInclude(Expression>> expression) where TChild : class, new() + { + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => PreFunc().ThenInclude(expression); + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + public UpdateNavTask Include(Expression> expression) where TChild : class, new() + { + return AsNav().ThenInclude(expression); + } + public UpdateNavTask Include(Expression>> expression) where TChild : class, new() + { + return AsNav().ThenInclude(expression); + } + + #endregion + + + #region +2 + public UpdateNavTask ThenInclude(Expression> expression, UpdateNavOptions options) where TChild : class, new() + { + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => + { + var nav = PreFunc().ThenInclude(expression, options); + nav.NavContext = this.NavContext; + return nav; + }; + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public UpdateNavTask ThenInclude(Expression>> expression, UpdateNavOptions options) where TChild : class, new() + { + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => + { + var nav = PreFunc().ThenInclude(expression, options); + result.NavContext = this.NavContext; + return nav; + }; + result.PreFunc = func; + result.Context = this.Context; + return result; + } + public UpdateNavTask Include(Expression> expression, UpdateNavOptions options) where TChild : class, new() + { + return AsNav().ThenInclude(expression, options); + } + public UpdateNavTask Include(Expression>> expression, UpdateNavOptions options) where TChild : class, new() + { + return AsNav().ThenInclude(expression, options); + } + #endregion + + + public bool ExecuteCommand() + { + var hasTran = this.Context.Ado.Transaction != null; + if (hasTran) + { + PreFunc(); + } + else + { + this.Context.Ado.UseTran(() => + { + PreFunc(); + }, ex => throw ex); + } + return true; + } + public async Task ExecuteCommandAsync() + { + await Task.Run(async () => + { + ExecuteCommand(); + await Task.Delay(0).ConfigureAwait(false); + }).ConfigureAwait(false); + return true; + } + + private UpdateNavTask AsNav() + { + UpdateNavTask result = new UpdateNavTask(); + Func> func = () => + { + var navres = PreFunc().AsNav(); + navres.IsAsNav = true; + navres.NavContext = this.NavContext; + return navres; + }; + result.PreFunc = func; + result.Context = this.Context; + result.NavContext = this.NavContext; + return result; + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExpressionableProvider/Expressionable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExpressionableProvider/Expressionable.cs new file mode 100644 index 000000000..3fafadf50 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/ExpressionableProvider/Expressionable.cs @@ -0,0 +1,585 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class Expressionable where T : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = it => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5) => true; + return _exp; + } + } + + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6, t7) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6, t7, t8) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6, t7, t8, t9) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6, t7, t8, t9, t10) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6, t7, t8, t9, t10, t11) => true; + return _exp; + } + } + public class Expressionable where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() + { + Expression> _exp = null; + + public Expressionable And(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable AndIF(bool isAnd, Expression> exp) + { + if (isAnd) + And(exp); + return this; + } + + public Expressionable Or(Expression> exp) + { + if (_exp == null) + _exp = exp; + else + _exp = Expression.Lambda>(Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters); + return this; + } + + public Expressionable OrIF(bool isOr, Expression> exp) + { + if (isOr) + Or(exp); + return this; + } + + + public Expression> ToExpression() + { + if (_exp == null) + _exp = (it, t2, t3, t4, T5, t6, t7, t8, t9, t10, t11, t12) => true; + return _exp; + } + } + public static class Expressionable + { + public static Expressionable Create() where T : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() where T10 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() where T10 : class, new() where T11 : class, new() + { + return new Expressionable(); + } + public static Expressionable Create() where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() where T5 : class, new() where T6 : class, new() where T7 : class, new() where T8 : class, new() where T9 : class, new() where T10 : class, new() where T11 : class, new() where T12 : class, new() + { + return new Expressionable(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/FastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/FastBuilder.cs new file mode 100644 index 000000000..43e8d30ec --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/FastBuilder.cs @@ -0,0 +1,72 @@ +using System.Data; + +namespace SqlSugar +{ + public class FastBuilder + { + public EntityInfo FastEntityInfo { get; set; } + public virtual bool IsActionUpdateColumns { get; set; } + public virtual DbFastestProperties DbFastestProperties { get; set; } + public SqlSugarProvider Context { get; set; } + public virtual string CharacterSet { get; set; } + public virtual string UpdateSql { get; set; } = @"UPDATE TM + SET {0} + FROM {1} TM + INNER JOIN {2} TE ON {3} "; + + + public virtual void CloseDb() + { + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) + { + this.Context.Ado.Connection.Close(); + } + } + + public virtual async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlbuilder = this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(updateColumns.Length == 0, "update columns count is 0"); + Check.ArgumentNullException(whereColumns.Length == 0, "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"TM.{sqlbuilder.GetTranslationColumnName(it)}=TE.{sqlbuilder.GetTranslationColumnName(it)}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"TM.{sqlbuilder.GetTranslationColumnName(it)}=TE.{sqlbuilder.GetTranslationColumnName(it)}")); + string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + return await Context.Ado.ExecuteCommandAsync(sql).ConfigureAwait(false); + } + + public virtual async Task CreateTempAsync(DataTable dt) where T : class, new() + { + var sqlbuilder = this.Context.Queryable().SqlBuilder; + await Context.UnionAll( + Context.Queryable().Filter(null, true).Select(string.Join(",", dt.Columns.Cast().Select(it => sqlbuilder.GetTranslationColumnName(it.ColumnName)))).Where(it => false).AS(dt.TableName), + Context.Queryable().Filter(null, true).Select(string.Join(",", dt.Columns.Cast().Select(it => sqlbuilder.GetTranslationColumnName(it.ColumnName)))).Where(it => false).AS(dt.TableName)).Select("top 1 * into #temp").ToListAsync().ConfigureAwait(false); + dt.TableName = "#temp"; + } + + public async virtual Task Merge(string tableName, DataTable dt, EntityInfo entityInfo, string[] whereColumns, string[] updateColumns, List datas) where T : class, new() + { + var result = 0; + var pageSize = 2000; + if (dt.Columns.Count > 100) + { + pageSize = 100; + } + else if (dt.Columns.Count > 50) + { + pageSize = 300; + } + else if (dt.Columns.Count > 30) + { + pageSize = 500; + } + await Context.Utilities.PageEachAsync(datas, pageSize, async pageItems => + { + var x = await Context.Storageable(pageItems).As(tableName).WhereColumns(whereColumns).ToStorageAsync().ConfigureAwait(false); + result += await x.BulkCopyAsync().ConfigureAwait(false); + result += await x.BulkUpdateAsync(updateColumns).ConfigureAwait(false); + return result; + }).ConfigureAwait(false); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/FastestProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/FastestProvider.cs new file mode 100644 index 000000000..0c6ec9804 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/FastestProvider.cs @@ -0,0 +1,540 @@ +using System.Data; +using System.Reflection; +namespace SqlSugar +{ + public partial class FastestProvider : IFastest where T : class, new() + { + internal SqlSugarProvider context; + private ISugarQueryable queryable; + private EntityInfo entityInfo { get; set; } + public bool isLog; + public FastestProvider(SqlSugarProvider sqlSugarProvider) + { + this.context = sqlSugarProvider; + this.queryable = this.context.Queryable(); + entityInfo = this.context.EntityMaintenance.GetEntityInfo(); + } + + #region BulkCopy + public int BulkCopy(string tableName, DataTable dt) + { + return BulkCopyAsync(tableName, dt).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public int BulkCopy(DataTable dt) + { + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + return BulkCopyAsync(this.AsName, dt).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public Task BulkCopyAsync(DataTable dt) + { + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + return BulkCopyAsync(this.AsName, dt); + } + public async Task BulkCopyAsync(string tableName, DataTable dt) + { + if (Size > 0) + { + int resul = 0; + await context.Utilities.PageEachAsync(dt.Rows.Cast().ToList(), Size, async item => + { + resul += await _BulkCopy(tableName, item.CopyToDataTable()).ConfigureAwait(false); + }).ConfigureAwait(false); + return resul; + } + else + { + return await _BulkCopy(tableName, dt).ConfigureAwait(false); + } + } + public int BulkCopy(List datas) + { + return BulkCopyAsync(datas).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public async Task BulkCopyAsync(List datas) + { + if (Size > 0) + { + if (this.GetBuider()?.DbFastestProperties?.NoPage == true) + { + Size = int.MaxValue / 2; + } + int resul = 0; + await context.Utilities.PageEachAsync(datas, Size, async item => + { + resul += await _BulkCopy(item).ConfigureAwait(false); + }).ConfigureAwait(false); + return resul; + } + else + { + return await _BulkCopy(datas).ConfigureAwait(false); + } + } + #endregion + + #region BulkUpdate + public int BulkUpdate(List datas) + { + return BulkUpdateAsync(datas).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public async Task BulkUpdateAsync(List datas) + { + var whereColumns = entityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); + var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); + return await BulkUpdateAsync(datas, whereColumns, updateColumns).ConfigureAwait(false); + } + public int BulkUpdate(List datas, string[] whereColumns, string[] updateColumns) + { + whereColumns = whereColumns.Select(x => this.entityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(x) || it.DbColumnName.EqualCase(x))?.DbColumnName ?? x).ToArray(); + updateColumns = updateColumns.Select(x => this.entityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(x) || it.DbColumnName.EqualCase(x))?.DbColumnName ?? x).ToArray(); + return BulkUpdateAsync(datas, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); + } + + public int BulkUpdate(List datas, string[] whereColumns) + { + return BulkUpdateAsync(datas, whereColumns).GetAwaiter().GetResult(); + } + + public async Task BulkUpdateAsync(List datas, string[] whereColumns) + { + whereColumns = whereColumns.Select(x => this.entityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(x) || it.DbColumnName.EqualCase(x))?.DbColumnName ?? x).ToArray(); + var updateColumns = this.entityInfo.Columns + .Where(it => !whereColumns.Any(z => z.EqualCase(it.DbColumnName))) + .Where(it => !it.IsIdentity) + .Where(it => !it.IsPrimarykey) + .Where(it => !it.IsOnlyIgnoreUpdate) + .Where(it => !it.IsIgnore) + .Select(it => it.DbColumnName) + .ToArray(); + return await BulkUpdateAsync(datas, whereColumns, updateColumns).ConfigureAwait(true); + } + public async Task BulkUpdateAsync(List datas, string[] whereColumns, string[] updateColumns) + { + + if (Size > 0) + { + int resul = 0; + await context.Utilities.PageEachAsync(datas, Size, async item => + { + resul += await _BulkUpdate(item, whereColumns, updateColumns).ConfigureAwait(false); + }).ConfigureAwait(false); + return resul; + } + else + { + return await _BulkUpdate(datas, whereColumns, updateColumns).ConfigureAwait(false); + } + } + + public int BulkUpdate(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns) + { + return BulkUpdateAsync(tableName, dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public int BulkUpdate(DataTable dataTable, string[] whereColumns, string[] updateColumns) + { + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + return BulkUpdateAsync(this.AsName, dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public int BulkUpdate(DataTable dataTable, string[] whereColumns) + { + string[] updateColumns = dataTable.Columns.Cast().Select(it => it.ColumnName).Where(it => !whereColumns.Any(z => z.EqualCase(it))).ToArray(); + whereColumns = dataTable.Columns.Cast().Select(it => it.ColumnName).Where(it => whereColumns.Any(z => z.EqualCase(it))).ToArray(); + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + return BulkUpdateAsync(this.AsName, dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); + } + public Task BulkUpdateAsync(DataTable dataTable, string[] whereColumns) + { + string[] updateColumns = dataTable.Columns.Cast().Select(it => it.ColumnName).Where(it => !whereColumns.Any(z => z.EqualCase(it))).ToArray(); + whereColumns = dataTable.Columns.Cast().Select(it => it.ColumnName).Where(it => whereColumns.Any(z => z.EqualCase(it))).ToArray(); + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + return BulkUpdateAsync(this.AsName, dataTable, whereColumns, updateColumns); + } + public async Task BulkUpdateAsync(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns) + { + + if (Size > 0) + { + int resul = 0; + await context.Utilities.PageEachAsync(dataTable.Rows.Cast().ToList(), Size, async item => + { + resul += await _BulkUpdate(tableName, item.CopyToDataTable(), whereColumns, updateColumns).ConfigureAwait(false); + }).ConfigureAwait(false); + return resul; + } + else + { + return await _BulkUpdate(tableName, dataTable, whereColumns, updateColumns).ConfigureAwait(false); + } + } + #endregion + + #region BulkMerge + public Task BulkMergeAsync(List datas) + { + var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); + var whereColumns = entityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); ; + return BulkMergeAsync(datas, whereColumns, updateColumns); + } + public int BulkMerge(List datas) + { + return BulkMergeAsync(datas).GetAwaiter().GetResult(); + } + public int BulkMerge(DataTable dataTable, string[] whereColumns, bool isIdentity) + { + object newValue, fastestMethod; + MethodInfo bulkCopyMethod; + _BulkMerge(dataTable, whereColumns, out newValue, out fastestMethod, out bulkCopyMethod, false, isIdentity); + var result = (int)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue }); + return result; + } + public Task BulkMergeAsync(DataTable dataTable, string[] whereColumns, bool isIdentity) + { + object newValue, fastestMethod; + MethodInfo bulkCopyMethod; + _BulkMerge(dataTable, whereColumns, out newValue, out fastestMethod, out bulkCopyMethod, true, isIdentity); + var result = (Task)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue }); + return result; + } + public int BulkMerge(DataTable dataTable, string[] whereColumns, string[] updateColumns, bool isIdentity) + { + return BulkMergeAsync(dataTable, whereColumns, updateColumns, isIdentity).GetAwaiter().GetResult(); + } + public Task BulkMergeAsync(DataTable dataTable, string[] whereColumns, string[] updateColumns, bool isIdentity) + { + object newValue, fastestMethod; + MethodInfo bulkCopyMethod; + _BulkMerge(dataTable, whereColumns, updateColumns, out newValue, out fastestMethod, out bulkCopyMethod, true, isIdentity); + var result = (Task)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue, whereColumns, updateColumns }); + return result; + } + public Task BulkMergeAsync(List datas, string[] whereColumns) + { + var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); + return BulkMergeAsync(datas, whereColumns, updateColumns); + } + public int BulkMerge(List datas, string[] whereColumns) + { + return BulkMergeAsync(datas, whereColumns).GetAwaiter().GetResult(); + } + public async Task BulkMergeAsync(List datas, string[] whereColumns, string[] updateColumns) + { + if (Size > 0) + { + int resul = 0; + await context.Utilities.PageEachAsync(datas, Size, async item => + { + resul += await _BulkMerge(item, updateColumns, whereColumns).ConfigureAwait(false); + }).ConfigureAwait(false); + return resul; + } + else + { + return await _BulkMerge(datas, updateColumns, whereColumns).ConfigureAwait(false); + } + } + public int BulkMerge(List datas, string[] whereColumns, string[] updateColumns) + { + return BulkMergeAsync(datas, whereColumns, updateColumns).GetAwaiter().GetResult(); + } + + private async Task _BulkMerge(List datas, string[] updateColumns, string[] whereColumns) + { + try + { + Begin(datas, false, true); + Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key"); + Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key"); + var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection; + this.context.CurrentConnectionConfig.IsAutoCloseConnection = false; + var old = this.context.Ado.IsDisableMasterSlaveSeparation; + this.context.Ado.IsDisableMasterSlaveSeparation = true; + DataTable dt = ToDdateTable(datas); + IFastBuilder buider = GetBuider(); + buider.Context = context; + if (buider?.DbFastestProperties?.IsMerge == true) + { + await buider.CreateTempAsync(dt).ConfigureAwait(false); + await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false); + } + var result = await buider.Merge(GetTableName(), dt, entityInfo, whereColumns, updateColumns, datas).ConfigureAwait(false); + //var queryTemp = this.context.Queryable().AS(dt.TableName).ToList();//test + //var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns); + if (buider?.DbFastestProperties?.IsMerge == true && this.context.CurrentConnectionConfig.DbType != DbType.Sqlite) + { + this.context.DbMaintenance.DropTable(dt.TableName); + } + this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + buider.CloseDb(); + End(datas, false, true); + this.context.Ado.IsDisableMasterSlaveSeparation = old; + return result; + } + catch (Exception) + { + this.context.Close(); + throw; + } + } + #endregion + + #region Core + private void _BulkMerge(DataTable dataTable, string[] whereColumns, out object newValue, out object fastestMethod, out MethodInfo bulkCopyMethod, bool isAsync, bool isIdentity) + { + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + var className = "BulkMerge_" + isIdentity + this.AsName.GetNonNegativeHashCodeString(); + var builder = this.context.DynamicBuilder().CreateClass(className, new SugarTable() + { + TableName = this.AsName + }); + foreach (DataColumn item in dataTable.Columns) + { + var isPrimaryKey = whereColumns.Any(it => it.EqualCase(item.ColumnName)); + var propertyType = item.DataType; + if (!propertyType.IsClass() && propertyType != typeof(string) && propertyType != typeof(byte[])) + { + propertyType = typeof(Nullable<>).MakeGenericType(UtilMethods.GetUnderType(item.DataType)); + } + builder.CreateProperty(item.ColumnName, propertyType, new SugarColumn() + { + IsPrimaryKey = isPrimaryKey, + IsIdentity = isIdentity && isPrimaryKey, + IsNullable = true, + + }); + } + var dicList = this.context.Utilities.DataTableToDictionaryList(dataTable); + var type = builder.WithCache().BuilderType(); + var value = this.context.DynamicBuilder().CreateObjectByType(type, dicList); + newValue = UtilMethods.ConvertToObjectList(type, value); + fastestMethod = this.context.GetType() + .GetMethod("Fastest") + .MakeGenericMethod(type) + .Invoke(this.context, null); + bulkCopyMethod = fastestMethod.GetType().GetMyMethod(isAsync ? "BulkMergeAsync" : "BulkMerge", 1); + } + private void _BulkMerge(DataTable dataTable, string[] whereColumns, string[] updateColumns, out object newValue, out object fastestMethod, out MethodInfo bulkCopyMethod, bool isAsync, bool isIdentity) + { + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + var className = "BulkMerge_" + isIdentity + this.AsName.GetNonNegativeHashCodeString(); + var builder = this.context.DynamicBuilder().CreateClass(className, new SugarTable() + { + TableName = this.AsName + }); + foreach (DataColumn item in dataTable.Columns) + { + var isPrimaryKey = whereColumns.Any(it => it.EqualCase(item.ColumnName)); + var propertyType = item.DataType; + if (!propertyType.IsClass() && propertyType != typeof(string) && propertyType != typeof(byte[])) + { + propertyType = typeof(Nullable<>).MakeGenericType(UtilMethods.GetUnderType(item.DataType)); + } + builder.CreateProperty(item.ColumnName, propertyType, new SugarColumn() + { + IsPrimaryKey = isPrimaryKey, + IsIdentity = isIdentity && isPrimaryKey, + IsNullable = true, + + }); + } + var dicList = this.context.Utilities.DataTableToDictionaryList(dataTable); + var type = builder.WithCache().BuilderType(); + var value = this.context.DynamicBuilder().CreateObjectByType(type, dicList); + newValue = UtilMethods.ConvertToObjectList(type, value); + fastestMethod = this.context.GetType() + .GetMethod("Fastest") + .MakeGenericMethod(type) + .Invoke(this.context, null); + bulkCopyMethod = fastestMethod.GetType().GetMyMethod(isAsync ? "BulkMergeAsync" : "BulkMerge", 3, newValue.GetType(), typeof(string[]), typeof(string[])); + } + + private async Task _BulkUpdate(List datas, string[] whereColumns, string[] updateColumns) + { + try + { + Begin(datas, false); + Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key"); + Check.Exception(updateColumns == null || updateColumns.Length == 0, "set columns count=0"); + var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection; + this.context.CurrentConnectionConfig.IsAutoCloseConnection = false; + var old = this.context.Ado.IsDisableMasterSlaveSeparation; + this.context.Ado.IsDisableMasterSlaveSeparation = true; + DataTable dt = ToDdateTable(datas); + IFastBuilder buider = GetBuider(); + ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns); + buider.Context = context; + await buider.CreateTempAsync(dt).ConfigureAwait(false); + await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false); + //var queryTemp = this.context.Queryable().AS(dt.TableName).ToList();//test + var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns).ConfigureAwait(false); + if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite) + { + this.context.DbMaintenance.DropTable(dt.TableName); + } + this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + buider.CloseDb(); + this.context.Ado.IsDisableMasterSlaveSeparation = old; + End(datas, false); + return result; + } + catch (Exception) + { + this.context.Close(); + throw; + } + } + + private void ActionIgnoreColums(string[] whereColumns, string[] updateColumns, DataTable dt, bool IsActionUpdateColumns) + { + if (entityInfo.Columns.Where(it => it.IsIgnore == false).Count() > whereColumns.Length + updateColumns.Length && IsActionUpdateColumns) + { + var ignoreColums = dt.Columns.Cast() + .Where(it => !whereColumns.Any(y => y.EqualCase(it.ColumnName))) + .Where(it => !updateColumns.Any(y => y.EqualCase(it.ColumnName))).ToList(); + foreach (DataRow item in dt.Rows) + { + foreach (var col in ignoreColums) + { + if (item[col.ColumnName].IsNullOrEmpty()) + { + if (col.DataType == UtilConstants.StringType) + { + item[col.ColumnName] = string.Empty; + if (this.queryable?.SqlBuilder?.SqlParameterKeyWord == ":") + { + item[col.ColumnName] = " "; + } + ; + } + else if (col.DataType == UtilConstants.DateType) + { + item[col.ColumnName] = UtilMethods.GetMinDate(this.context.CurrentConnectionConfig); + } + else + { + item[col.ColumnName] = Activator.CreateInstance(col.DataType); + } + } + } + } + } + } + + private async Task _BulkUpdate(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns) + { + var datas = new string[dataTable.Rows.Count].ToList(); + Begin(datas, false); + Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key"); + Check.Exception(updateColumns == null || updateColumns.Length == 0, "set columns count=0"); + var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection; + this.context.CurrentConnectionConfig.IsAutoCloseConnection = false; + var old = this.context.Ado.IsDisableMasterSlaveSeparation; + this.context.Ado.IsDisableMasterSlaveSeparation = true; + dataTable.TableName = this.queryable.SqlBuilder.GetTranslationTableName(tableName); + DataTable dt = GetCopyWriteDataTableUpdate(dataTable); + IFastBuilder buider = GetBuider(); + if (dt.Columns.Count != dataTable.Columns.Count) + { + ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns); + } + buider.Context = context; + if (buider.DbFastestProperties == null) + { + buider.DbFastestProperties = new DbFastestProperties(); + } + buider.DbFastestProperties.WhereColumns = whereColumns; + await buider.CreateTempAsync(dt).ConfigureAwait(false); + await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false); + //var queryTemp = this.context.Queryable().AS(dt.TableName).ToList();//test + var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns).ConfigureAwait(false); + if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite) + { + this.context.DbMaintenance.DropTable(dt.TableName); + } + this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + buider.CloseDb(); + this.context.Ado.IsDisableMasterSlaveSeparation = old; + End(datas, false); + return result; + } + private async Task _BulkCopy(List datas) + { + Begin(datas, true); + DataTable dt = ToDdateTable(datas); + IFastBuilder buider = GetBuider(); + buider.Context = context; + var result = await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false); + End(datas, true); + return result; + } + private async Task _BulkCopy(string tableName, DataTable dataTable) + { + var datas = new string[dataTable.Rows.Count].ToList(); + Begin(datas, true); + DataTable dt = dataTable; + dt.TableName = this.queryable.SqlBuilder.GetTranslationTableName(tableName); + dt = GetCopyWriteDataTable(dt); + IFastBuilder buider = GetBuider(); + buider.Context = context; + var result = await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false); + End(datas, true); + return result; + } + #endregion + + #region AOP + private void End(List datas, bool isAdd, bool isMerge = false) + { + var title = isAdd ? "BulkCopy" : "BulkUpdate"; + if (isMerge) + { + title = "BulkMerge"; + } + this.context.Ado.IsEnableLogEvent = isLog; + if (this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuted != null) + { + this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuted($"End {title} name:{GetTableName()} ,count: {datas.Count},current time: {DateTime.Now}", Array.Empty()); + } + RemoveCache(); + } + private void Begin(List datas, bool isAdd, bool isMerge = false) + { + var title = isAdd ? "BulkCopy" : "BulkUpdate"; + if (isMerge) + { + title = "BulkMerge"; + } + isLog = this.context.Ado.IsEnableLogEvent; + this.context.Ado.IsEnableLogEvent = false; + if (this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuting != null) + { + this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuting($"Begin {title} name:{GetTableName()} ,count: {datas.Count},current time: {DateTime.Now} ", Array.Empty()); + } + var dataEvent = this.context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (IsDataAop && dataEvent != null) + { + var entity = this.context.EntityMaintenance.GetEntityInfo(typeof(Type)); + foreach (var item in datas) + { + DataAop(item, isAdd + ? + DataFilterType.InsertByObject : + DataFilterType.UpdateByObject + , entity); + } + } + } + private void DataAop(Type item, DataFilterType type, EntityInfo entity) + { + var dataEvent = this.context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (dataEvent != null && item != null) + { + foreach (var columnInfo in entity.Columns) + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = type, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/Private.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/Private.cs new file mode 100644 index 000000000..3f8da4d43 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/Private.cs @@ -0,0 +1,350 @@ +using System.Data; + +namespace SqlSugar +{ + public partial class FastestProvider : IFastest where T : class, new() + { + private IFastBuilder GetBuider() + { + var className = string.Empty; + switch (this.context.CurrentConnectionConfig.DbType) + { + case DbType.MySql: + var result = new MySqlFastBuilder(); + result.CharacterSet = this.CharacterSet; + return result; + case DbType.SqlServer: + var result2 = new SqlServerFastBuilder(); + result2.DbFastestProperties.IsOffIdentity = this.IsOffIdentity; + return result2; + case DbType.Sqlite: + return new SqliteFastBuilder(this.entityInfo); + case DbType.Oracle: + return new OracleFastBuilder(this.entityInfo); + case DbType.PostgreSQL: + return new PostgreSQLFastBuilder(this.entityInfo); + case DbType.MySqlConnector: + var resultConnector = InstanceFactory.CreateInstance("SqlSugar.MySqlConnector.MySqlFastBuilder"); + resultConnector.CharacterSet = this.CharacterSet; + return resultConnector; + case DbType.Dm: + var result3 = new DmFastBuilder(); + result3.DbFastestProperties.IsOffIdentity = this.IsOffIdentity; + return result3; + case DbType.ClickHouse: + var resultConnectorClickHouse = InstanceFactory.CreateInstance("SqlSugar.ClickHouse.ClickHouseFastBuilder"); + resultConnectorClickHouse.CharacterSet = this.CharacterSet; + return resultConnectorClickHouse; + //case DbType.Kdbndp: + // break; + //case DbType.Oscar: + // break; + case DbType.QuestDB: + return new QuestDBFastBuilder(this.entityInfo); + case DbType.Custom: + className = InstanceFactory.CustomNamespace + "." + InstanceFactory.CustomDbName + "FastBuilder"; + break; + case DbType.GaussDBNative: + className = "SqlSugar.GaussDB.GaussDBFastBuilder"; + break; + default: + className = $"SqlSugar.{this.context.CurrentConnectionConfig.DbType.ToString().Replace("Native", "")}FastBuilder"; + break; + } + var reslut = InstanceFactory.CreateInstance(className); + reslut.CharacterSet = this.CharacterSet; + reslut.FastEntityInfo = this.entityInfo; + return reslut; + } + private DataTable ToDdateTable(List datas) + { + var builder = GetBuider(); + DataTable tempDataTable = ReflectionInoCore.GetInstance().GetOrCreate("BulkCopyAsync" + typeof(T).GetHashCode(), + () => + { + if (AsName == null) + { + return queryable.Where(it => false).Select("*").ToDataTable(); + } + else + { + return queryable.AS(AsName).Where(it => false).Select("*").ToDataTable(); + } + } + ); + var dt = new DataTable(); + List uInt64TypeName = new List(); + foreach (DataColumn item in tempDataTable.Columns) + { + if (item.DataType == typeof(UInt64)) + { + uInt64TypeName.Add(item.ColumnName); + } + if (item.DataType.Name == "ClickHouseDecimal") + { + dt.Columns.Add(item.ColumnName, typeof(decimal)); + } + else + { + dt.Columns.Add(item.ColumnName, item.DataType); + } + } + dt.TableName = GetTableName(); + var columns = entityInfo.Columns; + if (columns.Where(it => !it.IsIgnore).Count() > tempDataTable.Columns.Count) + { + var tempColumns = tempDataTable.Columns.Cast().Select(it => it.ColumnName); + columns = columns.Where(it => tempColumns.Any(s => s.EqualCase(it.DbColumnName))).ToList(); + } + var isMySql = this.context.CurrentConnectionConfig.DbType.IsIn(DbType.MySql, DbType.MySqlConnector); + var isSqliteCore = SugarCompatible.IsFramework == false && this.context.CurrentConnectionConfig.DbType.IsIn(DbType.Sqlite); + foreach (var item in datas) + { + var dr = dt.NewRow(); + foreach (var column in columns) + { + if (column.IsIgnore) + { + continue; + } + var name = column.DbColumnName; + if (name == null) + { + name = column.PropertyName; + } + var value = ValueConverter(column, GetValue(item, column)); + if (column.SqlParameterDbType != null && column.SqlParameterDbType is Type && UtilMethods.HasInterface((Type)column.SqlParameterDbType, typeof(ISugarDataConverter))) + { + var columnInfo = column; + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 }) as SugarParameter; + value = p.Value; + } + else if (isMySql && column.UnderType == UtilConstants.BoolType) + { + + if (value.ObjToBool() == false && uInt64TypeName.Any(z => z.EqualCase(column.DbColumnName))) + { + value = DBNull.Value; + } + } + else if (isSqliteCore && column.UnderType == UtilConstants.StringType && value is bool) + { + value = "isSqliteCore_" + value.ObjToString(); + } + else if (isSqliteCore && column.UnderType == UtilConstants.BoolType && value is bool) + { + value = Convert.ToBoolean(value) ? 1 : 0; + } + else if (column.UnderType == UtilConstants.DateTimeOffsetType && value != null && value != DBNull.Value) + { + if (builder.DbFastestProperties?.HasOffsetTime == true) + { + //Don't need to deal with + } + else + { + value = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + } + } + else if (value != DBNull.Value && value != null && column.UnderType?.FullName == "System.TimeOnly") + { + value = UtilMethods.TimeOnlyToTimeSpan(value); + } + else if (value != DBNull.Value && value != null && column.UnderType?.FullName == "System.DateOnly") + { + value = UtilMethods.DateOnlyToDateTime(value); + } + dr[name] = value; + } + dt.Rows.Add(dr); + } + + return dt; + } + private static object GetValue(T item, EntityColumnInfo column) + { + if (StaticConfig.EnableAot) + { + return column.PropertyInfo.GetValue(item); + } + else + { + return PropertyCallAdapterProvider.GetInstance(column.PropertyName).InvokeGet(item); + } + } + + private string GetTableName() + { + if (this.AsName.HasValue()) + { + return queryable.SqlBuilder.GetTranslationTableName(AsName); + } + else + { + return queryable.SqlBuilder.GetTranslationTableName(this.context.EntityMaintenance.GetTableName()); + } + } + private object ValueConverter(EntityColumnInfo columnInfo, object value) + { + if (value == null) + return DBNull.Value; + if (value is DateTime && (DateTime)value == DateTime.MinValue) + { + value = Convert.ToDateTime("1900-01-01"); + } + //else if (columnInfo.IsJson) + //{ + // columnInfo.IsJson = true; + //} + //else if (columnInfo.IsArray) + //{ + // columnInfo.IsArray = true; + //} + else if (columnInfo.UnderType.IsEnum()) + { + value = Convert.ToInt64(value); + } + else if (columnInfo.IsJson && value != null) + { + value = this.context.Utilities.SerializeObject(value); + } + else if (columnInfo.IsTranscoding && value.HasValue()) + { + value = UtilMethods.EncodeBase64(value.ToString()); + } + return value; + } + private DataTable GetCopyWriteDataTable(DataTable dt) + { + var builder = GetBuider(); + if (builder.DbFastestProperties?.IsConvertDateTimeOffsetToDateTime == true) + { + dt = UtilMethods.ConvertDateTimeOffsetToDateTime(dt); + } + if (builder.DbFastestProperties?.IsNoCopyDataTable == true) + { + return dt; + } + DataTable tempDataTable = null; + if (AsName == null) + { + tempDataTable = queryable.Clone().Where(it => false).Select("*").ToDataTable(); + } + else + { + tempDataTable = queryable.Clone().AS(AsName).Where(it => false).Select("*").ToDataTable(); + } + ; + List uInt64TypeName = new List(); + foreach (DataColumn item in tempDataTable.Columns) + { + if (item.DataType == typeof(UInt64)) + { + uInt64TypeName.Add(item.ColumnName); + } + } + var temColumnsList = tempDataTable.Columns.Cast().Select(it => it.ColumnName.ToLower()).ToList(); + var columns = dt.Columns.Cast().Where(it => temColumnsList.Contains(it.ColumnName.ToLower())).ToList(); + foreach (DataRow item in dt.Rows) + { + DataRow dr = tempDataTable.NewRow(); + foreach (DataColumn column in columns) + { + + dr[column.ColumnName] = item[column.ColumnName]; + if (dr[column.ColumnName] == null || dr[column.ColumnName] == DBNull.Value) + { + dr[column.ColumnName] = DBNull.Value; + } + else if (column.DataType == UtilConstants.BoolType && this.context.CurrentConnectionConfig.DbType.IsIn(DbType.MySql, DbType.MySqlConnector)) + { + if (Convert.ToBoolean(dr[column.ColumnName]) == false && uInt64TypeName.Any(z => z.EqualCase(column.ColumnName))) + { + dr[column.ColumnName] = DBNull.Value; + } + } + } + tempDataTable.Rows.Add(dr); + } + tempDataTable.TableName = dt.TableName; + return tempDataTable; + } + private DataTable GetCopyWriteDataTableUpdate(DataTable dt) + { + var sqlBuilder = this.context.Queryable().SqlBuilder; + var dts = dt.Columns.Cast().Select(it => sqlBuilder.GetTranslationColumnName(it.ColumnName)).ToList(); + DataTable tempDataTable = null; + if (AsName == null) + { + tempDataTable = queryable.Clone().Where(it => false).Select(string.Join(",", dts)).ToDataTable(); + } + else + { + tempDataTable = queryable.Clone().AS(AsName).Where(it => false).Select(string.Join(",", dts)).ToDataTable(); + } + ; + List uInt64TypeName = new List(); + foreach (DataColumn item in tempDataTable.Columns) + { + if (item.DataType == typeof(UInt64)) + { + uInt64TypeName.Add(item.ColumnName); + } + } + var temColumnsList = tempDataTable.Columns.Cast().Select(it => it.ColumnName.ToLower()).ToList(); + var columns = dt.Columns.Cast().Where(it => temColumnsList.Contains(it.ColumnName.ToLower())).ToList(); + foreach (DataRow item in dt.Rows) + { + DataRow dr = tempDataTable.NewRow(); + foreach (DataColumn column in columns) + { + + dr[column.ColumnName] = item[column.ColumnName]; + if (dr[column.ColumnName] == null || dr[column.ColumnName] == DBNull.Value) + { + dr[column.ColumnName] = DBNull.Value; + } + else if (column.DataType == UtilConstants.BoolType && this.context.CurrentConnectionConfig.DbType.IsIn(DbType.MySql, DbType.MySqlConnector)) + { + if (Convert.ToBoolean(dr[column.ColumnName]) == false && uInt64TypeName.Any(z => z.EqualCase(column.ColumnName))) + { + dr[column.ColumnName] = DBNull.Value; + } + } + } + tempDataTable.Rows.Add(dr); + } + tempDataTable.TableName = dt.TableName; + return tempDataTable; + } + + private void RemoveCache() + { + if (!string.IsNullOrEmpty(CacheKey) || !string.IsNullOrEmpty(CacheKeyLike)) + { + Check.Exception(this.context.CurrentConnectionConfig.ConfigureExternalServices?.DataInfoCacheService == null, "ConnectionConfig.ConfigureExternalServices.DataInfoCacheService is null"); + var service = this.context.CurrentConnectionConfig.ConfigureExternalServices?.DataInfoCacheService; + if (!string.IsNullOrEmpty(CacheKey)) + { + CacheSchemeMain.RemoveCache(service, CacheKey); + } + if (!string.IsNullOrEmpty(CacheKeyLike)) + { + CacheSchemeMain.RemoveCacheByLike(service, CacheKeyLike); + } + } + if (this.context.CurrentConnectionConfig?.MoreSettings?.IsAutoRemoveDataCache == true) + { + var cacheService = this.context.CurrentConnectionConfig?.ConfigureExternalServices?.DataInfoCacheService; + if (cacheService != null) + { + CacheSchemeMain.RemoveCache(cacheService, this.context.EntityMaintenance.GetTableName()); + } + } + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/Setting.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/Setting.cs new file mode 100644 index 000000000..a64f363a5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/Setting.cs @@ -0,0 +1,54 @@ +namespace SqlSugar +{ + public partial class FastestProvider : IFastest where T : class, new() + { + private string AsName { get; set; } + private int Size { get; set; } + private string CacheKey { get; set; } + private string CacheKeyLike { get; set; } + private string CharacterSet { get; set; } + private bool IsDataAop { get; set; } + private bool IsOffIdentity { get; set; } + public IFastest SetCharacterSet(string CharacterSet) + { + this.CharacterSet = CharacterSet; + return this; + } + public IFastest EnableDataAop() + { + this.IsDataAop = true; + return this; + } + public IFastest RemoveDataCache() + { + CacheKey = typeof(T).FullName; + return this; + } + public IFastest RemoveDataCache(string cacheKey) + { + CacheKeyLike = this.context.EntityMaintenance.GetTableName(); + return this; + } + public IFastest AS(string tableName) + { + this.AsName = tableName; + return this; + } + public IFastest PageSize(int size) + { + this.Size = size; + return this; + } + public IFastest OffIdentity() + { + this.IsOffIdentity = true; + return this; + } + public SplitFastest SplitTable() + { + SplitFastest result = new SplitFastest(); + result.FastestProvider = this; + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/SplitFastest.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/SplitFastest.cs new file mode 100644 index 000000000..60a54f47d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FastestProvider/SplitFastest.cs @@ -0,0 +1,141 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class SplitFastest where T : class, new() + { + public FastestProvider FastestProvider { get; set; } + public SqlSugarProvider Context { get { return this.FastestProvider.context; } } + public EntityInfo EntityInfo { get { return this.Context.EntityMaintenance.GetEntityInfo(); } } + public int BulkCopy(List datas) + { + if (StaticConfig.SplitTableCreateTableFunc != null) + { + StaticConfig.SplitTableCreateTableFunc(typeof(T), datas?.Cast()?.ToArray()); + } + List groupModels; + int result; + GroupDataList(datas, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + CreateTable(item.Key); + var addList = item.Select(it => it.Item).ToList(); + result += FastestProvider.AS(item.Key).BulkCopy(addList); + this.Context.MappingTables.Add(EntityInfo.EntityName, EntityInfo.DbTableName); + } + return result; + } + public async Task BulkCopyAsync(List datas) + { + if (StaticConfig.SplitTableCreateTableFunc != null) + { + StaticConfig.SplitTableCreateTableFunc(typeof(T), datas?.Cast()?.ToArray()); + } + List groupModels; + int result; + GroupDataList(datas, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + CreateTable(item.Key); + var addList = item.Select(it => it.Item).ToList(); + result += await FastestProvider.AS(item.Key).BulkCopyAsync(addList).ConfigureAwait(false); + this.Context.MappingTables.Add(EntityInfo.EntityName, EntityInfo.DbTableName); + } + return result; + } + + + public int BulkUpdate(List datas) + { + List groupModels; + int result; + GroupDataList(datas, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + CreateTable(item.Key); + var addList = item.Select(it => it.Item).ToList(); + result += FastestProvider.AS(item.Key).BulkUpdate(addList); + this.Context.MappingTables.Add(EntityInfo.EntityName, EntityInfo.DbTableName); + } + return result; + } + public async Task BulkUpdateAsync(List datas) + { + List groupModels; + int result; + GroupDataList(datas, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + CreateTable(item.Key); + var addList = item.Select(it => it.Item).ToList(); + result += await FastestProvider.AS(item.Key).BulkUpdateAsync(addList).ConfigureAwait(false); + this.Context.MappingTables.Add(EntityInfo.EntityName, EntityInfo.DbTableName); + } + return result; + } + + + public int BulkUpdate(List datas, string[] wherColumns, string[] updateColumns) + { + List groupModels; + int result; + GroupDataList(datas, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + result += FastestProvider.AS(item.Key).BulkUpdate(addList, wherColumns, updateColumns); ; + } + return result; + } + public async Task BulkUpdateAsync(List datas, string[] wherColumns, string[] updateColumns) + { + List groupModels; + int result; + GroupDataList(datas, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + result += await FastestProvider.AS(item.Key).BulkUpdateAsync(addList, wherColumns, updateColumns).ConfigureAwait(false); ; + } + return result; + } + private void CreateTable(string tableName) + { + var isLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + if (!this.Context.DbMaintenance.IsAnyTable(tableName, false)) + { + this.Context.MappingTables.Add(EntityInfo.EntityName, tableName); + this.Context.CodeFirst.InitTables(); + } + this.Context.Ado.IsEnableLogEvent = isLog; + } + + private void GroupDataList(List datas, out List groupModels, out int result) + { + var attribute = typeof(T).GetCustomAttribute() as SplitTableAttribute; + Check.Exception(attribute == null, $"{typeof(T).Name} need SplitTableAttribute"); + groupModels = new List(); + var db = FastestProvider.context; + var hasSplitField = typeof(T).GetProperties().Any(it => it.GetCustomAttribute() != null); + foreach (var item in datas) + { + if (groupModels.Count > 0 && !hasSplitField) + groupModels.Add(new GroupModel() { GroupName = groupModels[0].GroupName, Item = item }); + else + { + var value = db.SplitHelper().GetValue(attribute.SplitType, item); + var tableName = db.SplitHelper().GetTableName(attribute.SplitType, value); + groupModels.Add(new GroupModel() { GroupName = tableName, Item = item }); + } + } + result = 0; + } + internal class GroupModel + { + public string GroupName { get; set; } + public T Item { get; set; } + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FilterProvider/FilterProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FilterProvider/FilterProvider.cs new file mode 100644 index 000000000..48dd89c70 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/FilterProvider/FilterProvider.cs @@ -0,0 +1,146 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class QueryFilterProvider : IFilter + { + internal SqlSugarProvider Context { get; set; } + private List _Filters { get; set; } + private List _BackUpFilters { get; set; } + public bool Any() + { + return _Filters != null && _Filters.Count != 0; + } + public IFilter Add(SqlFilterItem filter) + { + if (_Filters == null) + _Filters = new List(); + //if (this.Context.CurrentConnectionConfig.IsShardSameThread) + //{ + // if (!_Filters.Select(it => it.FilterValue(this.Context).Sql).Contains(filter.FilterValue(this.Context).Sql)) + // _Filters.Add(filter); + //} + //else + //{ + _Filters.Add(filter); + //} + return this; + } + + public void Remove(string filterName) + { + if (_Filters == null) + _Filters = new List(); + _Filters.RemoveAll(it => it.FilterName == filterName); + } + + public List GetFilterList + { + get + { + if (_Filters == null) + _Filters = new List(); + return _Filters; + } + } + public void Clear() + { + _Filters = new List(); + } + public void Clear() + { + _Filters = _Filters.Where(it => !(it is TableFilterItem)).ToList(); + } + public void Clear(params Type[] types) + { + _Filters = _Filters.Where(it => !types.Contains(it.type)).ToList(); + } + public void Clear() + { + _Filters = _Filters.Where(it => !(it is TableFilterItem) && !(it is TableFilterItem)).ToList(); + } + public void Clear() + { + _Filters = _Filters.Where(it => !(it is TableFilterItem) && !(it is TableFilterItem) && !(it is TableFilterItem)).ToList(); + } + public void ClearAndBackup() + { + _BackUpFilters = _Filters; + _Filters = new List(); + } + + public void ClearAndBackup() + { + _BackUpFilters = _Filters; + _Filters = _BackUpFilters.Where(it => !(it is TableFilterItem)).ToList(); + } + + public void ClearAndBackup() + { + _BackUpFilters = _Filters; + _Filters = _BackUpFilters.Where(it => !(it is TableFilterItem) && !(it is TableFilterItem)).ToList(); + } + + public void ClearAndBackup() + { + _BackUpFilters = _Filters; + _Filters = _BackUpFilters.Where(it => !(it is TableFilterItem) && !(it is TableFilterItem) && !(it is TableFilterItem)).ToList(); + } + + public void ClearAndBackup(params Type[] types) + { + _BackUpFilters = _Filters; + _Filters = _BackUpFilters.Where(it => !types.Contains(it.type)).ToList(); + } + + public void Restore() + { + _Filters = _BackUpFilters; + if (_Filters == null) + { + _Filters = new List(); + } + } + + public QueryFilterProvider AddTableFilter(Expression> expression, FilterJoinPosition filterJoinType = FilterJoinPosition.On) + { + var isOn = filterJoinType == FilterJoinPosition.On; + var tableFilter = new TableFilterItem(expression, isOn); + this.Add(tableFilter); + return this; + } + public QueryFilterProvider AddTableFilterIF(bool isAppendFilter, Expression> expression, FilterJoinPosition filterJoinType = FilterJoinPosition.On) + { + if (isAppendFilter) + { + AddTableFilter(expression, filterJoinType); + } + return this; + } + public QueryFilterProvider AddTableFilter(Type type, string shortName, FormattableString expString, FilterJoinPosition filterJoinType = FilterJoinPosition.On) + { + var exp = DynamicCoreHelper.GetWhere(type, shortName, expString); + return AddTableFilter(type, exp, filterJoinType); + } + public QueryFilterProvider AddTableFilter(Type type, Expression expression, FilterJoinPosition filterJoinType = FilterJoinPosition.On) + { + var isOn = filterJoinType == FilterJoinPosition.On; + this.Add(new TableFilterItem(type, expression, isOn)); + return this; + } + + public QueryFilterProvider AddTableFilterIF(bool isAppendFilter, Type type, Expression expression, FilterJoinPosition posType = FilterJoinPosition.On) + { + if (isAppendFilter) + { + AddTableFilter(type, expression, posType); + } + return this; + } + public enum FilterJoinPosition + { + On = 0, + Where = 1 + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/GridSave/GridSaveProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/GridSave/GridSaveProvider.cs new file mode 100644 index 000000000..a314f5973 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/GridSave/GridSaveProvider.cs @@ -0,0 +1,90 @@ +namespace SqlSugar +{ + public class GridSaveProvider where T : class, new() + { + internal SqlSugarProvider Context { get; set; } + internal List OldList { get; set; } + internal List SaveList { get; set; } + internal bool IsIncluesFirstAll { get; set; } + internal string[] IgnoreColumnsSaveInclues { get; set; } + public bool ExecuteCommand() + { + var deleteList = GetDeleteList(); + this.Context.Deleteable(deleteList).PageSize(1000).ExecuteCommand(); + if (IsIncludesSave()) + { + this.Context.Utilities.PageEach(SaveList, 1000, pageList => + { + var options = new UpdateNavRootOptions() { IsInsertRoot = true }; + this.Context.UpdateNav(pageList, options) + .IncludesAllFirstLayer(IgnoreColumnsSaveInclues).ExecuteCommand(); + }); + } + else + { + this.Context.Storageable(SaveList).PageSize(1000).ExecuteCommand(); + } + return true; + } + + public async Task ExecuteCommandAsync() + { + var deleteList = GetDeleteList(); + await Context.Deleteable(deleteList).PageSize(1000).ExecuteCommandAsync().ConfigureAwait(false); + if (IsIncludesSave()) + { + await Context.Utilities.PageEachAsync(SaveList, 1000, async pageList => + { + var options = new UpdateNavRootOptions() { IsInsertRoot = true }; + await Context.UpdateNav(pageList, options) + .IncludesAllFirstLayer(IgnoreColumnsSaveInclues).ExecuteCommandAsync().ConfigureAwait(false); + }).ConfigureAwait(false); + } + else + { + await Context.Storageable(SaveList).PageSize(1000).ExecuteCommandAsync().ConfigureAwait(false); + } + return true; + } + + public List GetDeleteList() + { + //下面代码ToDictionary会有重复错请修改 + string[] primaryKeys = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey).Select(it => it.PropertyName).ToArray(); + var saveListDictionary = this.SaveList.Select(item => + new { Key = CreateCompositeKey(primaryKeys, item), Value = item }); + var deleteList = this.OldList.Where(oldItem => + { + var compositeKey = CreateCompositeKey(primaryKeys, oldItem); + return !saveListDictionary.Any(it => it.Key == compositeKey); + }).ToList(); + return deleteList; + } + + public GridSaveProvider IncludesAllFirstLayer(params string[] ignoreColumns) + { + this.IsIncluesFirstAll = true; + IgnoreColumnsSaveInclues = ignoreColumns; + return this; + } + + + private bool IsIncludesSave() + { + return IsIncluesFirstAll && this.Context.EntityMaintenance.GetEntityInfo().Columns.Any(it => it.Navigat != null); + } + + + private string CreateCompositeKey(string[] propertyNames, object obj) + { + var keyValues = propertyNames.Select(propertyName => GetPropertyValue(obj, propertyName)?.ToString() ?? ""); + return string.Join("|", keyValues); + } + + private object GetPropertyValue(object obj, string propertyName) + { + var property = obj.GetType().GetProperty(propertyName); + return property != null ? property.GetValue(obj) : null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertMethodInfo.cs new file mode 100644 index 000000000..ee5dbcc69 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertMethodInfo.cs @@ -0,0 +1,125 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class InsertMethodInfo + { + internal SqlSugarProvider Context { get; set; } + internal MethodInfo MethodInfo { get; set; } + internal object objectValue { get; set; } + internal int pageSize { get; set; } + public int ExecuteCommand() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + inertable = GetPageInsertable(inertable); + var result = inertable.GetType().GetMethod("ExecuteCommand").Invoke(inertable, Array.Empty()); + return (int)result; + } + + public InsertMethodInfo PageSize(int pageSize) + { + this.pageSize = pageSize; + return this; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + inertable = GetPageInsertable(inertable); + var result = inertable.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(inertable, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public int ExecuteReturnIdentity() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMethod("ExecuteReturnIdentity").Invoke(inertable, Array.Empty()); + return (int)result; + } + public async Task ExecuteReturnIdentityAsync() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMyMethod("ExecuteReturnIdentityAsync", 0).Invoke(inertable, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + + public CommonMethodInfo AS(string tableName) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("AS", 1, typeof(string)); + var result = newMethod.Invoke(inertable, new object[] { tableName }); + return new CommonMethodInfo() + { + Context = result + }; + } + public CommonMethodInfo EnableDiffLogEvent(object businessData = null) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("EnableDiffLogEvent", 1, typeof(object)); + var result = newMethod.Invoke(inertable, new object[] { businessData }); + return new CommonMethodInfo() + { + Context = result + }; + } + public CommonMethodInfo IgnoreColumns(params string[] ignoreColumns) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("IgnoreColumns", 1, typeof(string[])); + var result = newMethod.Invoke(inertable, new object[] { ignoreColumns }); + return new CommonMethodInfo() + { + Context = result + }; + } + public CommonMethodInfo IgnoreColumns(bool ignoreNullColumn) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("IgnoreColumns", 2, typeof(bool), typeof(bool)); + var result = newMethod.Invoke(inertable, new object[] { ignoreNullColumn, true }); + return new CommonMethodInfo() + { + Context = result + }; + } + + public SplitMethodInfo SplitTable() + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("SplitTable", 0); + var result = newMethod.Invoke(inertable, Array.Empty()); + return new SplitMethodInfo() + { + Context = result + }; + } + + public long ExecuteReturnSnowflakeId() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMethod("ExecuteReturnSnowflakeId").Invoke(inertable, Array.Empty()); + return (long)result; + } + public async Task ExecuteReturnSnowflakeIdAsync() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMyMethod("ExecuteReturnSnowflakeIdAsync", 0).Invoke(inertable, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + + private object GetPageInsertable(object inertable) + { + if (pageSize > 0) + { + inertable = inertable.GetType().GetMethod("PageSize").Invoke(inertable, new object[] { pageSize }); + } + return inertable; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertNavMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertNavMethodInfo.cs new file mode 100644 index 000000000..ba45351d8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertNavMethodInfo.cs @@ -0,0 +1,49 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class InsertNavMethodInfo + { + internal object MethodInfos { get; set; } + internal SqlSugarProvider Context { get; set; } + + public InsertNavMethodInfo IncludeByNameString(string navMemberName, InsertNavOptions insertNavOptions = null) + { + var type = MethodInfos.GetType().GetGenericArguments()[0]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.MethodInfos.GetType().GetMyMethod("Include", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this.MethodInfos, new object[] { exp, insertNavOptions }); + this.MethodInfos = obj; + return this; + } + public InsertNavMethodInfo ThenIncludeByNameString(string navMemberName, InsertNavOptions insertNavOptions = null) + { + var type = MethodInfos.GetType().GetGenericArguments()[1]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.MethodInfos.GetType().GetMyMethod("ThenInclude", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this.MethodInfos, new object[] { exp, insertNavOptions }); + this.MethodInfos = obj; + return this; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return false; + var result = MethodInfos.GetType().GetMethod("ExecuteCommandAsync").Invoke(MethodInfos, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public bool ExecuteCommand() + { + if (Context == null) return false; + var result = MethodInfos.GetType().GetMethod("ExecuteCommand").Invoke(MethodInfos, Array.Empty()); + return (bool)result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertableHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertableHelper.cs new file mode 100644 index 000000000..a2b3a237f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertableHelper.cs @@ -0,0 +1,744 @@ +using System.Data; +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class InsertableProvider : IInsertable where T : class, new() + { + #region Protected Methods + private string _ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + Before(sql); + return sql; + } + private string _ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + Before(sql); + return sql; + } + + private string _ExecuteCommand() + { + if (InsertBuilder.DbColumnInfoList.HasValue()) + { + var pks = GetPrimaryKeys(); + foreach (var item in InsertBuilder.DbColumnInfoList) + { + var isPk = pks.Any(y => y.Equals(item.DbColumnName, StringComparison.CurrentCultureIgnoreCase)) || item.IsPrimarykey; + if (isPk && item.PropertyType == UtilConstants.GuidType && item.Value is Guid guid && guid == Guid.Empty) + { + if (StaticConfig.CustomGuidFunc != null) + { + item.Value = StaticConfig.CustomGuidFunc(); + } + else if (StaticConfig.CustomGuidByValueFunc != null && item.Value is Guid guidValue) + { + item.Value = StaticConfig.CustomGuidByValueFunc(guidValue); + } + else + { + item.Value = Guid.NewGuid(); + } + if (InsertObjs.First().GetType().GetProperties().Any(it => it.Name == item.PropertyName)) + InsertObjs.First().GetType().GetProperties().First(it => it.Name == item.PropertyName).SetValue(InsertObjs.First(), item.Value, null); + } + } + } + InsertBuilder.IsReturnIdentity = false; + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + Before(sql); + return sql; + } + protected void AutoRemoveDataCache() + { + var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (moreSetts?.IsAutoRemoveDataCache == true && extService?.DataInfoCacheService != null) + { + this.RemoveDataCache(); + } + } + protected virtual void PreToSql() + { + #region Identities + if (!IsOffIdentity) + { + List identities = GetIdentityKeys(); + if (identities != null && identities.Count != 0) + { + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => + { + return !identities.Any(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + }).ToList(); + } + } + #endregion + + #region IgnoreColumns + if (this.Context.IgnoreColumns?.Any() == true) + { + var currentIgnoreColumns = this.Context.IgnoreColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => + { + return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); + }).ToList(); + } + + if (this.Context.IgnoreInsertColumns?.Any() == true) + { + var currentIgnoreColumns = this.Context.IgnoreInsertColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => + { + return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); + }).ToList(); + } + #endregion + if (this.IsSingle) + { + var isDic = this.EntityInfo.DbTableName.StartsWith("Dictionary`"); + foreach (var item in this.InsertBuilder.DbColumnInfoList) + { + if (this.InsertBuilder.Parameters == null) this.InsertBuilder.Parameters = new List(); + var paramters = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, item.PropertyType); + if (InsertBuilder.IsNoInsertNull && paramters.Value == null) + { + continue; + } + if (item.SqlParameterDbType is Type) + { + continue; + } + if (item.IsJson) + { + paramters.IsJson = true; + SqlBuilder.ChangeJsonType(paramters); + } + if (item.IsArray) + { + paramters.IsArray = true; + if (item.Value == null || item.Value == DBNull.Value) + { + ArrayNull(item, paramters); + } + + } + if (item.Value == null && isDic) + { + var type = this.SqlBuilder.GetNullType(this.InsertBuilder.GetTableNameString, item.DbColumnName); + if (type != null) + { + paramters = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, type); + + } + } + this.InsertBuilder.Parameters.Add(paramters); + } + } + } + + private static void ArrayNull(DbColumnInfo item, SugarParameter parameter) + { + if (item.PropertyType.IsIn(typeof(Guid[]), typeof(Guid?[]))) + { + parameter.DbType = System.Data.DbType.Guid; + } + else if (item.PropertyType.IsIn(typeof(int[]), typeof(int?[]))) + { + parameter.DbType = System.Data.DbType.Int32; + } + else if (item.PropertyType.IsIn(typeof(long[]), typeof(long?[]))) + { + parameter.DbType = System.Data.DbType.Int64; + } + else if (item.PropertyType.IsIn(typeof(short[]), typeof(short?[]))) + { + parameter.DbType = System.Data.DbType.Int16; + } + } + internal void Init() + { + InsertBuilder.EntityInfo = this.EntityInfo; + Check.Exception(InsertObjs == null || InsertObjs.Length == 0, "InsertObjs is null"); + int i = 0; + foreach (var item in InsertObjs) + { + List insertItem = new List(); + if (item is Dictionary) + { + Check.ExceptionEasy("To use Insertable dictionary, use string or object", "Insertable字典请使用string,object类型"); + } + if (item is Dictionary) + { + SetInsertItemByDic(i, item, insertItem); + } + else + { + DataAop(item); + SetInsertItemByEntity(i, item, insertItem); + } + this.InsertBuilder.DbColumnInfoList.AddRange(insertItem); + ++i; + } + } + + private void DataAop(T item) + { + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (dataEvent != null && item != null) + { + foreach (var columnInfo in this.EntityInfo.Columns) + { + if (columnInfo.ForOwnsOnePropertyInfo != null) + { + var data = columnInfo.ForOwnsOnePropertyInfo.GetValue(item, null); + if (data != null) + { + dataEvent(columnInfo.PropertyInfo.GetValue(data, null), new DataFilterModel() { OperationType = DataFilterType.InsertByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + else if (columnInfo.PropertyInfo.Name == "Item" && columnInfo.IsIgnore) + { + //class index + } + else + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.InsertByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + } + + private void DataChangeAop(T[] items) + { + + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataChangesExecuted; + if (dataEvent != null) + { + foreach (var item in items) + { + if (item != null && !(item is Dictionary)) + { + foreach (var columnInfo in this.EntityInfo.Columns) + { + if (columnInfo.ForOwnsOnePropertyInfo != null) + { + var data = columnInfo.ForOwnsOnePropertyInfo.GetValue(item, null); + if (data != null) + { + dataEvent(columnInfo.PropertyInfo.GetValue(data, null), new DataFilterModel() { OperationType = DataFilterType.InsertByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + else if (columnInfo.PropertyInfo.Name == "Item" && columnInfo.IsIgnore) + { + //class index + } + else + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.InsertByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + } + } + } + + private void SetInsertItemByDic(int i, T item, List insertItem) + { + foreach (var column in (item as Dictionary).OrderBy(it => it.Key)) + { + var columnInfo = new DbColumnInfo() + { + Value = column.Value, + DbColumnName = column.Key, + PropertyName = column.Key, + PropertyType = column.Value == null ? DBNull.Value.GetType() : UtilMethods.GetUnderType(column.Value.GetType()), + TableId = i + }; + if (columnInfo.PropertyType?.FullName == "System.Text.Json.JsonElement") + { + columnInfo.Value = column.Value.ObjToString(); + } + if (columnInfo.PropertyType.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.Value = columnInfo.Value.ToString(); + columnInfo.PropertyType = UtilConstants.StringType; + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + insertItem.Add(columnInfo); + } + } + private void SetInsertItemByEntity(int i, T item, List insertItem) + { + if (item == null) + { + return; + } + foreach (var column in EntityInfo.Columns) + { + if (column.IsIgnore || column.IsOnlyIgnoreInsert) continue; + var isMapping = IsMappingColumns; + var columnInfo = new DbColumnInfo() + { + Value = GetValue(item, column), + DbColumnName = column.DbColumnName, + PropertyName = column.PropertyName, + PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), + TableId = i, + InsertSql = column.InsertSql, + InsertServerTime = column.InsertServerTime, + DataType = column.DataType, + SqlParameterDbType = column.SqlParameterDbType, + IsIdentity = column.IsIdentity + + }; + if (column.DbColumnName == null) + { + column.DbColumnName = column.PropertyName; + } + if (isMapping && column.ForOwnsOnePropertyInfo == null) + { + columnInfo.DbColumnName = GetDbColumnName(column.PropertyName); + } + if (column.IsJson) + { + columnInfo.IsJson = true; + } + if (column.IsArray) + { + columnInfo.IsArray = true; + } + if (columnInfo.PropertyType.IsEnum() && columnInfo.Value != null) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.Value = columnInfo.Value.ToString(); + columnInfo.PropertyType = UtilConstants.StringType; + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + if (column.IsJson && columnInfo.Value != null) + { + if (columnInfo.Value != null) + columnInfo.Value = this.Context.Utilities.SerializeObject(columnInfo.Value); + } + //var tranColumn=EntityInfo.Columns.FirstOrDefault(it => it.IsTranscoding && it.DbColumnName.Equals(column.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (column.IsTranscoding && columnInfo.Value.HasValue()) + { + columnInfo.Value = UtilMethods.EncodeBase64(columnInfo.Value.ToString()); + } + insertItem.Add(columnInfo); + } + if (EntityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(EntityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = EntityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + insertItem.Add(new DbColumnInfo() { DbColumnName = name, PropertyName = name, PropertyType = typeof(string), Value = value }); + } + } + } + private static object GetValue(T item, EntityColumnInfo column) + { + if (column.ForOwnsOnePropertyInfo != null) + { + var owsPropertyValue = column.ForOwnsOnePropertyInfo.GetValue(item, null); + return column.PropertyInfo.GetValue(owsPropertyValue, null); + } + if (StaticConfig.EnableAot) + { + return column.PropertyInfo.GetValue(item, null); + } + else + { + return PropertyCallAdapterProvider.GetInstance(column.PropertyName).InvokeGet(item); + } + } + + private string GetDbColumnName(string propertyName) + { + if (!IsMappingColumns) + { + return propertyName; + } + if (this.Context.MappingColumns.Any(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase))) + { + this.MappingColumnList = this.Context.MappingColumns.Where(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + } + if (MappingColumnList == null || MappingColumnList.Count == 0) + { + return propertyName; + } + else + { + var mappInfo = this.MappingColumnList.FirstOrDefault(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return mappInfo == null ? propertyName : mappInfo.DbColumnName; + } + } + + protected virtual List GetPrimaryKeys() + { + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + protected virtual List GetIdentityKeys() + { + return this.EntityInfo.Columns.Where(it => + { + + if (StaticConfig.Check_StringIdentity) + { + Check.ExceptionEasy(it.IsIdentity && it.UnderType == typeof(string), "Auto-incremented is not a string, how can I use a executable startup configuration: StaticConfig.Check_StringIdentity=false ", "自增不是能string,如何非要用可以程序启动配置:StaticConfig.Check_StringIdentity=false"); + } + return it.IsIdentity; + + }).Select(it => it.DbColumnName).ToList(); + } + //private void TaskStart(Task result) + //{ + // if (this.Context.CurrentConnectionConfig.IsShardSameThread) + // { + // Check.Exception(true, "IsShardSameThread=true can't be used async method"); + // } + // result.Start(); + //} + protected void RestoreMapping() + { + if (IsAs) + { + this.Context.MappingTables = OldMappingTableList; + } + } + //protected IInsertable CopyInsertable() + //{ + // var asyncContext = this.Context.Utilities.CopyContext(true); + // asyncContext.CurrentConnectionConfig.IsAutoCloseConnection = true; + // asyncContext.IsAsyncMethod = true; + // var asyncInsertable = asyncContext.Insertable(this.InsertObjs); + // var asyncInsertableBuilder = asyncInsertable.InsertBuilder; + // asyncInsertableBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList; + // asyncInsertableBuilder.EntityInfo = this.InsertBuilder.EntityInfo; + // asyncInsertableBuilder.Parameters = this.InsertBuilder.Parameters; + // asyncInsertableBuilder.sql = this.InsertBuilder.sql; + // asyncInsertableBuilder.IsNoInsertNull = this.InsertBuilder.IsNoInsertNull; + // asyncInsertableBuilder.IsReturnIdentity = this.InsertBuilder.IsReturnIdentity; + // asyncInsertableBuilder.EntityInfo = this.InsertBuilder.EntityInfo; + // asyncInsertableBuilder.TableWithString = this.InsertBuilder.TableWithString; + // if (this.RemoveCacheFunc != null) + // { + // asyncInsertable.RemoveDataCache(); + // } + // return asyncInsertable; + //} + + protected void After(string sql, long? result) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = InsertBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.AfterData = GetDiffTable(sql, result); + diffModel.Time = this.Context.Ado.SqlExecutionTime; + if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) + this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + if (this.RemoveCacheFunc != null) + { + this.RemoveCacheFunc(); + } + DataChangeAop(this.InsertObjs); + } + protected void Before(string sql) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = InsertBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.BeforeData = null; + diffModel.Sql = sql; + diffModel.Parameters = parameters.ToArray(); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + } + private List GetDiffTable(string sql, long? identity) + { + + if (GetIdentityKeys().HasValue() && this.InsertObjs.Length > 1) + { + return GetDiffTableByEntity(); + } + else if (GetIdentityKeys().IsNullOrEmpty()) + { + return GetDiffTableByEntity(); + } + else + { + return GetDiffTableBySql(identity); + } + + } + + private List GetDiffTableByEntity() + { + List parameters = new List(); + List result = new List(); + var dt2 = this.Context.Utilities.ListToDataTable(this.InsertObjs.ToList()); + foreach (DataRow row in dt2.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt2.Columns) + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).FirstOrDefault(it => + it.PropertyName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = sugarColumn?.DbColumnName ?? col.ColumnName; + addItem.IsPrimaryKey = sugarColumn?.IsPrimarykey ?? false; + addItem.ColumnDescription = sugarColumn?.ColumnDescription; + item.Columns.Add(addItem); + } + result.Add(item); + } + return result; + } + + private List GetDiffTableBySql(long? identity) + { + List parameters = new List(); + List result = new List(); + var whereSql = string.Empty; + List cons = new List(); + if (identity != null && identity > 0 && GetIdentityKeys().HasValue()) + { + var fieldName = GetIdentityKeys().Last(); + + if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + var fieldObjectType = this.EntityInfo.Columns.FirstOrDefault(x => x.DbColumnName == fieldName) + .PropertyInfo.PropertyType; + cons.Add(new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + FieldName = fieldName, + FieldValue = identity.ToString(), + FieldValueConvertFunc = it => UtilMethods.ChangeType2(it, fieldObjectType) + }); + } + else + cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fieldName, FieldValue = identity.ToString() }); + } + else + { + foreach (var item in this.EntityInfo.Columns.Where(it => it.IsIgnore == false && GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase)))) + { + var fielddName = item.DbColumnName; + var filedObject = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.PropertyName).PropertyInfo.GetValue(this.InsertObjs.Last(), null); + var fieldValue = filedObject.ObjToString(); + if (filedObject != null && filedObject.GetType() != typeof(string) && this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fielddName, FieldValue = fieldValue, FieldValueConvertFunc = it => UtilMethods.ChangeType2(it, filedObject.GetType()) }); + } + else + { + cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fielddName, FieldValue = fieldValue }); + } + } + } + Check.Exception(cons.IsNullOrEmpty(), "Insertable.EnableDiffLogEvent need primary key"); + var sqlable = this.SqlBuilder.ConditionalModelToSql(cons); + whereSql = sqlable.Key; + parameters.AddRange(sqlable.Value); + var dt = this.Context.Queryable().Where(whereSql).AddParameters(parameters).ToDataTable(); + if (dt.Rows?.Count > 0) + { + foreach (DataRow row in dt.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt.Columns) + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; + addItem.ColumnDescription = sugarColumn.ColumnDescription; + item.Columns.Add(addItem); + } + result.Add(item); + } + return result; + } + else + { + DiffLogTableInfo diffTable = new DiffLogTableInfo(); + diffTable.TableName = this.EntityInfo.DbTableName; + diffTable.TableDescription = this.EntityInfo.TableDescription; + diffTable.Columns = this.EntityInfo.Columns.Where(it => it.IsIgnore == false).Select(it => new DiffLogColumnInfo() + { + ColumnDescription = it.ColumnDescription, + ColumnName = it.DbColumnName, + Value = it.PropertyInfo.GetValue(this.InsertObjs.Last(), null), + IsPrimaryKey = it.IsPrimarykey + }).ToList(); + return new List() { diffTable }; + } + } + + public IInsertable CallEntityMethod(Expression> method) + { + if (this.InsertObjs.HasValue()) + { + var oldColumns = this.InsertBuilder.DbColumnInfoList.Select(it => it.PropertyName).ToHashSet(); + var expression = (LambdaExpression.Lambda(method).Body as LambdaExpression).Body; + Check.Exception(!(expression is MethodCallExpression), method.ToString() + " is not method"); + var callExpresion = expression as MethodCallExpression; + UtilMethods.DataInoveByExpresson(this.InsertObjs, callExpresion); + this.InsertBuilder.DbColumnInfoList = new List(); + Init(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => oldColumns.Contains(it.PropertyName)).ToList(); + } + return this; + } + + #endregion + + #region Insert PkList + + private List InsertPkListWithFunc(EntityColumnInfo pkInfo) + { + InsertBuilder.IsReturnPkList = true; + InsertBuilder.IsNoPage = true; + string sql = _ExecuteCommand(); + sql = this.InsertBuilder.ConvertInsertReturnIdFunc(SqlBuilder.GetTranslationColumnName(pkInfo.DbColumnName), sql); + var result = Ado.SqlQuery(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + After(sql, null); + return result; + } + + private List InsertPkListNoFunc(EntityColumnInfo pkInfo) + { + if (this.Ado.Transaction != null) + { + return ReturnDefaultIdentity(pkInfo); + } + else + { + try + { + this.Context.Ado.BeginTran(); + var result = ReturnDefaultIdentity(pkInfo); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + } + + private List InsertPkListIdentityCount1(EntityColumnInfo pkInfo) + { + if (pkInfo.UnderType == UtilConstants.IntType) + { + return new List { (Type)(object)this.ExecuteReturnIdentity() }; + } + else + { + return new List { (Type)(object)this.ExecuteReturnBigIdentity() }; + } + } + + private List InsertPkListLong() + { + var list = this.ExecuteReturnSnowflakeIdList(); + try + { + return list.Cast().ToList(); + } + catch + { + Check.ExceptionEasy($"long to ExecuteReturnPkList<{typeof(Type).Name}> error ", $" long 转换成ExecuteReturnPkList<{typeof(Type).Name}>失败"); + return null; + } + } + + private List InsertPkListGuid(EntityColumnInfo pkInfo) + { + Check.ExceptionEasy(pkInfo.UnderType.Name != typeof(Type).Name, $"{pkInfo.UnderType.Name} to ExecuteReturnPkList<{typeof(Type).Name}> error ", $" {pkInfo.UnderType.Name} 转换成ExecuteReturnPkList<{typeof(Type).Name}>失败"); + this.ExecuteCommand(); + List result = new List(); + if (InsertBuilder.DbColumnInfoList.HasValue()) + { + foreach (var item in InsertBuilder.DbColumnInfoList) + { + var isPk = item.DbColumnName.EqualCase(pkInfo.DbColumnName); + if (isPk) + { + result.Add((Type)item.Value); + } + } + } + return result; + } + private List ReturnDefaultIdentity(EntityColumnInfo pkInfo) + { + List result = new List(); + foreach (var item in this.InsertObjs) + { + var insertable = this.Context.Insertable(item) + .AS(this.InsertBuilder.AsName) + .InsertColumns(this.InsertBuilder.DbColumnInfoList.Select(it => it.DbColumnName).Distinct().ToArray()); + if (pkInfo.UnderType == UtilConstants.IntType) + { + result.Add((Type)(object)insertable.ExecuteReturnIdentity()); + } + else + { + result.Add((Type)(object)insertable.ExecuteReturnBigIdentity()); + } + } + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertablePage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertablePage.cs new file mode 100644 index 000000000..238d6f96a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertablePage.cs @@ -0,0 +1,160 @@ +namespace SqlSugar +{ + public class InsertablePage where T : class, new() + { + public int PageSize { get; set; } + public SqlSugarProvider Context { get; set; } + public T[] DataList { get; set; } + public string TableName { get; internal set; } + public List InsertColumns { get; internal set; } + public bool IsEnableDiffLogEvent { get; internal set; } + public DiffLogModel DiffModel { get; internal set; } + public bool IsOffIdentity { get; internal set; } + public bool IsInsertColumnsNull { get; internal set; } + public bool IsMySqlIgnore { get; internal set; } + public int ExecuteCommand() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + this.Context.Utilities.PageEach(DataList, PageSize, pageItem => + { + result += this.Context.Insertable(pageItem).AS(TableName).MySqlIgnore(IsMySqlIgnore).IgnoreColumnsNull(this.IsInsertColumnsNull).OffIdentity(IsOffIdentity).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).InsertColumns(InsertColumns.ToArray()).ExecuteCommand(); + }); + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return result; + } + public async Task ExecuteCommandAsync() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + await Context.Utilities.PageEachAsync(DataList, PageSize, async pageItem => + { + result += await Context.Insertable(pageItem).AS(TableName).IgnoreColumnsNull(IsInsertColumnsNull).OffIdentity(IsOffIdentity).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).InsertColumns(InsertColumns.ToArray()).ExecuteCommandAsync().ConfigureAwait(false); + }).ConfigureAwait(false); + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return result; + } + + public List ExecuteReturnSnowflakeIdList() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return new List(); + } + if (PageSize == 0) { PageSize = 1000; } + var result = new List(); + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + this.Context.Utilities.PageEach(DataList, PageSize, pageItem => + { + result.AddRange(this.Context.Insertable(pageItem).AS(TableName).OffIdentity(IsOffIdentity).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).InsertColumns(InsertColumns.ToArray()).ExecuteReturnSnowflakeIdList()); + }); + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return result; + } + public async Task> ExecuteReturnSnowflakeIdListAsync() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return new List(); + } + if (PageSize == 0) { PageSize = 1000; } + var result = new List(); + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + await Context.Utilities.PageEachAsync(DataList, PageSize, async pageItem => + { + result.AddRange(await Context.Insertable(pageItem).AS(TableName).OffIdentity(IsOffIdentity).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).InsertColumns(InsertColumns.ToArray()).ExecuteReturnSnowflakeIdListAsync().ConfigureAwait(false)); + }).ConfigureAwait(false); + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return result; + } + + public InsertablePage IgnoreColumnsNull(bool isIgnoreNull = true) + { + this.PageSize = 1; + this.IsInsertColumnsNull = isIgnoreNull; + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertableProvider.cs new file mode 100644 index 000000000..a36e5e91b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/InsertableProvider.cs @@ -0,0 +1,793 @@ +using System.Data; +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public partial class InsertableProvider : IInsertable where T : class, new() + { + public SqlSugarProvider Context { get; set; } + public IAdo Ado { get { return Context.Ado; } } + public ISqlBuilder SqlBuilder { get; set; } + public InsertBuilder InsertBuilder { get; set; } + + public bool IsMappingTable { get { return this.Context.MappingTables?.Any() == true; } } + public bool IsMappingColumns { get { return this.Context.MappingColumns?.Any() == true; } } + public bool IsSingle { get { return this.InsertObjs.Length == 1; } } + + public EntityInfo EntityInfo { get; set; } + public List MappingColumnList { get; set; } + private List IgnoreColumnNameList { get; set; } + internal bool IsOffIdentity { get; set; } + public T[] InsertObjs { get; set; } + + public MappingTableList OldMappingTableList { get; set; } + public bool IsAs { get; set; } + public bool IsEnableDiffLogEvent { get; set; } + public DiffLogModel diffModel { get; set; } + internal Action RemoveCacheFunc { get; set; } + + + #region Core + public void AddQueue() + { + if (this.InsertObjs?.Length > 0 && this.InsertObjs[0] != null) + { + var sqlObj = this.ToSql(); + this.Context.Queues.Add(sqlObj.Key, sqlObj.Value); + } + } + public virtual int ExecuteCommand() + { + if (this.InsertObjs.Length == 1 && this.InsertObjs.First() == null) + { + return 0; + } + string sql = _ExecuteCommand(); + var result = Ado.ExecuteCommand(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + After(sql, null); + if (result == -1) return this.InsertObjs.Length; + return result; + } + public virtual string ToSqlString() + { + var sqlObj = this.ToSql(); + var result = sqlObj.Key; + if (result == null) return null; + result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig, sqlObj); + return result; + } + public virtual KeyValuePair> ToSql() + { + InsertBuilder.IsReturnIdentity = true; + if (this.SqlBuilder.SqlParameterKeyWord == ":" && !this.EntityInfo.Columns.Any(it => it.IsIdentity)) + { + InsertBuilder.IsReturnIdentity = false; + } + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + return new KeyValuePair>(sql, InsertBuilder.Parameters); + } + public async Task> ExecuteReturnPkListAsync() + { + return await Task.Run(() => ExecuteReturnPkList()).ConfigureAwait(false); + } + public virtual List ExecuteReturnPkList() + { + var pkInfo = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + Check.ExceptionEasy(pkInfo == null, "ExecuteReturnPkList need primary key", "ExecuteReturnPkList需要主键"); + Check.ExceptionEasy(this.EntityInfo.Columns.Count(it => it.IsPrimarykey == true) > 1, "ExecuteReturnPkList ,Only support technology single primary key", "ExecuteReturnPkList只支技单主键"); + var isIdEntity = pkInfo.IsIdentity || (pkInfo.OracleSequenceName.HasValue() && this.Context.CurrentConnectionConfig.DbType == DbType.Oracle); + if (isIdEntity && this.InsertObjs.Length == 1) + { + return InsertPkListIdentityCount1(pkInfo); + } + else if (isIdEntity && this.InsertBuilder.ConvertInsertReturnIdFunc == null) + { + return InsertPkListNoFunc(pkInfo); + } + else if (isIdEntity && this.InsertBuilder.ConvertInsertReturnIdFunc != null) + { + return InsertPkListWithFunc(pkInfo); + } + else if (pkInfo.UnderType == UtilConstants.LongType) + { + return InsertPkListLong(); + } + else + { + return InsertPkListGuid(pkInfo); + } + } + + public virtual int ExecuteReturnIdentity() + { + if (this.InsertObjs.Length == 1 && this.InsertObjs.First() == null) + { + return 0; + } + string sql = _ExecuteReturnIdentity(); + var result = 0; + if (InsertBuilder.IsOleDb) + { + var isAuto = false; + if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection; + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false; + } + result = Ado.GetInt(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + result = Ado.GetInt(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + if (this.Context.Ado.IsAnyTran() == false && isAuto) + { + this.Ado.Close(); + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + } + } + else + { + result = Ado.GetInt(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + } + After(sql, result); + return result; + } + + public virtual long ExecuteReturnBigIdentity() + { + if (this.InsertObjs.Length == 1 && this.InsertObjs.First() == null) + { + return 0; + } + string sql = _ExecuteReturnBigIdentity(); + long result = 0; + if (InsertBuilder.IsOleDb) + { + var isAuto = false; + if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection; + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false; + } + result = Convert.ToInt64(Ado.GetScalar(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray())); + result = Convert.ToInt64(Ado.GetScalar(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray())); + if (this.Context.Ado.IsAnyTran() == false && isAuto) + { + this.Ado.Close(); + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + } + } + else + { + result = (Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray())).ObjToLong(); + } + After(sql, result); + return result; + } + + public virtual long ExecuteReturnSnowflakeId() + { + if (this.InsertObjs.Length > 1) + { + return this.ExecuteReturnSnowflakeIdList().First(); + } + + var id = SnowFlakeSingle.instance.getID(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType); + Check.Exception(snowProperty == null, "The entity sets the primary key and is long"); + Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true"); + foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName)) + { + item.Value = id; + snowProperty?.PropertyInfo.SetValue(this.InsertObjs.First(), id); + } + this.ExecuteCommand(); + return id; + } + public List ExecuteReturnSnowflakeIdList() + { + List result = new List(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType); + Check.Exception(snowProperty == null, "The entity sets the primary key and is long"); + Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true"); + foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName)) + { + var id = SnowFlakeSingle.instance.getID(); + item.Value = id; + result.Add(id); + var obj = this.InsertObjs.ElementAtOrDefault(item.TableId); + if (obj != null) + { + snowProperty?.PropertyInfo.SetValue(obj, id); + } + } + this.ExecuteCommand(); + return result; + } + public Task ExecuteReturnSnowflakeIdAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ExecuteReturnSnowflakeIdAsync(); + } + public async Task ExecuteReturnSnowflakeIdAsync() + { + var id = SnowFlakeSingle.instance.getID(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType); + Check.Exception(snowProperty == null, "The entity sets the primary key and is long"); + Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true"); + foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName)) + { + item.Value = id; + snowProperty?.PropertyInfo.SetValue(this.InsertObjs.First(), id); + } + await ExecuteCommandAsync().ConfigureAwait(false); + return id; + } + public async Task> ExecuteReturnSnowflakeIdListAsync() + { + List result = new List(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType); + Check.Exception(snowProperty == null, "The entity sets the primary key and is long"); + Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true"); + foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName)) + { + var id = SnowFlakeSingle.instance.getID(); + item.Value = id; + result.Add(id); + var obj = this.InsertObjs.ElementAtOrDefault(item.TableId); + if (obj != null) + { + snowProperty?.PropertyInfo.SetValue(obj, id); + } + } + await ExecuteCommandAsync().ConfigureAwait(false); + return result; + } + + public Task> ExecuteReturnSnowflakeIdListAsync(CancellationToken token) + { + this.Ado.CancellationToken = token; + return ExecuteReturnSnowflakeIdListAsync(); + } + + public virtual T ExecuteReturnEntity() + { + ExecuteCommandIdentityIntoEntity(); + return InsertObjs.First(); + } + public virtual bool ExecuteCommandIdentityIntoEntity() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true) + { + var identity = this.EntityInfo.Columns.FirstOrDefault(it => it.IsIdentity); + if (identity != null) + { + identityKeys = new List() { identity.DbColumnName }; + } + } + if (identityKeys.Count == 0) + { + var snowColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey && it.UnderType == UtilConstants.LongType); + if (snowColumn != null) + { + if (Convert.ToInt64(snowColumn.PropertyInfo.GetValue(result)) == 0) + { + var id = this.ExecuteReturnSnowflakeId(); + snowColumn.PropertyInfo.SetValue(result, id); + } + else + { + ExecuteCommand(); + } + return true; + } + else + { + return this.ExecuteCommand() > 0; + } + } + var idValue = ExecuteReturnBigIdentity(); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(uint))) + { + setValue = Convert.ToUInt32(idValue); + } + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ulong))) + { + setValue = Convert.ToUInt64(idValue); + } + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ushort))) + { + setValue = Convert.ToUInt16(idValue); + } + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(short))) + { + setValue = Convert.ToInt16(idValue); + } + else + setValue = Convert.ToInt32(idValue); + this.Context.EntityMaintenance.GetProperty(identityKey).SetValue(result, setValue, null); + return idValue > 0; + } + public Task ExecuteCommandAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ExecuteCommandAsync(); + } + public async Task ExecuteCommandAsync() + { + if (this.InsertObjs.Length == 1 && this.InsertObjs.First() == null) + { + return 0; + } + string sql = _ExecuteCommand(); + var result = await Ado.ExecuteCommandAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + After(sql, null); + if (result == -1) return this.InsertObjs.Length; + return result; + } + public Task ExecuteReturnIdentityAsync(CancellationToken token) + { + this.Ado.CancellationToken = token; + return ExecuteReturnIdentityAsync(); + } + public virtual async Task ExecuteReturnIdentityAsync() + { + if (this.InsertObjs.Length == 1 && this.InsertObjs.First() == null) + { + return 0; + } + string sql = _ExecuteReturnIdentity(); + var result = 0; + if (InsertBuilder.IsOleDb) + { + var isAuto = false; + if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection; + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false; + } + result = Ado.GetInt(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + result = Ado.GetInt(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + if (this.Context.Ado.IsAnyTran() == false && isAuto) + { + this.Ado.Close(); + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + } + } + else + { + result = await Ado.GetIntAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + } + After(sql, result); + return result; + } + public T ExecuteReturnEntity(bool isIncludesAllFirstLayer) + { + var data = ExecuteReturnEntity(); + if (this.InsertBuilder.IsWithAttr) + { + return this.Context.Root.QueryableWithAttr().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().First(); + } + else + { + return this.Context.Queryable().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().First(); + } + } + public async Task ExecuteReturnEntityAsync() + { + await ExecuteCommandIdentityIntoEntityAsync().ConfigureAwait(false); + return InsertObjs.First(); + } + public async Task ExecuteReturnEntityAsync(bool isIncludesAllFirstLayer) + { + var data = await ExecuteReturnEntityAsync().ConfigureAwait(false); + if (this.InsertBuilder.IsWithAttr) + { + return await Context.Root.QueryableWithAttr().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().FirstAsync().ConfigureAwait(false); + } + else + { + return await Context.Queryable().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().FirstAsync().ConfigureAwait(false); + } + } + public async Task ExecuteCommandIdentityIntoEntityAsync() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (identityKeys.Count == 0) + { + var snowColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey && it.UnderType == UtilConstants.LongType); + if (snowColumn != null) + { + + if (Convert.ToInt64(snowColumn.PropertyInfo.GetValue(result)) == 0) + { + var id = await ExecuteReturnSnowflakeIdAsync().ConfigureAwait(false); + snowColumn.PropertyInfo.SetValue(result, id); + } + else + { + await ExecuteCommandAsync().ConfigureAwait(false); + } + return true; + } + else + { + return await ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + } + var idValue = await ExecuteReturnBigIdentityAsync().ConfigureAwait(false); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(uint))) + { + setValue = Convert.ToUInt32(idValue); + } + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ulong))) + { + setValue = Convert.ToUInt64(idValue); + } + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ushort))) + { + setValue = Convert.ToUInt16(idValue); + } + else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(short))) + { + setValue = Convert.ToInt16(idValue); + } + else + setValue = Convert.ToInt32(idValue); + this.Context.EntityMaintenance.GetProperty(identityKey).SetValue(result, setValue, null); + return idValue > 0; + } + public Task ExecuteReturnBigIdentityAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ExecuteReturnBigIdentityAsync(); + } + public virtual async Task ExecuteReturnBigIdentityAsync() + { + if (this.InsertObjs.Length == 1 && this.InsertObjs.First() == null) + { + return 0; + } + string sql = _ExecuteReturnBigIdentity(); + long result = 0; + if (InsertBuilder.IsOleDb) + { + var isAuto = false; + if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection; + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false; + } + result = Ado.GetInt(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + result = Ado.GetInt(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + if (this.Context.Ado.IsAnyTran() == false && isAuto) + { + this.Ado.Close(); + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; + } + } + else + { + result = (await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false)).ObjToLong(); + } + After(sql, result); + return result; + } + + #endregion + + #region Setting + public InsertablePage PageSize(int pageSize) + { + InsertablePage result = new InsertablePage(); + result.PageSize = pageSize; + result.Context = this.Context; + result.DataList = this.InsertObjs; + result.TableName = this.InsertBuilder.AsName; + result.IsEnableDiffLogEvent = this.IsEnableDiffLogEvent; + result.DiffModel = this.diffModel; + result.IsMySqlIgnore = this.InsertBuilder.MySqlIgnore; + result.IsOffIdentity = this.InsertBuilder.IsOffIdentity; + if (this.InsertBuilder.DbColumnInfoList.Count != 0) + result.InsertColumns = this.InsertBuilder.DbColumnInfoList.GroupBy(it => it.TableId).First().Select(it => it.DbColumnName).ToList(); + return result; + } + public IParameterInsertable UseParameter() + { + var result = new ParameterInsertable(); + result.Context = this.Context; + result.Inserable = this; + return result; + } + public IInsertable AsType(Type tableNameType) + { + return AS(this.Context.EntityMaintenance.GetEntityInfo(tableNameType).DbTableName); + } + public IInsertable AS(string tableName) + { + this.InsertBuilder.AsName = tableName; + return this; ; + } + public IInsertable IgnoreColumns(Expression> columns) + { + if (columns == null) return this; + var ignoreColumns = InsertBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + return this; + } + public IInsertable IgnoreColumns(params string[] columns) + { + if (columns == null) + columns = Array.Empty(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !columns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !columns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + return this; + } + + public IInsertable IgnoreColumnsNull(bool isIgnoreNull = true) + { + if (isIgnoreNull) + { + Check.Exception(this.InsertObjs.Length > 1, ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert, use .PageSize(1).IgnoreColumnsNull().ExecuteCommand()", "ignoreNullColumn 不支持批量操作,你可以用PageSzie(1).IgnoreColumnsNull().ExecuteCommand()")); + this.InsertBuilder.IsNoInsertNull = true; + } + return this; + } + public IInsertable PostgreSQLConflictNothing(string[] columns) + { + this.InsertBuilder.ConflictNothing = columns; + return this; + } + public IInsertable MySqlIgnore() + { + this.InsertBuilder.MySqlIgnore = true; + return this; + } + public IInsertable MySqlIgnore(bool isIgnore) + { + if (isIgnore) + { + return MySqlIgnore(); + } + else + { + return this; + } + } + public IInsertable InsertColumns(Expression> columns) + { + if (columns == null) return this; + var ignoreColumns = InsertBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => ignoreColumns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || ignoreColumns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + return this; + } + + public IInsertable InsertColumns(string[] columns) + { + if (columns == null) return this; + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => columns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || columns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + return this; + } + + public IInsertable With(string lockString) + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + this.InsertBuilder.TableWithString = lockString; + return this; + } + public IInsertable OffIdentity(bool isSetOn) + { + if (isSetOn) + { + return this.OffIdentity(); + } + else + { + return this; + } + } + public IInsertable OffIdentity() + { + this.IsOffIdentity = true; + this.InsertBuilder.IsOffIdentity = true; + return this; + } + public IInsertable IgnoreColumns(bool ignoreNullColumn, bool isOffIdentity = false) + { + Check.Exception(this.InsertObjs.Length > 1 && ignoreNullColumn, ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert, use .PageSize(1).IgnoreColumnsNull().ExecuteCommand()", "ignoreNullColumn 不支持批量操作, 你可以使用 .PageSize(1).IgnoreColumnsNull().ExecuteCommand()")); + this.IsOffIdentity = isOffIdentity; + this.InsertBuilder.IsOffIdentity = isOffIdentity; + if (this.InsertBuilder.LambdaExpressions == null) + this.InsertBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig); + this.InsertBuilder.IsNoInsertNull = ignoreNullColumn; + return this; + } + + public IInsertable RemoveDataCache() + { + this.RemoveCacheFunc = () => + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + CacheSchemeMain.RemoveCache(cacheService, this.Context.EntityMaintenance.GetTableName()); + }; + return this; + } + public IInsertable RemoveDataCache(string likeString) + { + this.RemoveCacheFunc = () => + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + CacheSchemeMain.RemoveCacheByLike(cacheService, likeString); + }; + return this; + } + public MySqlBlukCopy UseMySql() + { + return new MySqlBlukCopy(this.Context, this.SqlBuilder, InsertObjs); + } + public SqlServerBlukCopy UseSqlServer() + { + PreToSql(); + var currentType = this.Context.CurrentConnectionConfig.DbType; + Check.Exception(currentType != DbType.SqlServer, "UseSqlServer no support " + currentType); + SqlServerBlukCopy result = new SqlServerBlukCopy(); + result.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.GroupBy(it => it.TableId).ToList(); + result.InsertBuilder = this.InsertBuilder; + result.Builder = this.SqlBuilder; + result.Context = this.Context; + result.Inserts = this.InsertObjs; + return result; + } + public OracleBlukCopy UseOracle() + + { + + PreToSql(); + + var currentType = this.Context.CurrentConnectionConfig.DbType; + + Check.Exception(currentType != DbType.Oracle, "UseSqlServer no support " + currentType); + + OracleBlukCopy result = new OracleBlukCopy(); + + result.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.GroupBy(it => it.TableId).ToList(); + + result.InsertBuilder = this.InsertBuilder; + + result.Builder = this.SqlBuilder; + + result.Context = this.Context; + + result.Inserts = this.InsertObjs; + InsertBuilder.IsBlukCopy = true; + + return result; + + } + + + public IInsertable EnableDiffLogEventIF(bool isDiffLogEvent, object diffLogBizData) + { + if (isDiffLogEvent) + { + return EnableDiffLogEvent(diffLogBizData); + } + return this; + } + public IInsertable EnableDiffLogEvent(object businessData = null) + { + //Check.Exception(this.InsertObjs.HasValue() && this.InsertObjs.Count() > 1, "DiffLog does not support batch operations"); + diffModel = new DiffLogModel(); + this.IsEnableDiffLogEvent = true; + diffModel.BusinessData = businessData; + diffModel.DiffType = DiffType.insert; + return this; + } + + public ISubInsertable AddSubList(Expression> items) + { + Check.Exception(GetPrimaryKeys().Count == 0, typeof(T).Name + " need Primary key"); + Check.Exception(GetPrimaryKeys().Count > 1, typeof(T).Name + "Multiple primary keys are not supported"); + //Check.Exception(this.InsertObjs.Count() > 1, "SubInserable No Support Insertable(List)"); + //Check.Exception(items.ToString().Contains(".First().")==false, items.ToString()+ " not supported "); + if (this.InsertObjs == null || this.InsertObjs.Length == 0) + { + return new SubInsertable(); + } + SubInsertable result = new SubInsertable(); + result.InsertObjects = this.InsertObjs; + result.Context = this.Context; + result.SubList = new List(); + result.SubList.Add(new SubInsertTreeExpression() { Expression = items }); + result.InsertBuilder = this.InsertBuilder; + result.Pk = GetPrimaryKeys().First(); + result.Entity = this.EntityInfo; + return result; + } + public ISubInsertable AddSubList(Expression> tree) + { + Check.Exception(GetPrimaryKeys().Count == 0, typeof(T).Name + " need Primary key"); + Check.Exception(GetPrimaryKeys().Count > 1, typeof(T).Name + "Multiple primary keys are not supported"); + //Check.Exception(this.InsertObjs.Count() > 1, "SubInserable No Support Insertable(List)"); + //Check.Exception(items.ToString().Contains(".First().")==false, items.ToString()+ " not supported "); + if (this.InsertObjs == null || this.InsertObjs.Length == 0) + { + return new SubInsertable(); + } + SubInsertable result = new SubInsertable(); + result.InsertObjects = this.InsertObjs; + result.Context = this.Context; + result.SubList = new List(); + result.InsertBuilder = this.InsertBuilder; + result.Pk = GetPrimaryKeys().First(); + result.Entity = this.EntityInfo; + result.AddSubList(tree); + return result; + } + public SplitInsertable SplitTable(SplitType splitType) + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + SplitTableContext helper = new SplitTableContext(Context) + { + EntityInfo = this.EntityInfo + }; + helper.CheckPrimaryKey(); + SplitInsertable result = new SplitInsertable(); + result.Context = this.Context; + result.EntityInfo = this.EntityInfo; + result.Helper = helper; + result.SplitType = splitType; + result.TableNames = new List>(); + result.MySqlIgnore = this.InsertBuilder.MySqlIgnore; + foreach (var item in this.InsertObjs) + { + var splitFieldValue = helper.GetValue(splitType, item); + var tableName = helper.GetTableName(splitType, splitFieldValue); + result.TableNames.Add(new KeyValuePair(tableName, item)); + } + result.Inserable = this; + return result; + } + + public SplitInsertable SplitTable() + { + if (StaticConfig.SplitTableCreateTableFunc != null) + { + StaticConfig.SplitTableCreateTableFunc(typeof(T), this.InsertObjs); + } + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + var splitTableAttribute = typeof(T).GetCustomAttribute(); + if (splitTableAttribute != null) + { + return SplitTable((splitTableAttribute as SplitTableAttribute).SplitType); + } + else + { + Check.Exception(true, $" {typeof(T).Name} need SplitTableAttribute"); + return null; + } + } + + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/ParameterInsertable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/ParameterInsertable.cs new file mode 100644 index 000000000..ebe07f496 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/ParameterInsertable.cs @@ -0,0 +1,209 @@ +using System.Text; + +namespace SqlSugar +{ + public class ParameterInsertable : IParameterInsertable where T : class, new() + { + internal IInsertable Inserable { get; set; } + internal SqlSugarProvider Context { get; set; } + public int ExecuteCommand() + { + if (this.Context.CurrentConnectionConfig.DbType.IsIn(DbType.Oracle, DbType.Dm)) + { + return DefaultExecuteCommand(); + } + else + { + return ValuesExecuteCommand(); + } + } + public async Task ExecuteCommandAsync() + { + if (this.Context.CurrentConnectionConfig.DbType.IsIn(DbType.Oracle, DbType.Dm)) + { + return await DefaultExecuteCommandAsync().ConfigureAwait(false); + } + else + { + return await ValuesExecuteCommandAsync().ConfigureAwait(false); + } + } + public int DefaultExecuteCommand() + { + int result = 0; + var inserable = Inserable as InsertableProvider; + var columns = inserable.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(it => it.Key).Distinct().ToList(); + var tableWithString = inserable.InsertBuilder.TableWithString; + var removeCacheFunc = inserable.RemoveCacheFunc; + var objects = inserable.InsertObjs; + this.Context.Utilities.PageEach(objects, 60, pagelist => + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + this.Context.AddQueue("begin"); + foreach (var item in pagelist) + { + var itemable = this.Context.Insertable(item); + itemable.InsertBuilder.DbColumnInfoList = itemable.InsertBuilder.DbColumnInfoList.Where(it => columns.Contains(it.DbColumnName)).ToList(); + itemable.InsertBuilder.TableWithString = tableWithString; + itemable.InsertBuilder.AsName = Inserable.InsertBuilder.AsName; + (itemable as InsertableProvider).RemoveCacheFunc = removeCacheFunc; + itemable.AddQueue(); + } + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + this.Context.AddQueue("end \r\n"); + result += this.Context.SaveQueues(false); + }); + //if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + // result=objects.Length; + if (result == -1) + { + result = objects.Length; + } + return result; + } + public async Task DefaultExecuteCommandAsync() + { + int result = 0; + var inserable = Inserable as InsertableProvider; + var columns = inserable.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(it => it.Key).Distinct().ToList(); + var tableWithString = inserable.InsertBuilder.TableWithString; + var removeCacheFunc = inserable.RemoveCacheFunc; + var objects = inserable.InsertObjs; + await Context.Utilities.PageEachAsync(objects, 60, async pagelist => + { + if (Context.CurrentConnectionConfig.DbType == DbType.Oracle) + Context.AddQueue("begin"); + foreach (var item in pagelist) + { + var itemable = Context.Insertable(item); + itemable.InsertBuilder.DbColumnInfoList = itemable.InsertBuilder.DbColumnInfoList.Where(it => columns.Contains(it.DbColumnName)).ToList(); + itemable.InsertBuilder.TableWithString = tableWithString; + itemable.InsertBuilder.AsName = Inserable.InsertBuilder.AsName; + (itemable as InsertableProvider).RemoveCacheFunc = removeCacheFunc; + itemable.AddQueue(); + } + if (Context.CurrentConnectionConfig.DbType == DbType.Oracle) + Context.AddQueue("end"); + result += await Context.SaveQueuesAsync(false).ConfigureAwait(false); + if (Context.CurrentConnectionConfig.DbType == DbType.Oracle) + result = objects.Length; + return result; + }).ConfigureAwait(false); + return result; + } + public int ValuesExecuteCommand() + { + + int result = 0; + var inserable = Inserable as InsertableProvider; + var columns = inserable.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(it => it.Key).Distinct().ToList(); + var tableWithString = inserable.InsertBuilder.AsName; + var removeCacheFunc = inserable.RemoveCacheFunc; + var objects = inserable.InsertObjs; + if (objects == null || objects.Length == 0 || (objects.Length == 1 && objects.First() == null)) + { + return result; + } + var identityList = inserable.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.PropertyName).ToArray(); + if (inserable.IsOffIdentity) + { + identityList = Array.Empty(); + } + var pageSize = 100; + var count = inserable.EntityInfo.Columns.Count; + pageSize = GetPageSize(pageSize, count); + this.Context.Utilities.PageEach(objects, pageSize, pagelist => + { + + StringBuilder batchInsetrSql; + List allParamter = new List(); + GetInsertValues(identityList, columns, tableWithString, removeCacheFunc, pagelist, out batchInsetrSql, allParamter); + result += this.Context.Ado.ExecuteCommand(batchInsetrSql.ToString(), allParamter); + + }); + return result; + + } + + public async Task ValuesExecuteCommandAsync() + { + int result = 0; + var inserable = Inserable as InsertableProvider; + var columns = inserable.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(it => it.Key).Distinct().ToList(); + var tableWithString = inserable.InsertBuilder.AsName; + var removeCacheFunc = inserable.RemoveCacheFunc; + var objects = inserable.InsertObjs; + var identityList = inserable.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.PropertyName).ToArray(); + if (inserable.IsOffIdentity) + { + identityList = Array.Empty(); + } + await Context.Utilities.PageEachAsync(objects, 100, async pagelist => + { + + StringBuilder batchInsetrSql; + List allParamter = new List(); + GetInsertValues(identityList, columns, tableWithString, removeCacheFunc, pagelist, out batchInsetrSql, allParamter); + result += await Context.Ado.ExecuteCommandAsync(batchInsetrSql.ToString(), allParamter).ConfigureAwait(false); + + }).ConfigureAwait(false); + return result; + } + #region Values Helper + + private static int GetPageSize(int pageSize, int count) + { + if (pageSize * count > 2100) + { + pageSize = 50; + } + if (pageSize * count > 2100) + { + pageSize = 20; + } + if (pageSize * count > 2100) + { + pageSize = 10; + } + + return pageSize; + } + private void GetInsertValues(string[] identitys, List columns, string tableWithString, Action removeCacheFunc, List items, out StringBuilder batchInsetrSql, List allParamter) + { + var itemable = this.Context.Insertable(items); + itemable.InsertBuilder.DbColumnInfoList = itemable.InsertBuilder.DbColumnInfoList.Where(it => columns.Contains(it.DbColumnName)).ToList(); + itemable.InsertBuilder.TableWithString = tableWithString; + (itemable as InsertableProvider).RemoveCacheFunc = removeCacheFunc; + batchInsetrSql = new StringBuilder(); + batchInsetrSql.Append("INSERT INTO " + itemable.InsertBuilder.GetTableNameString + " "); + batchInsetrSql.Append('('); + var groupList = itemable.InsertBuilder.DbColumnInfoList.Where(it => !identitys.Contains(it.PropertyName)).GroupBy(it => it.TableId).ToList(); + string columnsString = string.Join(",", groupList.First().Select(it => itemable.InsertBuilder.Builder.GetTranslationColumnName(it.DbColumnName))); + batchInsetrSql.Append(columnsString); + batchInsetrSql.Append(") VALUES"); + string insertColumns = ""; + foreach (var gitem in groupList) + { + batchInsetrSql.Append('('); + insertColumns = string.Join(",", gitem.Select(it => FormatValue(it.PropertyType, it.DbColumnName, it.Value, allParamter, itemable.InsertBuilder.Builder.SqlParameterKeyWord))); + batchInsetrSql.Append(insertColumns); + if (groupList.Last() == gitem) + { + batchInsetrSql.Append(") "); + } + else + { + batchInsetrSql.Append("), "); + } + } + } + private string FormatValue(Type type, string name, object value, List allParamter, string keyword) + { + var result = keyword + name + allParamter.Count; + var addParameter = new SugarParameter(result, value, type); + allParamter.Add(addParameter); + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/SplitInsertable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/SplitInsertable.cs new file mode 100644 index 000000000..a78b84bb9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/SplitInsertable.cs @@ -0,0 +1,245 @@ +namespace SqlSugar +{ + public class SplitInsertable where T : class, new() + { + private static readonly object SplitLockObj = new object(); + public SqlSugarProvider Context; + internal SplitTableContext Helper; + public EntityInfo EntityInfo; + public SplitType SplitType; + internal IInsertable Inserable { get; set; } + internal List> TableNames { get; set; } + internal bool MySqlIgnore { get; set; } + + public int ExecuteCommand() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = _ExecuteCommand(); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return _ExecuteCommand(); + } + } + public async Task ExecuteCommandAsync() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = await _ExecuteCommandAsync().ConfigureAwait(false); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return await _ExecuteCommandAsync().ConfigureAwait(false); + } + } + + + public List ExecuteReturnSnowflakeIdList() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = _ExecuteReturnSnowflakeIdList(); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return _ExecuteReturnSnowflakeIdList(); + } + } + public async Task> ExecuteReturnSnowflakeIdListAsync() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = await _ExecuteReturnSnowflakeIdListAsync().ConfigureAwait(false); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return await _ExecuteReturnSnowflakeIdListAsync().ConfigureAwait(false); + } + } + + + public long ExecuteReturnSnowflakeId() + { + return ExecuteReturnSnowflakeIdList().FirstOrDefault(); + } + public async Task ExecuteReturnSnowflakeIdAsync() + { + var list = await ExecuteReturnSnowflakeIdListAsync().ConfigureAwait(false); + return list.FirstOrDefault(); + } + + + internal int _ExecuteCommand() + { + CreateTable(); + var result = 0; + var groups = TableNames.GroupBy(it => it.Key).ToList(); + var parent = ((InsertableProvider)Inserable); + var names = parent.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(i => i.Key).ToList(); + foreach (var item in groups) + { + var list = item.Select(it => it.Value as T).ToList(); + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + this.Context.Aop.DataExecuting = null; + var groupInserable = (InsertableProvider)this.Context.Insertable(list); + this.Context.Aop.DataExecuting = dataEvent; + groupInserable.InsertBuilder.TableWithString = parent.InsertBuilder.TableWithString; + groupInserable.RemoveCacheFunc = parent.RemoveCacheFunc; + groupInserable.diffModel = parent.diffModel; + groupInserable.IsEnableDiffLogEvent = parent.IsEnableDiffLogEvent; + groupInserable.InsertBuilder.IsNoInsertNull = parent.InsertBuilder.IsNoInsertNull; + groupInserable.IsOffIdentity = parent.IsOffIdentity; + groupInserable.InsertBuilder.MySqlIgnore = this.MySqlIgnore; + result += groupInserable.AS(item.Key).InsertColumns(names.ToArray()).ExecuteCommand(); + } + return result; + } + internal async Task _ExecuteCommandAsync() + { + CreateTable(); + var result = 0; + var groups = TableNames.GroupBy(it => it.Key).ToList(); + var parent = ((InsertableProvider)Inserable); + var names = parent.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(i => i.Key).ToList(); + foreach (var item in groups) + { + var list = item.Select(it => it.Value as T).ToList(); + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + this.Context.Aop.DataExecuting = null; + var groupInserable = (InsertableProvider)this.Context.Insertable(list); + this.Context.Aop.DataExecuting = dataEvent; + groupInserable.InsertBuilder.TableWithString = parent.InsertBuilder.TableWithString; + groupInserable.RemoveCacheFunc = parent.RemoveCacheFunc; + groupInserable.diffModel = parent.diffModel; + groupInserable.IsEnableDiffLogEvent = parent.IsEnableDiffLogEvent; + groupInserable.InsertBuilder.IsNoInsertNull = parent.InsertBuilder.IsNoInsertNull; + groupInserable.IsOffIdentity = parent.IsOffIdentity; + groupInserable.InsertBuilder.MySqlIgnore = this.MySqlIgnore; + result += await groupInserable.AS(item.Key).InsertColumns(names.ToArray()).ExecuteCommandAsync().ConfigureAwait(false); + } + return result; + } + + internal List _ExecuteReturnSnowflakeIdList() + { + CreateTable(); + var result = new List(); + var groups = TableNames.GroupBy(it => it.Key).ToList(); + var parent = ((InsertableProvider)Inserable); + var names = parent.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(i => i.Key).ToList(); + foreach (var item in groups) + { + var list = item.Select(it => it.Value as T).ToList(); + var groupInserable = (InsertableProvider)this.Context.Insertable(list); + groupInserable.InsertBuilder.TableWithString = parent.InsertBuilder.TableWithString; + groupInserable.RemoveCacheFunc = parent.RemoveCacheFunc; + groupInserable.diffModel = parent.diffModel; + groupInserable.IsEnableDiffLogEvent = parent.IsEnableDiffLogEvent; + groupInserable.InsertBuilder.IsNoInsertNull = parent.InsertBuilder.IsNoInsertNull; + groupInserable.IsOffIdentity = parent.IsOffIdentity; + groupInserable.InsertBuilder.MySqlIgnore = this.MySqlIgnore; + var idList = groupInserable.AS(item.Key).InsertColumns(names.ToArray()).ExecuteReturnSnowflakeIdList(); + result.AddRange(idList); + } + return result; + } + internal async Task> _ExecuteReturnSnowflakeIdListAsync() + { + CreateTable(); + var result = new List(); + var groups = TableNames.GroupBy(it => it.Key).ToList(); + var parent = ((InsertableProvider)Inserable); + var names = parent.InsertBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(i => i.Key).ToList(); + foreach (var item in groups) + { + var list = item.Select(it => it.Value as T).ToList(); + var groupInserable = (InsertableProvider)this.Context.Insertable(list); + groupInserable.InsertBuilder.TableWithString = parent.InsertBuilder.TableWithString; + groupInserable.RemoveCacheFunc = parent.RemoveCacheFunc; + groupInserable.diffModel = parent.diffModel; + groupInserable.IsEnableDiffLogEvent = parent.IsEnableDiffLogEvent; + groupInserable.InsertBuilder.IsNoInsertNull = parent.InsertBuilder.IsNoInsertNull; + groupInserable.IsOffIdentity = parent.IsOffIdentity; + groupInserable.InsertBuilder.MySqlIgnore = this.MySqlIgnore; + var idList = await groupInserable.AS(item.Key).InsertColumns(names.ToArray()).ExecuteReturnSnowflakeIdListAsync().ConfigureAwait(false); + result.AddRange(idList); + } + return result; + } + + + private void CreateTable() + { + var isLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + foreach (var item in TableNames.GroupBy(it => it.Key).Select(it => it).ToDictionary(it => it.Key, it => it.First().Value)) + { + var newDb = this.Context.CopyNew(); + newDb.CurrentConnectionConfig.IsAutoCloseConnection = true; + if (!newDb.DbMaintenance.IsAnyTable(item.Key, false)) + { + lock (SplitLockObj) + { + var newDb2 = this.Context.CopyNew(); + newDb2.CurrentConnectionConfig.IsAutoCloseConnection = true; + if (!newDb2.DbMaintenance.IsAnyTable(item.Key, false)) + { + if (item.Value != null) + { + this.Context.MappingTables.Add(EntityInfo.EntityName, item.Key); + this.Context.CodeFirst.InitTables(); + } + } + } + } + } + this.Context.Ado.IsEnableLogEvent = isLog; + this.Context.MappingTables.Add(EntityInfo.EntityName, EntityInfo.DbTableName); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/SubInserable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/SubInserable.cs new file mode 100644 index 000000000..197ed9cfb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/InsertableProvider/SubInserable.cs @@ -0,0 +1,323 @@ +using System.Data.SqlTypes; +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubInsertable : ISubInsertable where T : class, new() + { + internal EntityInfo Entity { get; set; } + internal List SubList { get; set; } + internal SqlSugarProvider Context { get; set; } + internal T[] InsertObjects { get; set; } + internal InsertBuilder InsertBuilder { get; set; } + internal string Pk { get; set; } + + public ISubInsertable AddSubList(Expression> items) + { + if (this.SubList == null) + this.SubList = new List(); + this.SubList.Add(new SubInsertTreeExpression() { Expression = items }); + return this; + } + public ISubInsertable AddSubList(Expression> tree) + { + try + { + var lamda = (tree as LambdaExpression); + var memInit = lamda.Body as MemberInitExpression; + if (memInit.Bindings != null) + { + + MemberAssignment memberAssignment = (MemberAssignment)memInit.Bindings[0]; + SubList.Add(new SubInsertTreeExpression() + { + Expression = memberAssignment.Expression, + Childs = GetSubInsertTree(((MemberAssignment)memInit.Bindings[1]).Expression) + }); + } + } + catch + { + Check.Exception(true, tree.ToString() + " format error "); + } + return this; + } + + private List GetSubInsertTree(Expression expression) + { + List resul = new List(); + + if (expression is ListInitExpression) + { + ListInitExpression exp = expression as ListInitExpression; + foreach (var item in exp.Initializers) + { + SubInsertTreeExpression tree = new SubInsertTreeExpression(); + var memInit = item.Arguments[0] as MemberInitExpression; + if (memInit.Bindings != null) + { + MemberAssignment memberAssignment = (MemberAssignment)memInit.Bindings[0]; + tree.Expression = memberAssignment.Expression; + if (memInit.Bindings.Count > 1) + { + tree.Childs = GetSubInsertTree(((MemberAssignment)memInit.Bindings[1]).Expression); + } + } + resul.Add(tree); + } + } + else + { + + } + return resul; + } + + [Obsolete("use ExecuteCommand")] + public object ExecuteReturnPrimaryKey() + { + return ExecuteCommand(); + } + + public async Task ExecuteCommandAsync() + { + object resut = 0; + await Task.Run(() => + { + resut = ExecuteCommand(); + }).ConfigureAwait(false); + return resut; + } + public object ExecuteCommand() + { + var isNoTrean = this.Context.Ado.Transaction == null; + try + { + if (isNoTrean) + this.Context.Ado.BeginTran(); + + var result = Execute(); + + if (isNoTrean) + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + if (isNoTrean) + this.Context.Ado.RollbackTran(); + throw; + } + } + + private int Execute() + { + if (InsertObjects?.Length > 0) + { + var isIdEntity = IsIdEntity(this.Entity); + if (!isIdEntity) + { + this.Context.Insertable(InsertObjects).ExecuteCommand(); + } + foreach (var InsertObject in InsertObjects) + { + int id = 0; + if (isIdEntity) + { + id = this.Context.Insertable(InsertObject).ExecuteReturnIdentity(); + this.Entity.Columns.First(it => it.IsIdentity || it.OracleSequenceName.HasValue()).PropertyInfo.SetValue(InsertObject, id); + } + var pk = GetPrimaryKey(this.Entity, InsertObject, id); + AddChildList(this.SubList, InsertObject, pk); + } + return InsertObjects.Length; + } + else + { + return 0; + } + } + [Obsolete("use ExecuteCommandAsync")] + public Task ExecuteReturnPrimaryKeyAsync() + { + return Task.FromResult(ExecuteReturnPrimaryKey()); + } + + private bool IsIdEntity(EntityInfo entity) + { + return entity.Columns.Where(it => it.IsIdentity || it.OracleSequenceName.HasValue()).Any(); + } + + private void AddChildList(List items, object insertObject, object pkValue) + { + if (items != null) + { + foreach (var item in items) + { + MemberExpression subMemberException; + string subMemberName = GetMemberName(item, out subMemberException); + string childName = GetChildName(item, subMemberException); + var childListProperty = insertObject.GetType().GetProperty(childName); + if (childListProperty == null) + { + childName = subMemberName; + childListProperty = insertObject.GetType().GetProperty(childName); + } + var childList = childListProperty.GetValue(insertObject); + if (childList != null) + { + if (!(childList is IEnumerable)) + { + childList = new List() { childList }; + } + if (!string.IsNullOrEmpty(subMemberName) && subMemberName != childName) + { + foreach (var child in childList as IEnumerable) + { + child.GetType().GetProperty(subMemberName).SetValue(child, pkValue); + } + } + if (!(childList as IEnumerable).Any()) + { + continue; + } + var type = (childList as IEnumerable).First().GetType(); + this.Context.InitMappingInfo(type); + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + var isIdentity = IsIdEntity(entityInfo); + var tableName = entityInfo.DbTableName; + List> insertList = new List>(); + var entityList = (childList as IEnumerable).ToList(); + foreach (var child in entityList) + { + insertList.Add(GetInsertDictionary(child, entityInfo)); + } + if (!isIdentity) + { + this.Context.Insertable(insertList).AS(tableName).ExecuteCommand(); + } + int i = 0; + foreach (var insert in insertList) + { + int id = 0; + if (isIdentity) + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + var sqlobj = this.Context.Insertable(insert).AS(tableName).ToSql(); + id = this.Context.Ado.GetInt(sqlobj.Key + " returning " + this.InsertBuilder.Builder.GetTranslationColumnName(entityInfo.Columns.First(it => isIdentity).DbColumnName), sqlobj.Value); + } + else + { + id = this.Context.Insertable(insert).AS(tableName).ExecuteReturnIdentity(); + } + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle && id == 0) + { + var seqName = entityInfo.Columns.First(it => it.OracleSequenceName.HasValue())?.OracleSequenceName; + id = this.Context.Ado.GetInt("select " + seqName + ".currval from dual"); + } + } + var entity = entityList[i]; + var pk = GetPrimaryKey(entityInfo, entity, id); + AddChildList(item.Childs, entity, pk); + ++i; + } + } + } + } + } + private Dictionary GetInsertDictionary(object insetObject, EntityInfo subEntity) + { + Dictionary insertDictionary = new Dictionary(); + foreach (var item in subEntity.Columns) + { + if (item.IsIdentity || item.IsIgnore) + { + + } + else if (!string.IsNullOrEmpty(item.OracleSequenceName) && this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + var value = "{SugarSeq:=}" + item.OracleSequenceName + ".nextval{SugarSeq:=}"; + insertDictionary.Add(item.DbColumnName, value); + continue; + } + else + { + var value = item.PropertyInfo.GetValue(insetObject); + if (value == null && this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + var underType = UtilMethods.GetUnderType(item.PropertyInfo.PropertyType); + if (underType == UtilConstants.DateType) + { + value = SqlDateTime.Null; + } + } + insertDictionary.Add(item.DbColumnName, value); + } + } + return insertDictionary; + } + private static string GetChildName(SubInsertTreeExpression item, MemberExpression subMemberException) + { + string childName; + MemberExpression listMember = null; + if (subMemberException.Expression is MethodCallExpression) + { + listMember = (subMemberException.Expression as MethodCallExpression).Arguments.First() as MemberExpression; + + } + else + { + listMember = (subMemberException.Expression as MemberExpression); + } + if (listMember == null && item.Expression is LambdaExpression) + { + listMember = (item.Expression as LambdaExpression).Body as MemberExpression; + } + if (listMember == null && item.Expression is MemberExpression) + { + listMember = item.Expression as MemberExpression; + } + childName = listMember.Member.Name; + return childName; + } + + private static string GetMemberName(SubInsertTreeExpression item, out MemberExpression subMemberException) + { + string subMemberName = null; + Expression lambdaExpression; + if (item.Expression is LambdaExpression) + { + lambdaExpression = (item.Expression as LambdaExpression).Body; + } + else + { + lambdaExpression = item.Expression; + } + if (lambdaExpression is UnaryExpression) + { + lambdaExpression = (lambdaExpression as UnaryExpression).Operand; + } + subMemberException = lambdaExpression as MemberExpression; + subMemberName = subMemberException.Member.Name; + return subMemberName; + } + + private object GetPrimaryKey(EntityInfo entityInfo, object InsertObject, int id) + { + object pkValue; + if (id.ObjToInt() == 0) + { + var primaryProperty = entityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + Check.Exception(primaryProperty == null, entityInfo.EntityName + " no primarykey"); + pkValue = primaryProperty.PropertyInfo.GetValue(InsertObject); + } + else + { + pkValue = id; + } + + return pkValue; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/AppendNavInfoList.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/AppendNavInfoList.cs new file mode 100644 index 000000000..5c368d523 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/AppendNavInfoList.cs @@ -0,0 +1,21 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class AppendNavInfo + { + public Dictionary MappingNavProperties { get; set; } = new Dictionary(); + public Dictionary AppendProperties { get; set; } = new Dictionary(); + public List Result { get; set; } = new List(); + } + internal class AppendNavResult + { + public Dictionary result = new Dictionary(); + } + internal class MappingNavColumnInfo + { + public List ExpressionList { get; set; } + public string Name { get; set; } + public string ParentName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/QueryableAppendColumn.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/QueryableAppendColumn.cs new file mode 100644 index 000000000..7dd386870 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/QueryableAppendColumn.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + internal class QueryableAppendColumn + { + public string AsName { get; set; } + public int Index { get; set; } + public object Value { get; set; } + public string Name { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/QueryableFormat.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/QueryableFormat.cs new file mode 100644 index 000000000..f0b6a5a98 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/QueryableFormat.cs @@ -0,0 +1,14 @@ +using System.Reflection; + +namespace SqlSugar +{ + internal class QueryableFormat + { + public Type Type { get; set; } + public string TypeString { get; set; } + public string Format { get; set; } + public string PropertyName { get; set; } + public string MethodName { get; set; } + public MethodInfo MethodInfo { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/SqlInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/SqlInfo.cs new file mode 100644 index 000000000..35c4e561d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/SqlInfo.cs @@ -0,0 +1,17 @@ +namespace SqlSugar +{ + + internal class SqlInfo + { + public bool IsSelectNav { get; set; } + public int? Take { get; set; } + public int? Skip { get; set; } + public string WhereString { get; set; } + public string OrderByString { get; set; } + public string SelectString { get; set; } + public List Parameters { get; set; } + public List MappingExpressions { get; set; } + public string TableShortName { get; set; } + public Func, IEnumerable> SplitTable { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/SubQueryToListDefaultT.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/SubQueryToListDefaultT.cs new file mode 100644 index 000000000..191c5e490 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Entities/SubQueryToListDefaultT.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + internal class SubQueryToListDefaultT + { + public object id { get; set; } + public object sugarIndex { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Includes.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Includes.cs new file mode 100644 index 000000000..7eb44e596 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Includes.cs @@ -0,0 +1,501 @@ +using System.Data; +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public ISugarQueryable IncludesByExpression2(Expression include1, Expression include2) + { + _Includes(this.Context, include1, include2); + return this; + } + public ISugarQueryable IncludesByExpression3(Expression include1, Expression include2, Expression include3) + { + _Includes(this.Context, include1, include2, include3); + return this; + } + public ISugarQueryable IncludesByExpression4(Expression include1, Expression include2, Expression include3, Expression include4) + { + _Includes(this.Context, include1, include2, include3, include4); + return this; + } + public ISugarQueryable IncludesByExpression5(Expression include1, Expression include2, Expression include3, Expression include4, Expression include5) + { + _Includes(this.Context, include1, include2, include3, include4, include5); + return this; + } + public ISugarQueryable IncludesByExpression(Expression include1) + { + _Includes(this.Context, include1); + return this; + } + public ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2) + { + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression2") + .First(); + List parametres = new List(); + List types = new List(); + var entityInfo = this.EntityInfo; + method = GetIncludesByNameStringMethod(types, navMemberName, method, parametres, entityInfo); + //var navFirst = GetNavColumnInfo(navMemberName, entityInfo); + var entityInfo2 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName2, method, parametres, entityInfo2); + method.MakeGenericMethod(types.ToArray()).Invoke(this, parametres.Cast().ToArray()); + return this; + } + public ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2, string thenNavMemberName3) + { + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression3") + .First(); + List parametres = new List(); + List types = new List(); + var entityInfo = this.EntityInfo; + method = GetIncludesByNameStringMethod(types, navMemberName, method, parametres, entityInfo); + //var navFirst = GetNavColumnInfo(navMemberName, entityInfo); + var entityInfo2 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName2, method, parametres, entityInfo2); + var entityInfo3 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName3, method, parametres, entityInfo3); + method.MakeGenericMethod(types.ToArray()).Invoke(this, parametres.Cast().ToArray()); + return this; + } + public ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2, string thenNavMemberName3, string thenNavMemberName4) + { + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression4") + .First(); + List parametres = new List(); + List types = new List(); + var entityInfo = this.EntityInfo; + method = GetIncludesByNameStringMethod(types, navMemberName, method, parametres, entityInfo); + //var navFirst = GetNavColumnInfo(navMemberName, entityInfo); + var entityInfo2 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName2, method, parametres, entityInfo2); + var entityInfo3 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName3, method, parametres, entityInfo3); + var entityInfo4 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName4, method, parametres, entityInfo4); + method.MakeGenericMethod(types.ToArray()).Invoke(this, parametres.Cast().ToArray()); + return this; + } + public ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2, string thenNavMemberName3, string thenNavMemberName4, string thenNavMemberName5) + { + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression5") + .First(); + List parametres = new List(); + List types = new List(); + var entityInfo = this.EntityInfo; + method = GetIncludesByNameStringMethod(types, navMemberName, method, parametres, entityInfo); + //var navFirst = GetNavColumnInfo(navMemberName, entityInfo); + var entityInfo2 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName2, method, parametres, entityInfo2); + var entityInfo3 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName3, method, parametres, entityInfo3); + var entityInfo4 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName4, method, parametres, entityInfo4); + var entityInfo5 = this.Context.EntityMaintenance.GetEntityInfo(types.Last()); + method = GetIncludesByNameStringMethod(types, thenNavMemberName5, method, parametres, entityInfo5); + method.MakeGenericMethod(types.ToArray()).Invoke(this, parametres.Cast().ToArray()); + return this; + } + private static MethodInfo GetIncludesByNameStringMethod(List types, string navMemberName, MethodInfo method, List parametres, EntityInfo entityInfo) + { + var navFirst = GetNavColumnInfo(navMemberName, entityInfo); + parametres.AddRange(GetIncludesByNameStringParameters(entityInfo.Type, navFirst)); + if (navFirst.PropertyInfo.PropertyType.FullName.IsCollectionsList()) + { + types.Add(navFirst.PropertyInfo.PropertyType.GetGenericArguments()[0]); + } + else + { + types.Add(navFirst.PropertyInfo.PropertyType); + } + return method; + } + + private static EntityColumnInfo GetNavColumnInfo(string navMemberName, EntityInfo entityInfo) + { + return entityInfo.Columns.Where(it => it.Navigat != null && it.PropertyName.EqualCase(navMemberName)).FirstOrDefault(); + } + + private static List GetIncludesByNameStringParameters(Type type, EntityColumnInfo item) + { + var parametres = new List { }; + Check.ExceptionEasy(item == null, "\r\nThe \"IncludesByNameString\" method encountered an error. The navigation object does not exist. Please check the parameters and navigation configuration.", "IncludesByNameString方法出错,导航对象不存在,请检查参数和导航配置"); + var properyType = item.PropertyInfo.PropertyType; + var properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + } + var exp = ExpressionBuilderHelper.CreateExpressionSelectField(type, item.PropertyName, properyType); + parametres.Add(exp); + return parametres; + } + + public ISugarQueryable IncludesByNameString(string navMemberName) + { + var navs = this.EntityInfo.Columns.Where(it => it.Navigat != null && it.PropertyName.EqualCase(navMemberName)).ToList(); + foreach (var item in navs) + { + var properyType = item.PropertyInfo.PropertyType; + var properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + } + var exp = ExpressionBuilderHelper.CreateExpressionSelectField(typeof(T), item.PropertyName, properyType); + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression") + .First() + .MakeGenericMethod(properyItemType); + method.Invoke(this, new object[] { exp }); + } + return this; + } + public ISugarQueryable IncludesAllFirstLayer(params string[] ignoreProperyNameList) + { + var navs = this.EntityInfo.Columns.Where(it => it.Navigat != null).ToList(); + foreach (var item in navs) + { + if (ignoreProperyNameList?.Any(z => z.EqualCase(item.PropertyName)) == true) + { + //future + } + else + { + var properyType = item.PropertyInfo.PropertyType; + var properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + } + var shortName = "it"; + if (this.QueryBuilder.TableShortName.HasValue()) + { + shortName = this.QueryBuilder.TableShortName; + } + var exp = ExpressionBuilderHelper.CreateExpressionSelectField(typeof(T), item.PropertyName, properyType, shortName); + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression") + .First() + .MakeGenericMethod(properyItemType); + method.Invoke(this, new object[] { exp }); + } + } + return this; + } + public ISugarQueryable IncludesAllSecondLayer(Expression> expression, params string[] ignoreProperyNameList) + { + this.Includes(expression); + var type = typeof(TReturn1); + if (type.FullName.IsCollectionsList()) + { + type = type.GetGenericArguments()[0]; + } + var navs = this.Context.EntityMaintenance.GetEntityInfo(type).Columns.Where(it => it.Navigat != null).ToList(); + foreach (var item in navs) + { + if (ignoreProperyNameList?.Any(z => z.EqualCase(item.PropertyName)) == true) + { + //future + } + else + { + var properyType = item.PropertyInfo.PropertyType; + var properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + } + var exp = ExpressionBuilderHelper.CreateExpressionSelectField(type, item.PropertyName, properyType); + var method = this.GetType().GetMethods().Where(it => it.Name == "IncludesByExpression2") + .First() + .MakeGenericMethod(type, properyItemType); + method.Invoke(this, new object[] { expression, exp }); + } + } + return this; + } + public ISugarQueryable Includes(Expression>> include1) + { + var result = GetManyQueryable(include1); + if (result != null) + { + return result; + } + _Includes(this.Context, include1); + return this; + } + public ISugarQueryable Includes(Expression> include1) + { + var result = GetManyQueryable(include1); + if (result != null) + { + return result; + } + _Includes(this.Context, include1); + return this; + } + public ISugarQueryable Includes(Expression> include1, Expression>> include2) { _Includes(this.Context, include1, include2); return this; } + public ISugarQueryable Includes(Expression> include1, Expression> include2) { _Includes(this.Context, include1, include2); return this; } + public ISugarQueryable Includes(Expression>> include1, Expression>> include2) { _Includes(this.Context, include1, include2); return this; } + public ISugarQueryable Includes(Expression>> include1, Expression> include2) { _Includes(this.Context, include1, include2); return this; } + public NavISugarQueryable Includes(Expression>> include1, Expression>> include2, Expression>> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression>> include1, Expression> include2, Expression>> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression>> include1, Expression>> include2, Expression> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression> include1, Expression>> include2, Expression>> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression> include1, Expression> include2, Expression> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression> include1, Expression> include2, Expression>> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression> include1, Expression>> include2, Expression> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + public NavISugarQueryable Includes(Expression>> include1, Expression> include2, Expression> include3) { _Includes(this.Context, include1, include2, include3); return GetNavSugarQueryable(); } + + + } + + public partial class NavQueryableProvider : QueryableProvider, NavISugarQueryable + { + + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4) { _Includes(this.Context, include1, include2, include3, include4); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5) { _Includes(this.Context, include1, include2, include3, include4, include5); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6) { _Includes(this.Context, include1, include2, include3, include4, include5, include6); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + public NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7) { _Includes(this.Context, include1, include2, include3, include4, include5, include6, include7); return this; } + + } +} + diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Includes.txt b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Includes.txt new file mode 100644 index 000000000..4f50f7fa9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/Includes.txt @@ -0,0 +1,105 @@ + +List sourceNumbers = new List { 2, 4, 8, 16, 32, 64, 128 }; +var ram = new Random(); +foreach (var source in sourceNumbers) +{ + var index = sourceNumbers.IndexOf(source) + 1; + //Console.WriteLine("index=" + index); + + List> result = new List>(); + + string sb = ""; + List sb2 = new List(); + for (int i = 1; i <= source; i++) + { + + List test = new List(); + + List test2 = new List(); + for (int j = 1; j <= index; j++) + { + + test2.Add(new Test() { i = j, b = ram.Next(1, 222) % 2 == 0 }); + sb += $"[{test2.Last().b}:{test2.Last().i}]"; + //sb2 += $"[{test2.Last().b}:{test2.Last().i}]"; + if (j == index) + { + if (sb2.Count > 0 && sb2.Contains(sb)) + { + j = 0; + sb = ""; + test2 = new List(); + } + else + { + test.AddRange(test2.Select(x => new Test { b = x.b, i = x.i })); + sb2.Add(sb); + sb = ""; + } + } + + } + + test = test.OrderBy(it => it.i).ToList(); + result.Add(test); + + } + foreach (var test in result) + { + List res = new List(); + List res2 = new List(); + List res3 = new List(); + foreach (var item in test) + { + res3.Add($"include{ item.i}"); + if (item.i == 1) + { + if (item.b == false) + { + res.Add($"Expression>> include{item.i}"); + } + else + { + res.Add($"Expression> include{item.i}"); + } + + } + else + { + if (item.b == false) + { + res.Add($"Expression>> include{item.i}"); + } + else + { + res.Add($"Expression> include{item.i}"); + } + } + res2.Add("TReturn" + (item.i)); + } + + Console.WriteLine($"public ISugarQueryable Includes<{string.Join(",", res2)}>({string.Join(",", res)}){{ _Includes(this.Context,{string.Join(",", res3)}); return this; }}"); + } + //Console.WriteLine("--"); +} + +Console.ReadKey(); + +public class Test +{ + public bool b { get; set; } + public int i { get; set; } +} + + +//1:1 true + +//2: +// 1 true , 2 true +// 1 false , 2 true + +//3: +// 1 true , 2 true 3 true +// 1 true , 2 false 3 true +// 1 false , 2 false 3 true +// 1 false , 2 true 3 true diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/IncludesHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/IncludesHelper.cs new file mode 100644 index 000000000..fe651156f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/IncludesHelper.cs @@ -0,0 +1,293 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.Expressions = expressions; + navigat.Context = this.Context; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Expressions = expressions; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Expressions = expressions; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR4 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.SelectR4 = SelectR4; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR4 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR5 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.SelectR4 = SelectR4; + navigat.SelectR5 = SelectR5; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + public NavISugarQueryable AsNavQueryable() + { + return GetNavSugarQueryable(); + } + private NavQueryableProvider GetNavSugarQueryable() + { + var result = new NavQueryableProvider(); + result.Context = this.Context; + var clone = this.Clone(); + result.SqlBuilder = clone.SqlBuilder; + result.QueryBuilder = clone.QueryBuilder; + return result; + } + private ISugarQueryable GetManyQueryable(Expression> include1) + { + ISugarQueryable result = null; + var isManyMembers = IsMembers(include1); + if (isManyMembers) + { + var array = ExpressionTool.ExtractMemberNames(include1); + if (array.Count > 1) + { + + if (array.Count == 2) + { + result = this.IncludesByNameString(array[0], array[1]); + } + else if (array.Count == 3) + { + result = this.IncludesByNameString(array[0], array[1], array[2]); + } + else if (array.Count == 4) + { + result = this.IncludesByNameString(array[0], array[1], array[2], array[3]); + } + else if (array.Count == 5) + { + result = this.IncludesByNameString(array[0], array[1], array[2], array[3], array[4]); + } + else if (array.Count == 6) + { + throw new Exception("Multiple levels of expression exceeded the upper limit"); + } + } + } + return result; + } + private static bool IsMembers(Expression> include1) + { + var isManyMembers = false; + var x = ((include1 as LambdaExpression).Body as MemberExpression)?.Expression; + if (x is MemberExpression) + { + var exp = (x as MemberExpression)?.Expression; + if (exp != null) + { + isManyMembers = true; + } + } + return isManyMembers; + } + + } + public partial class NavQueryableProvider : QueryableProvider, NavISugarQueryable + { + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.Expressions = expressions; + navigat.Context = this.Context; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR4 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.SelectR4 = SelectR4; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR4 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR5 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.SelectR4 = SelectR4; + navigat.SelectR5 = SelectR5; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR4 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR5 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR6 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.SelectR4 = SelectR4; + navigat.SelectR5 = SelectR5; + navigat.SelectR6 = SelectR6; + navigat.Expressions = expressions; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + navigat.QueryBuilder = this.QueryBuilder; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + private void _Includes(SqlSugarProvider context, params Expression[] expressions) + { + Func, List> SelectR1 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR2 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR3 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR4 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR5 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR6 = it => it.Select().ToList().Select(x => x as object).ToList(); + Func, List> SelectR7 = it => it.Select().ToList().Select(x => x as object).ToList(); + var navigat = new NavigatManager(); + navigat.SelectR1 = SelectR1; + navigat.SelectR2 = SelectR2; + navigat.SelectR3 = SelectR3; + navigat.SelectR4 = SelectR4; + navigat.SelectR5 = SelectR5; + navigat.SelectR6 = SelectR6; + navigat.SelectR7 = SelectR7; + navigat.Expressions = expressions; + navigat.QueryBuilder = this.QueryBuilder; + navigat.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + navigat.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + navigat.Context = this.Context; + if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List(); + this.QueryBuilder.Includes.Add(navigat); + } + + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/MappingFieldsHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/MappingFieldsHelper.cs new file mode 100644 index 000000000..2447bebcb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/MappingFieldsHelper.cs @@ -0,0 +1,216 @@ +using System.Collections; +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class MappingFieldsHelper + { + public SqlSugarProvider Context { get; set; } + public EntityInfo NavEntity { get; set; } + public EntityInfo RootEntity { get; set; } + + public MappingFieldsInfo GetMappings(Expression thisFiled, Expression mappingFiled) + { + MappingFieldsInfo mappingFields = new MappingFieldsInfo(); + var pkName = ""; + if ((mappingFiled as LambdaExpression).Body is UnaryExpression) + { + pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + return mappingFields; + } + + public List GetMppingSql(List list, List mappingFieldsExpressions) + { + List conditionalModels = new List(); + foreach (var model in list) + { + var clist = new List>(); + var i = 0; + foreach (var item in mappingFieldsExpressions) + { + InitMappingFieldsExpression(item); + clist.Add(new KeyValuePair(i == 0 ? WhereType.Or : WhereType.And, new ConditionalModel() + { + FieldName = item.LeftEntityColumn.DbColumnName, + ConditionalType = ConditionalType.Equal, + FieldValue = item.RightEntityColumn.PropertyInfo.GetValue(model).ObjToString(), + CSharpTypeName = UtilMethods.GetUnderType(item.RightEntityColumn.PropertyInfo.PropertyType).Name + })); + i++; + } + conditionalModels.Add(new ConditionalCollections() + { + ConditionalList = clist + }); + } + return conditionalModels; + } + + public void SetChildList(EntityColumnInfo navColumnInfo, object item, List list, List mappingFieldsExpressions) + { + if (item != null) + { + //var expable =Expressionable.Create(); + List setList = GetSetList(item, list, mappingFieldsExpressions); + //navColumnInfo.PropertyInfo.SetValue(); + var instance = Activator.CreateInstance(navColumnInfo.PropertyInfo.PropertyType, true); + var ilist = instance as IList; + foreach (var value in setList) + { + ilist.Add(value); + } + navColumnInfo.PropertyInfo.SetValue(item, ilist); + } + } + + public void SetChildItem(EntityColumnInfo navColumnInfo, object item, List list, List mappingFieldsExpressions) + { + if (item != null) + { + //var expable =Expressionable.Create(); + List setList = GetSetList(item, list, mappingFieldsExpressions); + //navColumnInfo.PropertyInfo.SetValue(); + var instance = Activator.CreateInstance(navColumnInfo.PropertyInfo.PropertyType, true); + var ilist = instance as IList; + foreach (var value in setList) + { + navColumnInfo.PropertyInfo.SetValue(item, value); + } + + } + } + public List GetSetList(object item, List list, List mappingFieldsExpressions) + { + foreach (var field in mappingFieldsExpressions) + { + InitMappingFieldsExpression(field); + } + var setList = new List(); + var count = mappingFieldsExpressions.Count; + if (count == 1) + { + setList = list.Where(it => GetWhereByIndex(item, mappingFieldsExpressions, it, 0)).ToList(); + } + else if (count == 2) + { + setList = list.Where(it => + GetWhereByIndex(item, mappingFieldsExpressions, it, 0) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 1) + ).ToList(); + } + else if (count == 3) + { + setList = list.Where(it => + GetWhereByIndex(item, mappingFieldsExpressions, it, 0) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 1) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 2) + ).ToList(); + } + else if (count == 4) + { + setList = list.Where(it => + GetWhereByIndex(item, mappingFieldsExpressions, it, 0) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 1) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 2) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 3) + ).ToList(); + } + else if (count == 5) + { + setList = list.Where(it => + GetWhereByIndex(item, mappingFieldsExpressions, it, 0) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 1) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 2) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 3) && + GetWhereByIndex(item, mappingFieldsExpressions, it, 4) + ).ToList(); + } + else + { + Check.ExceptionEasy("MappingField max value is 5", "MappingField最大数量不能超过5"); + } + + return setList; + } + + private static bool GetWhereByIndex(object item, List mappingFieldsExpressions, object it, int index) + { + var left = mappingFieldsExpressions[index].LeftEntityColumn.PropertyInfo.GetValue(it).ObjToString(); + var right = mappingFieldsExpressions[index].RightEntityColumn.PropertyInfo.GetValue(item).ObjToString(); ; + return left == right; + } + + private void InitMappingFieldsExpression(MappingFieldsExpression item) + { + var leftName = item.LeftName; + var rightName = item.RightName; + if (item.LeftEntityColumn == null) + { + item.LeftEntityColumn = this.NavEntity.Columns.FirstOrDefault(it => it.PropertyName == leftName); + } + if (item.RightEntityColumn == null && this.Context != null) + { + if (item.RightColumnExpression is LambdaExpression) + { + var body = (item.RightColumnExpression as LambdaExpression).Body; + if (body is UnaryExpression) + { + body = ((UnaryExpression)body).Operand; + } + if (body is MemberExpression) + { + var exp = (body as MemberExpression).Expression; + if (exp.NodeType == ExpressionType.Parameter) + { + item.RightEntityColumn = this.Context.EntityMaintenance.GetEntityInfo(exp.Type).Columns.FirstOrDefault(it => it.PropertyName == rightName); + } + } + } + if (item.RightEntityColumn == null) + item.RightEntityColumn = this.RootEntity.Columns.FirstOrDefault(it => it.PropertyName == rightName); + } + } + + } + public class MappingFieldsInfo + { + public DbColumnInfo LeftColumn { get; set; } + public DbColumnInfo RightColumn { get; set; } + } + public class MappingFieldsExpression + { + public Expression LeftColumnExpression { get; set; } + public Expression RightColumnExpression { get; set; } + public EntityColumnInfo LeftEntityColumn { get; set; } + public EntityColumnInfo RightEntityColumn { get; set; } + private string _LeftName; + public string LeftName + { + get + { + if (_LeftName == null) + { + _LeftName = ExpressionTool.GetMemberName(this.LeftColumnExpression); + } + return _LeftName; + } + } + private string _RightName; + public string RightName + { + get + { + if (_RightName == null) + { + _RightName = ExpressionTool.GetMemberName(this.RightColumnExpression); + } + return _RightName; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/NavSelectHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/NavSelectHelper.cs new file mode 100644 index 000000000..9ecabf9a1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/NavSelectHelper.cs @@ -0,0 +1,352 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal static class NavSelectHelper + { + internal static List GetList(Expression> expression, QueryableProvider queryableProvider) + { + + List result = new List(); + var isSqlFunc = IsSqlFunc(expression, queryableProvider); + var isClass = IsClass(expression, queryableProvider); + if (isGroup(expression, queryableProvider)) + { + var sqlfuncQueryable = queryableProvider.Clone(); + sqlfuncQueryable.QueryBuilder.Includes = null; + result = sqlfuncQueryable + .Select(expression) + .ToList(); + var includeQueryable = queryableProvider.Clone(); + includeQueryable.Select(GetGroupSelect(typeof(T), queryableProvider.Context, queryableProvider.QueryBuilder)); + includeQueryable.QueryBuilder.NoCheckInclude = true; + var mappingColumn = GetMappingColumn(expression); + MegerList(result, includeQueryable.ToList(), sqlfuncQueryable.Context, mappingColumn); + } + else if (isSqlFunc) + { + result = SqlFunc(expression, queryableProvider); + } + else if (typeof(TResult).IsAnonymousType() && isClass == false) + { + result = SqlFunc(expression, queryableProvider); + } + else if (typeof(TResult).IsAnonymousType() && isClass == true) + { + result = Action(expression, queryableProvider); + } + else if (expression.ToString().Contains("FirstOrDefault()")) + { + result = Action(expression, queryableProvider); + } + else + { + try + { + result = SqlFunc(expression, queryableProvider); + } + catch (Exception ex) + { + try + { + Console.WriteLine("Select DTO error . Warning:" + ex.Message); + result = Action(expression, queryableProvider); + } + catch + { + + throw; + } + } + } + return result; + } + + private static List Action(Expression> expression, QueryableProvider queryableProvider) + { + List result; + var entity = queryableProvider.Context.EntityMaintenance.GetEntityInfo(); + var list = queryableProvider.Clone().ToList(); + var dt = queryableProvider.Context.Utilities.ListToDataTable(list); + foreach (System.Data.DataRow item in dt.Rows) + { + foreach (System.Data.DataColumn columnInfo in dt.Columns) + { + if (columnInfo.DataType.IsClass()) + { + if (item[columnInfo.ColumnName] == null || item[columnInfo.ColumnName] == DBNull.Value) + { + item[columnInfo.ColumnName] = Activator.CreateInstance(columnInfo.DataType, true); + } + } + } + } + list = queryableProvider.Context.Utilities.DataTableToList(dt); + result = list.Select(expression.Compile()).ToList(); + return result; + } + + private static List SqlFunc(Expression> expression, QueryableProvider queryableProvider) + { + var mappingColumn = GetMappingColumn(expression); + if (mappingColumn.Any(it => it.IsError)) + { + return Action(expression, queryableProvider); + } + List result; + var sqlfuncQueryable = queryableProvider.Clone(); + var dtoEntity = sqlfuncQueryable.Context.EntityMaintenance.GetEntityInfo().Columns; + var tableEntity = sqlfuncQueryable.Context.EntityMaintenance.GetEntityInfo().Columns; + var ignoreColumns = GetIgnoreColumns(dtoEntity, tableEntity); + sqlfuncQueryable.QueryBuilder.Includes = null; + result = sqlfuncQueryable + .IgnoreColumns(ignoreColumns) + .Select(expression) + .ToList(); + var selector = GetDefaultSelector(queryableProvider.Context.EntityMaintenance.GetEntityInfo(), queryableProvider.QueryBuilder); + var queryable = queryableProvider.Select(selector).Clone(); + queryable.QueryBuilder.NoCheckInclude = true; + var includeList = queryable.ToList(); + MegerList(result, includeList, sqlfuncQueryable.Context, mappingColumn); + return result; + } + + private static string[] GetIgnoreColumns(List dtoEntity, List tableEntity) + { + var column = (from dto in dtoEntity + join tab in tableEntity on dto.PropertyInfo.PropertyType equals tab.PropertyInfo.PropertyType + where tab.Navigat != null + select tab.PropertyName).Distinct().ToArray(); + return column; + } + + internal static async Task> GetListAsync(Expression> expression, QueryableProvider queryableProvider) + { + return await Task.Run(() => { return GetList(expression, queryableProvider); }).ConfigureAwait(false); + } + + private static string GetGroupSelect(Type type, SqlSugarProvider context, QueryBuilder queryBuilder) + { + var entity = context.EntityMaintenance.GetEntityInfo(type); + List selector = new List(); + List columns = GetListNavColumns(entity); + foreach (var item in columns) + { + if (queryBuilder.TableShortName.HasValue()) + { + selector.Add($" min({queryBuilder.TableShortName}.{item.DbColumnName}) as {item.DbColumnName}"); + } + else + { + selector.Add($" min({item.DbColumnName}) as {item.DbColumnName}"); + } + } + return string.Join(",", selector); + } + + private static string GetDefaultSelector(EntityInfo entityInfo, QueryBuilder queryBuilder) + { + List columns = GetListNavColumns(entityInfo); + var selector = new List(); + if (columns.Count == 0) return null; + foreach (var item in columns) + { + if (queryBuilder.TableShortName.HasValue()) + { + selector.Add($" {queryBuilder.TableShortName}.{item.DbColumnName} as {item.DbColumnName}"); + } + else + { + selector.Add($" {item.DbColumnName} as {item.DbColumnName}"); + } + } + return string.Join(",", selector); + } + + private static List GetListNavColumns(EntityInfo entityInfo) + { + var list = entityInfo.Columns.Where(it => it.Navigat != null).Select( + it => it.Navigat.Name + ).ToArray(); + var list2 = entityInfo.Columns.Where(it => it.Navigat?.Name2 != null).Select( + it => it.Navigat.Name2 + ).ToArray(); + var columns = entityInfo.Columns.Where(it => it.IsPrimarykey || + list.Contains(it.PropertyName) || + list2.Contains(it.PropertyName) + ).ToList(); + return columns; + } + + private static void MegerList(List result, List includeList, SqlSugarProvider context, List navMappingColumns) + { + if (result.Count != includeList.Count) return; + var columns = context.EntityMaintenance.GetEntityInfo().Columns; + var resColumns = context.EntityMaintenance.GetEntityInfo().Columns; + var i = 0; + foreach (var item in includeList) + { + foreach (var column in columns) + { + if (column.Navigat != null) + { + var value = column.PropertyInfo.GetValue(item); + var resColumn = resColumns + .FirstOrDefault(z => + z.PropertyName.Equals(column.PropertyName) && + z.PropertyInfo.PropertyType == column.PropertyInfo.PropertyType + ); + if (resColumn == null && navMappingColumns.Any(z => z.Value == column.PropertyName)) + { + var mappingColumn = navMappingColumns.First(z => z.Value == column.PropertyName); + resColumn = resColumns + .FirstOrDefault(z => + z.PropertyName.Equals(mappingColumn.Key) && + z.PropertyInfo.PropertyType == column.PropertyInfo.PropertyType + ); + } + if (resColumn != null) + { + var resItem = result[i]; + resColumn.PropertyInfo.SetValue(resItem, value); + } + } + } + i++; + } + } + private static bool IsClass(Expression> expression, QueryableProvider queryableProvider) + { + var body = ExpressionTool.GetLambdaExpressionBody(expression); + if (body is NewExpression) + { + var newExp = ((NewExpression)body); + foreach (var item in newExp.Arguments) + { + if (item is MemberExpression) + { + var member = (MemberExpression)item; + if (member.Type.IsClass()) + { + return true; + } + } + } + } + return false; + } + + private static bool IsSqlFunc(Expression> expression, QueryableProvider queryableProvider) + { + var body = ExpressionTool.GetLambdaExpressionBody(expression); + if (body is NewExpression) + { + var newExp = ((NewExpression)body); + foreach (var item in newExp.Arguments) + { + if (item is MethodCallExpression) + { + var method = ((MethodCallExpression)item).Method; + if (method.DeclaringType?.Name == "SqlFunc") + { + return true; + } + } + } + } + if (body is MemberInitExpression) + { + var newExp = ((MemberInitExpression)body); + foreach (var item in newExp.Bindings) + { + MemberAssignment memberAssignment = (MemberAssignment)item; + if (memberAssignment.Expression is MethodCallExpression) + { + var method = ((MethodCallExpression)memberAssignment.Expression).Method; + if (method.DeclaringType?.Name == "SqlFunc") + { + return true; + } + } + } + } + return false; + } + private static List GetMappingColumn(Expression expression) + { + var body = ExpressionTool.GetLambdaExpressionBody(expression); + var parameterName = (expression as LambdaExpression).Parameters.FirstOrDefault().Name; + List result = new List(); + if (body is NewExpression) + { + var index = 0; + var arg = ((NewExpression)body).Arguments; + var members = ((NewExpression)body).Members; + foreach (var item in arg) + { + var name = members[index].Name; + if (item is MethodCallExpression) + { + AddCallError(result, item, parameterName); + } + index++; + } + } + else if (body is MemberInitExpression) + { + foreach (var item in ((MemberInitExpression)body).Bindings) + { + MemberAssignment memberAssignment = (MemberAssignment)item; + var key = memberAssignment.Member.Name; + var value = memberAssignment.Expression; + if (memberAssignment.Expression is MemberExpression) + { + result.Add(new NavMappingColumn() { Key = key, Value = ExpressionTool.GetMemberName(memberAssignment.Expression) }); + } + else if (memberAssignment.Expression is MethodCallExpression) + { + AddCallError(result, memberAssignment.Expression, parameterName); + } + } + } + return result; + } + + private static void AddCallError(List result, Expression item, string parameterName) + { + var method = (item as MethodCallExpression); + if (method.Method.Name == "ToList" && method.Arguments.Count > 0 && method.Arguments[0] is MethodCallExpression) + { + method = (MethodCallExpression)method.Arguments[0]; + } + if (method.Method.Name == "Select") + { + if (!item.ToString().Contains("Subqueryable")) + { + result.Add(new NavMappingColumn() { IsError = true }); + } + } + else if (method.Method.Name == "Join") + { + + if (item.ToString().Contains($" {parameterName}.")) + { + result.Add(new NavMappingColumn() { IsError = true }); + } + } + } + + private static bool isGroup(Expression> expression, QueryableProvider queryableProvider) + { + var isGroup = queryableProvider.QueryBuilder.GetGroupByString.HasValue(); + return isGroup; + } + + internal class NavMappingColumn + { + public string Key { get; set; } + public string Value { get; set; } + public bool IsError { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/NavigatManager.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/NavigatManager.cs new file mode 100644 index 000000000..645110163 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/NavigatManager.cs @@ -0,0 +1,1093 @@ +using System.Collections; +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public class NavigatManager + { + public SqlSugarProvider Context { get; set; } + public bool IsCrossQueryWithAttr { get; set; } + public Dictionary CrossQueryItems { get; set; } + public Func, List> SelectR1 { get; set; } + public Func, List> SelectR2 { get; set; } + public Func, List> SelectR3 { get; set; } + public Func, List> SelectR4 { get; set; } + public Func, List> SelectR5 { get; set; } + public Func, List> SelectR6 { get; set; } + public Func, List> SelectR7 { get; set; } + public Func, List> SelectR8 { get; set; } + public Expression[] Expressions { get; set; } + public List RootList { get; set; } + public QueryBuilder QueryBuilder { get; set; } + + //public QueryableProvider Queryable { get; set; } + + private List _preExpressionList = new List(); + private List _preList = new List(); + private List _ListCallFunc; + //private Expression[] _expressions; + //private List _list; + //private EntityInfo _entityInfo; + public void Execute() + { + var i = 1; + foreach (var item in Expressions) + { + ExecuteByLay(i, item); + i++; + } + } + + private void ExecuteByLay(int i, Expression item) + { + _ListCallFunc = GetWhereExpression(ref item); + if (i == 1) + { + ExecuteByLay(item, RootList.Select(it => it as object).ToList(), SelectR1); + } + else if (i == 2) + { + var currentList = RootList; + if (RootList == null || currentList.Count == 0) return; + var memberExpression = ((_preExpressionList.Last() as LambdaExpression).Body as MemberExpression); + var navObjectName = memberExpression.Member.Name; + var navType = currentList[0].GetType().GetProperty(navObjectName).PropertyType.Name; + var isList = navType.StartsWith("List`"); + List list = new List(); + if (isList) + { + list = currentList.SelectMany(it => (it.GetType().GetProperty(navObjectName).GetValue(it) as IList)?.Cast() ?? new List { }).ToList(); + + } + else + { + list = currentList.Select(it => (it.GetType().GetProperty(navObjectName).GetValue(it))).ToList(); + } + ExecuteByLay(item, list, SelectR2); + _preList = list; + } + else if (i == 3) + { + var currentList = _preList.Where(it => it != null).ToList(); + if (RootList == null || currentList.Count == 0) return; + List list = ExecuteByLay(currentList); + ExecuteByLay(item, list, SelectR3); + _preList = list.ToList(); + } + else if (i == 4) + { + var currentList = _preList.Where(it => it != null).ToList(); + if (RootList == null || currentList.Count == 0) return; + List list = ExecuteByLay(currentList); + ExecuteByLay(item, list, SelectR4); + _preList = list.ToList(); + } + else if (i == 5) + { + var currentList = _preList.Where(it => it != null).ToList(); + if (RootList == null || currentList.Count == 0) return; + List list = ExecuteByLay(currentList); + ExecuteByLay(item, list, SelectR5); + _preList = list.ToList(); + } + else if (i == 6) + { + var currentList = _preList.Where(it => it != null).ToList(); + if (RootList == null || currentList.Count == 0) return; + List list = ExecuteByLay(currentList); + ExecuteByLay(item, list, SelectR6); + _preList = list.ToList(); + } + else if (i == 7) + { + var currentList = _preList.Where(it => it != null).ToList(); + if (RootList == null || currentList.Count == 0) return; + List list = ExecuteByLay(currentList); + ExecuteByLay(item, list, SelectR7); + _preList = list.ToList(); + } + _preExpressionList.Add(item); + _ListCallFunc = new List(); + } + + private List ExecuteByLay(List currentList) + { + var memberExpression = ((_preExpressionList.Last() as LambdaExpression).Body as MemberExpression); + var navObjectName = memberExpression.Member.Name; + var navType = currentList[0].GetType().GetProperty(navObjectName).PropertyType.Name; + var isList = navType.StartsWith("List`"); + List list = new List(); + if (isList) + { + list = currentList.Where(it => it.GetType().GetProperty(navObjectName).GetValue(it) != null).SelectMany(it => (it.GetType().GetProperty(navObjectName).GetValue(it) as IList).Cast()).ToList(); + + } + else + { + list = currentList.Where(it => it.GetType().GetProperty(navObjectName).GetValue(it) != null).Select(it => (it.GetType().GetProperty(navObjectName).GetValue(it))).ToList(); + } + + return list; + } + + private void ExecuteByLay(Expression expression, List list, Func, List> selector) + { + if (list == null || list.Count == 0) return; + list = list.Where(it => it != null).ToList(); + var memberExpression = ((expression as LambdaExpression).Body as MemberExpression); + + var listItemType = list.Where(it => it != null).FirstOrDefault()?.GetType(); + if (listItemType == null) + { + return; + } + if (listItemType.Name.StartsWith("List`")) + { + listItemType = listItemType.GetGenericArguments()[0]; + } + //if (listItemType == null) return; + + var listItemEntity = this.Context.EntityMaintenance.GetEntityInfo(listItemType); + var listPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault(); + var navObjectName = memberExpression.Member.Name; + var navObjectNamePropety = listItemType.GetProperty(navObjectName); + var navObjectNameColumnInfo = listItemEntity.Columns.First(it => it.PropertyName == navObjectName); + Check.ExceptionEasy(navObjectNameColumnInfo.Navigat == null, $"{navObjectName} not [Navigat(..)] ", $"{navObjectName} 没有导航特性 [Navigat(..)] "); + + + + if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.OneToOne) + { + this.Context.Utilities.PageEach(list, 5000, pageList => + { + OneToOne(pageList, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo); + }); + } + else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.OneToMany) + { + this.Context.Utilities.PageEach(list, 5000, pageList => + { + OneToMany(pageList, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo); + }); + } + else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.ManyToOne) + { + this.Context.Utilities.PageEach(list, 5000, pageList => + { + OneToOne(pageList, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo); + }); + } + else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.Dynamic) + { + this.Context.Utilities.PageEach(list, 100, pageList => + { + Dynamic(pageList, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo, expression); + }); + } + else + { + this.Context.Utilities.PageEach(list, 100, pageList => + { + ManyToMany(pageList, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo); + }); + } + } + + private List GetWhereExpression(ref Expression expression) + { + List expressions = new List(); + var isCall = (expression as LambdaExpression).Body is MethodCallExpression; + if (isCall) + { + var newexp = (expression as LambdaExpression).Body; + while (newexp is MethodCallExpression) + { + expressions.Add(newexp); + newexp = (newexp as MethodCallExpression).Arguments[0]; + } + expression = LambdaExpression.Lambda(newexp); + } + return expressions; + } + + private void ManyToMany(List list, Func, List> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo) + { + var bEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0]; + var bEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(bEntity); + var bPkColumn = bEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + if (navObjectNameColumnInfo.Navigat.BClassId.HasValue()) + { + bPkColumn = bEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.BClassId); + } + Check.ExceptionEasy(bPkColumn == null, $"{bEntityInfo.EntityName} need primary key", $"{bEntityInfo.EntityName} 实体需要配置主键"); + var bDb = this.Context; + bDb = GetCrossDatabase(bDb, bEntity); + bDb.InitMappingInfo(bEntity); + var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault(); + if (navObjectNameColumnInfo.Navigat.AClassId.HasValue()) + { + listItemPkColumn = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.AClassId); + } + Check.ExceptionEasy(listItemPkColumn == null, $"{listItemEntity.EntityName} need primary key", $"{listItemEntity.EntityName} 实体需要配置主键"); + var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList(); + var mappingEntity = this.Context.EntityMaintenance.GetEntityInfo(navObjectNameColumnInfo.Navigat.MappingType); + var aColumn = mappingEntity.Columns.First(it => it.PropertyName == navObjectNameColumnInfo.Navigat.MappingAId); + var bColumn = mappingEntity.Columns.First(it => it.PropertyName == navObjectNameColumnInfo.Navigat.MappingBId); + List conditionalModels = new List(); + conditionalModels.Add((new ConditionalModel() + { + ConditionalType = ConditionalType.In, + FieldName = aColumn.DbColumnName, + FieldValue = String.Join(",", ids), + CSharpTypeName = aColumn.PropertyInfo.PropertyType.Name + })); + var abDb = this.Context; + abDb = GetCrossDatabase(abDb, mappingEntity.Type); + var queryable = abDb.Queryable(); + var abids = queryable.AS(mappingEntity.DbTableName).WhereIF(navObjectNameColumnInfo?.Navigat?.WhereSql != null, navObjectNameColumnInfo?.Navigat?.WhereSql).ClearFilter(QueryBuilder.RemoveFilters).Filter(this.QueryBuilder?.IsDisabledGobalFilter == true ? null : mappingEntity.Type).Where(conditionalModels).Select($"{queryable.SqlBuilder.GetTranslationColumnName(aColumn.DbColumnName)} as aid,{queryable.SqlBuilder.GetTranslationColumnName(bColumn.DbColumnName)} as bid").ToList(); + + List conditionalModels2 = new List(); + conditionalModels2.Add((new ConditionalModel() + { + ConditionalType = ConditionalType.In, + FieldName = bPkColumn.DbColumnName, + FieldValue = String.Join(",", abids.Select(it => it.Bid).ToArray()), + CSharpTypeName = bColumn.PropertyInfo.PropertyType.Name + })); + var sql = GetWhereSql(GetCrossDatabase(abDb, bEntity)); + if (sql.SelectString == null) + { + var columns = bEntityInfo.Columns.Where(it => !it.IsIgnore) + .Select(it => GetOneToManySelectByColumnInfo(it, abDb)).ToList(); + sql.SelectString = String.Join(",", columns); + } + else + { + var bid = InstanceFactory.GetQueryBuilderWithContext(abDb).Builder.GetTranslationColumnName(bPkColumn.DbColumnName); + if (!sql.SelectString.Contains(bid?.ToLower(), StringComparison.CurrentCultureIgnoreCase) && !sql.SelectString.Contains('*')) + { + sql.SelectString += ("," + bid + " AS " + bid); + } + } + var bList = selector(bDb.Queryable().AS(bEntityInfo.DbTableName).ClearFilter(QueryBuilder.RemoveFilters).Filter(this.QueryBuilder?.IsDisabledGobalFilter == true ? null : bEntityInfo.Type).AddParameters(sql.Parameters).Where(conditionalModels2).WhereIF(sql.WhereString.HasValue(), sql.WhereString).Select(sql.SelectString).OrderByIF(sql.OrderByString.HasValue(), sql.OrderByString)); + if (bList.HasValue()) + { + foreach (var listItem in list) + { + if (navObjectNamePropety.GetValue(listItem) == null) + { + var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true); + var ilist = instance as IList; + foreach (var bInfo in bList) + { + var pk = listItemPkColumn.PropertyInfo.GetValue(listItem).ObjToString(); + var bid = bPkColumn.PropertyInfo.GetValue(bInfo).ObjToString(); + if (abids.Any(x => x.Aid == pk && x.Bid == bid)) + { + ilist.Add(bInfo); + } + } + if (sql.MappingExpressions.HasValue()) + { + MappingFieldsHelper helper = new MappingFieldsHelper(); + helper.Context = this.Context; + helper.NavEntity = bEntityInfo; + helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo(); + helper.SetChildList(navObjectNameColumnInfo, listItem, ilist.Cast().ToList(), sql.MappingExpressions); + } + else + { + if (sql.Skip != null || sql.Take != null) + { + var instanceCast = (instance as IList); + var newinstance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true) as IList; + SkipTakeIList(sql, instanceCast, newinstance); + navObjectNamePropety.SetValue(listItem, newinstance); + } + else + { + navObjectNamePropety.SetValue(listItem, instance); + } + } + } + } + } + else + { + foreach (var listItem in list) + { + if (navObjectNamePropety.GetValue(listItem) == null) + { + var newinstance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true) as IList; + navObjectNamePropety.SetValue(listItem, newinstance); + } + } + } + } + + private static void SkipTakeIList(SqlInfo sql, IList instanceCast, IList newinstance) + { + var intArray = Enumerable.Range(0, instanceCast.Count); + if (sql.Skip != null) + { + intArray = intArray + .Skip(sql.Skip.Value); + } + if (sql.Take != null) + { + intArray = intArray + .Take(sql.Take.Value); + } + foreach (var i in intArray) + { + newinstance.Add(instanceCast[i]); + } + } + + private void OneToOne(List list, Func, List> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo) + { + var navColumn = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name); + Check.ExceptionEasy(navColumn == null, "OneToOne navigation configuration error", $"OneToOne导航配置错误: 实体{listItemEntity.EntityName} 不存在{navObjectNameColumnInfo.Navigat.Name}"); + var navType = navObjectNamePropety.PropertyType; + var db = this.Context; + db = GetCrossDatabase(db, navType); + var navEntityInfo = db.EntityMaintenance.GetEntityInfo(navType); + db.InitMappingInfo(navEntityInfo.Type); + var navPkColumn = navEntityInfo.Columns.Where(it => it.IsPrimarykey).FirstOrDefault(); + var navPkCount = navEntityInfo.Columns.Where(it => it.IsPrimarykey).Count(); + Check.ExceptionEasy(navPkColumn == null && navObjectNameColumnInfo.Navigat.Name2 == null, navEntityInfo.EntityName + "need primarykey", navEntityInfo.EntityName + " 需要主键"); + if (navObjectNameColumnInfo.Navigat.Name2.HasValue()) + { + navPkColumn = navEntityInfo.Columns.Where(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name2).FirstOrDefault(); + } + if (navPkColumn == null && navType.FullName.IsCollectionsList()) + { + Check.ExceptionEasy($"{navObjectNamePropety.Name} type error ", $"一对一不能是List对象 {navObjectNamePropety.Name} "); + } + List ids = null; + var isOwnsOneProperty = IsOwnsOneProperty(listItemEntity, navObjectNameColumnInfo); + if (isOwnsOneProperty) + { + var data = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name); + ids = list.Select(it => + { + var ownsObj = data.ForOwnsOnePropertyInfo.GetValue(it); + return ownsObj.GetType().GetProperty(navObjectNameColumnInfo.Navigat.Name).GetValue(ownsObj); + }).Select(it => it == null ? "null" : it).Distinct().ToList(); + } + else + { + ids = list.Select(it => it.GetType().GetProperty(navObjectNameColumnInfo.Navigat.Name).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList(); + } + List conditionalModels = new List(); + if (IsEnumNumber(navColumn)) + { + ids = ids.Select(it => Convert.ToInt64(it)).Cast().ToList(); + } + if (navPkColumn?.UnderType?.Name == UtilConstants.StringType.Name) + { + ids = ids.Select(it => it?.ToString()?.Replace(",", "[comma]")).Cast().ToList(); + } + if (navPkColumn?.UnderType?.Name == UtilConstants.DateType.Name) + { + ids = ids.Select(it => it == null ? null : it.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff")).Cast().ToList(); + } + conditionalModels.Add((new ConditionalModel() + { + ConditionalType = ConditionalType.In, + FieldName = navPkColumn.DbColumnName, + FieldValue = String.Join(",", ids), + CSharpTypeName = navPkColumn?.UnderType?.Name + })); + if (OneToOneGlobalInstanceRegistry.IsAny()) + { + foreach (var item in list) + { + var firstObj = navObjectNamePropety.GetValue(item); + if (OneToOneGlobalInstanceRegistry.IsNavigationInitializerCreated(firstObj)) + { + navObjectNamePropety.SetValue(item, null); + } + } + } + if (list.Count != 0 && navObjectNamePropety.GetValue(list.First()) == null) + { + var sqlObj = GetWhereSql(db, navObjectNameColumnInfo.Navigat.Name); + if (sqlObj.SelectString == null) + { + var columns = navEntityInfo.Columns.Where(it => !it.IsIgnore) + .Select(it => GetOneToOneSelectByColumnInfo(it, db)).ToList(); + sqlObj.SelectString = String.Join(",", columns); + } + var navList = selector(db.Queryable().ClearFilter(QueryBuilder.RemoveFilters).Filter((navPkColumn.IsPrimarykey && navPkCount == 1) ? null : this.QueryBuilder?.IsDisabledGobalFilter == true ? null : navEntityInfo.Type).AS(GetDbTableName(navEntityInfo, sqlObj)) + .WhereIF(navObjectNameColumnInfo.Navigat.WhereSql.HasValue(), navObjectNameColumnInfo.Navigat.WhereSql) + .WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString) + .AddParameters(sqlObj.Parameters).Where(conditionalModels) + .Select(sqlObj.SelectString)); + + if (isOwnsOneProperty) + { + { + // 有 OwnsOne 的情况 + var data = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name); + + var groupQuery = (from l in list + let ownsObj = data.ForOwnsOnePropertyInfo.GetValue(l) + join n in navList + on ownsObj.GetType() + .GetProperty(navObjectNameColumnInfo.Navigat.Name) + .GetValue(ownsObj) + .ObjToString() + equals navPkColumn.PropertyInfo.GetValue(n).ObjToString() + select new + { + l, + n + }).ToList(); + + foreach (var item in groupQuery) + { + + // var setValue = navList.FirstOrDefault(x => navPkColumn.PropertyInfo.GetValue(x).ObjToString() == navColumn.PropertyInfo.GetValue(item).ObjToString()); + + if (navObjectNamePropety.GetValue(item.l) == null) + { + navObjectNamePropety.SetValue(item.l, item.n); + } + else + { + //The reserved + } + + } + } + } + else + { + var groupQuery = (from l in list + join n in navList + on navColumn.PropertyInfo.GetValue(l).ObjToString() + equals navPkColumn.PropertyInfo.GetValue(n).ObjToString() + select new + { + l, + n + }).ToList(); + foreach (var item in groupQuery) + { + + // var setValue = navList.FirstOrDefault(x => navPkColumn.PropertyInfo.GetValue(x).ObjToString() == navColumn.PropertyInfo.GetValue(item).ObjToString()); + + if (navObjectNamePropety.GetValue(item.l) == null) + { + navObjectNamePropety.SetValue(item.l, item.n); + } + else + { + //The reserved + } + + } + } + } + } + + private void OneToMany(List list, Func, List> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo) + { + Check.ExceptionEasy(navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments().Length == 0, navObjectNamePropety?.Name + "Navigation configuration error one to many should be List", navObjectNamePropety?.Name + "导航配置错误一对多应该是List"); + + var navEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0]; + var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navEntity); + var childDb = this.Context; + childDb = GetCrossDatabase(childDb, navEntityInfo.Type); + childDb.InitMappingInfo(navEntityInfo.Type); + var navColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name); + Check.ExceptionEasy(navColumn == null, $"{navEntityInfo.EntityName} not found {navObjectNameColumnInfo.Navigat.Name} ", $"实体 {navEntityInfo.EntityName} 未找到导航配置列 {navObjectNameColumnInfo.Navigat.Name} "); + //var navType = navObjectNamePropety.PropertyType; + var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault(); + Check.ExceptionEasy(listItemPkColumn == null && navObjectNameColumnInfo.Navigat.Name2 == null, listItemEntity.EntityName + " not primary key", listItemEntity.EntityName + "没有主键"); + if (navObjectNameColumnInfo.Navigat.Name2.HasValue()) + { + listItemPkColumn = listItemEntity.Columns.Where(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name2).FirstOrDefault(); + Check.ExceptionEasy(listItemPkColumn == null, $"{navObjectNameColumnInfo.PropertyName} Navigate is error ", $"{navObjectNameColumnInfo.PropertyName}导航配置错误,可能顺序反了。"); + } + var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList(); + List conditionalModels = new List(); + if (IsEnumNumber(navColumn)) + { + ids = ids.Select(it => Convert.ToInt64(it)).Cast().ToList(); + } + if (navColumn?.UnderType?.Name == UtilConstants.StringType.Name) + { + ids = ids.Select(it => it?.ToString()?.Replace(",", "[comma]")).Cast().ToList(); + } + conditionalModels.Add((new ConditionalModel() + { + ConditionalType = ConditionalType.In, + FieldName = navColumn.DbColumnName, + FieldValue = String.Join(",", ids), + CSharpTypeName = listItemPkColumn?.UnderType?.Name + })); + var sqlObj = GetWhereSql(childDb, navObjectNameColumnInfo.Navigat.Name); + + if (list.Count != 0 && navObjectNamePropety.GetValue(list.First()) == null) + { + if (sqlObj.SelectString == null) + { + var columns = navEntityInfo.Columns.Where(it => !it.IsIgnore) + .Select(it => GetOneToManySelectByColumnInfo(it, childDb)).ToList(); + sqlObj.SelectString = String.Join(",", columns); + } + var navList = selector(childDb.Queryable(sqlObj.TableShortName).AS(GetDbTableName(navEntityInfo, sqlObj)).ClearFilter(QueryBuilder.RemoveFilters).Filter(this.QueryBuilder?.IsDisabledGobalFilter == true ? null : navEntityInfo.Type).AddParameters(sqlObj.Parameters).Where(conditionalModels).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).WhereIF(navObjectNameColumnInfo?.Navigat?.WhereSql != null, navObjectNameColumnInfo?.Navigat?.WhereSql).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString)); + if (navList.HasValue()) + { + //var setValue = navList + // .Where(x => navColumn.PropertyInfo.GetValue(x).ObjToString() == listItemPkColumn.PropertyInfo.GetValue(item).ObjToString()).ToList(); + var groupQuery = (from l in list.Distinct() + join n in navList + on listItemPkColumn.PropertyInfo.GetValue(l).ObjToString() + equals navColumn.PropertyInfo.GetValue(n).ObjToString() + select new + { + l, + n + }).GroupBy(it => it.l).ToList(); + foreach (var item in groupQuery) + { + var itemSelectList = item.Select(it => it.n); + if (sqlObj.Skip != null) + { + itemSelectList = itemSelectList + .Skip(sqlObj.Skip.Value); + } + if (sqlObj.Take != null) + { + itemSelectList = itemSelectList + .Take(sqlObj.Take.Value); + } + if (sqlObj.MappingExpressions.HasValue()) + { + MappingFieldsHelper helper = new MappingFieldsHelper(); + helper.NavEntity = navEntityInfo; + helper.Context = this.Context; + helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo(); + helper.SetChildList(navObjectNameColumnInfo, item.Key, itemSelectList.ToList(), sqlObj.MappingExpressions); + } + else + { + + var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true); + var ilist = instance as IList; + foreach (var value in itemSelectList.ToList()) + { + ilist.Add(value); + } + navObjectNamePropety.SetValue(item.Key, instance); + } + } + foreach (var item in list) + { + if (navObjectNamePropety.GetValue(item) == null) + { + var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true); + navObjectNamePropety.SetValue(item, instance); + } + } + } + else + { + //No navigation data set new List() + foreach (var item in list) + { + var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true); + navObjectNamePropety.SetValue(item, instance); + } + } + } + } + + private void Dynamic(List list, Func, List> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo, Expression expression) + { + var args = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments(); + if (args.Length == 0) + { + DynamicOneToOne(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo, expression); + return; + } + var navEntity = args[0]; + + var childDb = this.Context; + childDb = GetCrossDatabase(childDb, navEntity); + + childDb.InitMappingInfo(navEntity); + var navEntityInfo = childDb.EntityMaintenance.GetEntityInfo(navEntity); + var sqlObj = GetWhereSql(childDb, navObjectNameColumnInfo.Navigat.Name); + if (IsJsonMapping(navObjectNameColumnInfo, sqlObj)) + { + CreateDynamicMappingExpression(sqlObj, navObjectNameColumnInfo.Navigat.Name, navEntityInfo, listItemEntity); + if (sqlObj.WhereString == null) + { + sqlObj.WhereString = navObjectNameColumnInfo?.Navigat?.Name2; + } + } + Check.ExceptionEasy(sqlObj.MappingExpressions.IsNullOrEmpty(), $"{expression} error,dynamic need MappingField ,Demo: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())", $"{expression} 解析出错,自定义映射需要 MappingField ,例子: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())"); + if (list.Count != 0 && navObjectNamePropety.GetValue(list.First()) == null) + { + MappingFieldsHelper helper = new MappingFieldsHelper(); + helper.Context = childDb; + helper.NavEntity = navEntityInfo; + helper.RootEntity = childDb.EntityMaintenance.GetEntityInfo(); + var whereSql = helper.GetMppingSql(list, sqlObj.MappingExpressions); + var navList = selector(childDb.Queryable().AS(GetDbTableName(navEntityInfo, sqlObj)).AddParameters(sqlObj.Parameters).Where(whereSql, true).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString)); + if (navList.HasValue()) + { + foreach (var item in list) + { + helper.SetChildList(navObjectNameColumnInfo, item, navList, sqlObj.MappingExpressions); + } + } + } + + } + + private void DynamicOneToOne(List list, Func, List> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo, Expression expression) + { + var navEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType; + var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navEntity); + var childDb = this.Context; + childDb = GetCrossDatabase(childDb, navEntity); + this.Context.InitMappingInfo(navEntity); + var sqlObj = GetWhereSql(childDb, navObjectNameColumnInfo.Navigat.Name); + if (IsJsonMapping(navObjectNameColumnInfo, sqlObj)) + { + CreateDynamicMappingExpression(sqlObj, navObjectNameColumnInfo.Navigat.Name, navEntityInfo, listItemEntity); + if (sqlObj.WhereString == null) + { + sqlObj.WhereString = navObjectNameColumnInfo?.Navigat?.Name2; + } + } + Check.ExceptionEasy(sqlObj.MappingExpressions.IsNullOrEmpty(), $"{expression} error,dynamic need MappingField ,Demo: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())", $"{expression}解析出错, 自定义映射需要 MappingField ,例子: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())"); + if (list.Count != 0 && navObjectNamePropety.GetValue(list.First()) == null) + { + MappingFieldsHelper helper = new MappingFieldsHelper(); + helper.Context = this.Context; + helper.NavEntity = navEntityInfo; + helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var whereSql = helper.GetMppingSql(list, sqlObj.MappingExpressions); + var navList = selector(childDb.Queryable().AS(GetDbTableName(navEntityInfo, sqlObj)).AddParameters(sqlObj.Parameters).Where(whereSql, true).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString)); + if (navList.HasValue()) + { + foreach (var item in list) + { + helper.SetChildItem(navObjectNameColumnInfo, item, navList, sqlObj.MappingExpressions); + } + } + } + } + + private SqlInfo GetWhereSql(SqlSugarProvider db, string properyName = null) + { + if (_ListCallFunc == null || _ListCallFunc.Count == 0) return new SqlInfo(); + List where = new List(); + List oredrBy = new List(); + _ListCallFunc.Reverse(); + SqlInfo result = new SqlInfo(); + result.Parameters = new List(); + var isList = false; + int parameterIndex = 100; + foreach (var item in _ListCallFunc) + { + var method = item as MethodCallExpression; + var queryable = db.Queryable(); + if (method.Method.Name == "Where") + { + if (method.Arguments[1].Type == typeof(List)) + { + //var x=method.Arguments[1]; + var conditionals = ExpressionTool.GetExpressionValue(method.Arguments[1]) as List; + if (conditionals.Count > 0) + { + var whereObj = queryable.QueryBuilder.Builder.ConditionalModelToSql(conditionals); + where.Add(whereObj.Key); + if (whereObj.Value != null) + result.Parameters.AddRange(whereObj.Value); + } + } + else + { + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = parameterIndex; + CheckHasRootShortName(method.Arguments[0], method.Arguments[1]); + var exp = method.Arguments[1]; + InitMappingtType(exp); + where.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()); + SetTableShortName(result, queryable); + parameterIndex = queryable.QueryBuilder.LambdaExpressions.ParameterIndex; + } + } + else if (method.Method.Name == "WhereIF") + { + var isOk = LambdaExpression.Lambda(method.Arguments[1]).Compile().DynamicInvoke(); + if (isOk.ObjToBool()) + { + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = parameterIndex; + var exp = method.Arguments[2]; + InitMappingtType(exp); + CheckHasRootShortName(method.Arguments[1], method.Arguments[2]); + where.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()); + SetTableShortName(result, queryable); + parameterIndex = queryable.QueryBuilder.LambdaExpressions.ParameterIndex; + } + } + else if (method.Method.Name.IsIn("OrderBy", "ThenBy")) + { + var exp = method.Arguments[1]; + oredrBy.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()); + SetTableShortName(result, queryable); + } + else if (method.Method.Name == "MappingField") + { + if (result.MappingExpressions == null) + result.MappingExpressions = new List(); + result.MappingExpressions.Add(new MappingFieldsExpression() + { + LeftColumnExpression = method.Arguments[1], + RightColumnExpression = method.Arguments[2] + }); + } + else if (method.Method.Name == "Select") + { + Select(properyName, result, method, queryable); + } + else if (method.Method.Name.IsIn("OrderByDescending", "ThenByDescending")) + { + var exp = method.Arguments[1]; + oredrBy.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString() + " DESC"); + } + else if (method.Method.Name == "Skip") + { + var exp = method.Arguments[1]; + if (exp is BinaryExpression) + { + result.Skip = (int)ExpressionTool.DynamicInvoke(exp); + } + else + { + result.Skip = (int)ExpressionTool.GetExpressionValue(exp); + } + } + else if (method.Method.Name == "Take") + { + var exp = method.Arguments[1]; + if (exp is BinaryExpression) + { + result.Take = (int)ExpressionTool.DynamicInvoke(exp); + } + else + { + result.Take = (int)ExpressionTool.GetExpressionValue(exp); + } + } + else if (method.Method.Name == "ToList") + { + if (method.Arguments.Count > 1) + { + Select(properyName, result, method, queryable); + } + isList = true; + } + else if (method.Method.Name == "SplitTable") + { + var exp = (Expression, IEnumerable>>)(item as MethodCallExpression).Arguments[1]; + result.SplitTable = exp.Compile(); + } + else + { + Check.ExceptionEasy($"no support {item}", $"不支持表达式{item} 不支持方法{method.Method.Name}"); + } + if (queryable.QueryBuilder.Parameters != null) + result.Parameters.AddRange(queryable.QueryBuilder.Parameters); + } + if (where.Count != 0) + { + Check.ExceptionEasy(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList"); + result.WhereString = String.Join(" AND ", where); + } + if (oredrBy.Count != 0) + { + Check.ExceptionEasy(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList"); + result.OrderByString = String.Join(" , ", oredrBy); + } + if (result.SelectString.HasValue()) + { + Check.ExceptionEasy(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList"); + result.OrderByString = String.Join(" , ", oredrBy); + } + return result; + } + + private void Select(string properyName, SqlInfo result, MethodCallExpression method, ISugarQueryable queryable) + { + var exp = method.Arguments[1]; + var newExp = (exp as LambdaExpression).Body; + var types = exp.Type.GetGenericArguments(); + var ps = ExpressionTool.GetParameters(exp).Select(it => it.Name).Distinct().ToList(); + if (ps.Count > 1 && result.TableShortName.IsNullOrEmpty()) + { + result.TableShortName = ps[0]; + } + if (types?.Length > 0) + { + var type = types[0]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + this.Context.InitMappingInfo(type); + Check.ExceptionEasy(newExp.Type != entityInfo.Type, $" new {newExp.Type.Name}is error ,use Select(it=>new {entityInfo.Type.Name})", $"new {newExp.Type.Name}是错误的,请使用Select(it=>new {entityInfo.Type.Name})"); + if (!entityInfo.Columns.Any(x => x.Navigat != null)) + { + result.SelectString = (" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.SelectSingle).GetString()); + } + else + { + var pkInfo = entityInfo.Columns.FirstOrDefault(x => x.IsPrimarykey); + result.SelectString = (" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.SelectSingle).GetString()); + if (ExpressionTool.ContainsTwoLevelAccess(exp)) + { + var shortName = ExpressionTool.GetParameters(exp).FirstOrDefault()?.Name; + if (shortName.HasValue()) + { + if (result.TableShortName == null) + { + result.TableShortName = shortName; + result.IsSelectNav = true; + } + } + } + if (pkInfo != null) + { + var pkName = pkInfo.DbColumnName; + AppColumns(result, queryable, pkName); + } + foreach (var nav in entityInfo.Columns.Where(x => x.Navigat != null && x.Navigat.NavigatType == NavigateType.OneToOne)) + { + var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name); + if (navColumn != null) + { + AppColumns(result, queryable, navColumn.DbColumnName); + } + } + foreach (var nav in entityInfo.Columns.Where(x => x.Navigat != null && x.Navigat.NavigatType == NavigateType.OneToMany && x.Navigat.Name2 != null)) + { + var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name2); + if (navColumn != null) + { + AppColumns(result, queryable, navColumn.DbColumnName); + } + } + result.SelectString = result.SelectString.TrimStart(','); + if (string.IsNullOrEmpty(result.SelectString)) + { + result.SelectString = null; + } + } + if (properyName != null) + { + var fkColumnsInfo = entityInfo.Columns.FirstOrDefault(x => x.PropertyName == properyName); + var pkColumnsInfo = entityInfo.Columns.FirstOrDefault(x => x.IsPrimarykey); + if (fkColumnsInfo != null) + { + var fkName = fkColumnsInfo.DbColumnName; + AppColumns(result, queryable, fkName); + } + if (pkColumnsInfo != null && fkColumnsInfo == null && result.SelectString?.Contains(queryable.SqlBuilder.GetTranslationColumnName(pkColumnsInfo.DbColumnName)) == false) + { + AppColumns(result, queryable, pkColumnsInfo.DbColumnName); + } + } + } + } + + private static void SetTableShortName(SqlInfo result, ISugarQueryable queryable) + { + if (queryable.QueryBuilder.TableShortName.HasValue() && result.TableShortName.IsNullOrEmpty()) + { + result.TableShortName = queryable.QueryBuilder.TableShortName; + } + } + + + private SqlSugarProvider GetCrossDatabase(SqlSugarProvider db, Type type) + { + if (IsCrossQueryWithAttr == false && this.CrossQueryItems == null) + { + return db; + } + else if (IsCrossQueryWithAttr) + { + var tenant = type.GetCustomAttribute(); + if (tenant != null) + { + return db.Root.GetConnection(tenant.configId); + } + else + { + return db; + } + } + else if (this.CrossQueryItems?.Count > 0 && this.CrossQueryItems.TryGetValue(type.FullName, out string? value)) + { + var result = db.Root.GetConnection(value); + return result; + } + else + { + return db; + } + } + + private static void AppColumns(SqlInfo result, ISugarQueryable queryable, string columnName) + { + var selectPkName = queryable.SqlBuilder.GetTranslationColumnName(columnName); + if (result.IsSelectNav) + { + if (result.SelectString?.Contains($" {selectPkName.ToLower()} AS {selectPkName.ToLower()}", StringComparison.CurrentCultureIgnoreCase) == false) + { + result.SelectString = result.SelectString + "," + (selectPkName + " AS " + selectPkName); + } + } + if (result.SelectString?.Contains(selectPkName, StringComparison.CurrentCultureIgnoreCase) == false) + { + result.SelectString = result.SelectString + "," + (selectPkName + " AS " + selectPkName); + } + } + public void CheckHasRootShortName(Expression rootExpression, Expression childExpression) + { + var rootShortName = GetShortName(rootExpression); + if (rootShortName.HasValue() && childExpression.ToString().Contains($" {rootShortName}.")) + { + Check.ExceptionEasy($".Where({childExpression}) no support {rootShortName}.Field, Use .MappingField", $".Where({childExpression})禁止出{rootShortName}.字段 , 你可以使用.MappingField(z=>z.字段,()=>{rootShortName}.字段) 与主表字段进行过滤"); + } + else if (rootShortName.HasValue() && childExpression.ToString().Contains($"({rootShortName}.")) + { + Check.ExceptionEasy($".Where({childExpression}) no support {rootShortName}.Field, Use .MappingField", $".Where({childExpression})禁止出{rootShortName}.字段 , 你可以使用.MappingField(z=>z.字段,()=>{rootShortName}.字段) 与主表字段进行过滤"); + } + } + + private static string GetShortName(Expression expression1) + { + string shortName = null; + if (expression1 is MemberExpression) + { + var shortNameExpression = (expression1 as MemberExpression).Expression; + if (shortNameExpression != null && shortNameExpression.Type == typeof(T)) + { + if (shortNameExpression is ParameterExpression) + { + shortName = (shortNameExpression as ParameterExpression).Name; + } + } + } + return shortName; + } + + + private string GetDbTableName(EntityInfo navEntityInfo, SqlInfo sqlInfo) + { + if (navEntityInfo.Type.GetCustomAttribute() != null && sqlInfo.SplitTable != null) + { + return "(" + this.Context.QueryableByObject(navEntityInfo.Type).SplitTable(sqlInfo.SplitTable).ToSqlString() + ") split_table"; + } + else if (navEntityInfo.Type.GetCustomAttribute() != null) + { + return "(" + this.Context.QueryableByObject(navEntityInfo.Type).SplitTable().ToSqlString() + ") split_table"; + } + else + { + return navEntityInfo.DbTableName; + } + } + + private void InitMappingtType(Expression exp) + { + if (exp is LambdaExpression) + { + var pars = (exp as LambdaExpression).Parameters; + if (pars != null) + { + foreach (var item in pars) + { + this.Context.InitMappingInfo(item.Type); + } + } + } + } + + + private bool IsEnumNumber(EntityColumnInfo navPkColumn) + { + return + navPkColumn?.UnderType?.IsEnum() == true && + navPkColumn?.SqlParameterDbType == null && + this.Context?.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true; + } + private static bool IsOwnsOneProperty(EntityInfo listItemEntity, EntityColumnInfo navObjectNameColumnInfo) + { + return listItemEntity.Columns.Any(it => it.IsOwnsOne) && !listItemEntity.Type.GetProperties().Any(it => it.PropertyType.Name == navObjectNameColumnInfo.Navigat.Name); + } + + private static bool IsJsonMapping(EntityColumnInfo navObjectNameColumnInfo, SqlInfo sqlObj) + { + return sqlObj.MappingExpressions == null && navObjectNameColumnInfo.Navigat.Name.HasValue(); + } + + private void CreateDynamicMappingExpression(SqlInfo sqlObj, string name, EntityInfo navEntityInfo, EntityInfo listItemEntity) + { + var json = Newtonsoft.Json.Linq.JArray.Parse(name); + sqlObj.MappingExpressions = new List(); + foreach (var item in json) + { + string m = item["m"] + ""; + string c = item["c"] + ""; + Check.ExceptionEasy(m.IsNullOrEmpty() || c.IsNullOrEmpty(), $"{name} Navigation json format error, see documentation", $"{name}导航json格式错误,请看文档"); + var cColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(c)); + Check.ExceptionEasy(cColumn == null, $"{c} does not exist in {navEntityInfo.EntityName}", $"{c}不存在于{navEntityInfo.EntityName}"); + var mColumn = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(m)); + Check.ExceptionEasy(cColumn == null, $"{m} does not exist in {listItemEntity.EntityName}", $"{m}不存在于{listItemEntity.EntityName}"); + sqlObj.MappingExpressions.Add(new MappingFieldsExpression() + { + + LeftEntityColumn = cColumn, + RightEntityColumn = mColumn, + }); + } + } + + private string GetOneToManySelectByColumnInfo(EntityColumnInfo it, ISqlSugarClient db) + { + QueryBuilder QueryBuilder = InstanceFactory.GetQueryBuilderWithContext(db); + if (it.QuerySql.HasValue()) + { + return it.QuerySql + " AS " + QueryBuilder.Builder.GetTranslationColumnName(it.PropertyName); + } + if (it.ForOwnsOnePropertyInfo != null) + { + return QueryBuilder.Builder.GetTranslationColumnName(it.DbColumnName); + } + return QueryBuilder.Builder.GetTranslationColumnName(it.DbColumnName) + " AS " + QueryBuilder.Builder.GetTranslationColumnName(it.PropertyName); + } + private string GetOneToOneSelectByColumnInfo(EntityColumnInfo it, ISqlSugarClient db) + { + QueryBuilder QueryBuilder = InstanceFactory.GetQueryBuilderWithContext(db); + if (it.QuerySql.HasValue()) + { + return it.QuerySql + " AS " + QueryBuilder.Builder.GetTranslationColumnName(it.PropertyName); + } + if (it.ForOwnsOnePropertyInfo != null) + { + + return QueryBuilder.Builder.GetTranslationColumnName(it.DbColumnName); + } + return QueryBuilder.Builder.GetTranslationColumnName(it.DbColumnName) + " AS " + QueryBuilder.Builder.GetTranslationColumnName(it.PropertyName); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryMethodInfo.cs new file mode 100644 index 000000000..abbbaf491 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryMethodInfo.cs @@ -0,0 +1,428 @@ +using System.Data; +using System.Text.RegularExpressions; + + +namespace SqlSugar +{ + public class QueryMethodInfo + { + public object QueryableObj { get; internal set; } + public SqlSugarProvider Context { get; internal set; } + public Type EntityType { get; set; } + + + #region Json 2 sql api + #endregion + + #region Sql API + + public QueryMethodInfo MergeTable() + { + var method = QueryableObj.GetType().GetMethod("MergeTable"); + this.QueryableObj = method.Invoke(QueryableObj, Array.Empty()); + return this; + } + public QueryMethodInfo AS(string tableName) + { + string shortName = $"{tableName}_1"; + if (!Regex.IsMatch(shortName, @"^\w+$")) + { + shortName = "maintable"; + } + var method = QueryableObj.GetType().GetMyMethod("AS", 2, typeof(string), typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { tableName, shortName }); + return this; + } + public QueryMethodInfo AS(string tableName, string shortName) + { + var method = QueryableObj.GetType().GetMyMethod("AS", 2, typeof(string), typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { tableName, shortName }); + return this; + } + public QueryMethodInfo OrderBy(List models) + { + var method = QueryableObj.GetType().GetMyMethod("OrderBy", 1, typeof(List)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { models }); + return this; + } + public QueryMethodInfo OrderBy(string orderBySql) + { + var method = QueryableObj.GetType().GetMyMethod("OrderBy", 1, typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { orderBySql }); + return this; + } + public QueryMethodInfo AddJoinInfo(string tableName, string shortName, string onWhere, JoinType type = JoinType.Left) + { + var method = QueryableObj.GetType().GetMyMethod("AddJoinInfo", 4, typeof(string), typeof(string), typeof(string), typeof(JoinType)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { tableName, shortName, onWhere, type }); + return this; + } + public QueryMethodInfo AddJoinInfo(string tableName, string shortName, IFuncModel onFunc, JoinType type = JoinType.Left) + { + var method = QueryableObj.GetType().GetMyMethod("AddJoinInfo", 4, typeof(string), typeof(string), typeof(IFuncModel), typeof(JoinType)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { tableName, shortName, onFunc, type }); + return this; + } + public QueryMethodInfo AddJoinInfo(List joinInfoParameters) + { + foreach (var item in joinInfoParameters) + { + AddJoinInfo(item.TableName, item.ShortName, item.Models, item.Type); + } + return this; + } + public QueryMethodInfo AddJoinInfo(Type joinEntityType, Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expOnWhere, JoinType type = JoinType.Left) + { + var method = QueryableObj.GetType().GetMyMethod("AddJoinInfo", 4, typeof(Type), typeof(Dictionary), typeof(FormattableString), typeof(JoinType)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { joinEntityType, keyIsShortName_ValueIsType_Dictionary, expOnWhere, type }); + return this; + } + public QueryMethodInfo AddJoinInfo(Type joinEntityType, string shortName, string onWhere, JoinType type = JoinType.Left) + { + var method = QueryableObj.GetType().GetMyMethod("AddJoinInfo", 4, typeof(Type), typeof(string), typeof(string), typeof(JoinType)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { joinEntityType, shortName, onWhere, type }); + return this; + } + public QueryMethodInfo GroupBy(List models) + { + var method = QueryableObj.GetType().GetMyMethod("GroupBy", 1, typeof(List)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { models }); + return this; + } + public QueryMethodInfo GroupBy(string groupBySql) + { + var method = QueryableObj.GetType().GetMyMethod("GroupBy", 1, typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { groupBySql }); + return this; + } + public QueryMethodInfo Where(string expShortName, FormattableString expressionString) + { + var method = QueryableObj.GetType().GetMyMethod("Where", 2, typeof(string), typeof(FormattableString)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { expShortName, expressionString }); + return this; + } + public QueryMethodInfo Where(Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expressionString) + { + var method = QueryableObj.GetType().GetMyMethod("Where", 2, typeof(Dictionary), typeof(FormattableString)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { keyIsShortName_ValueIsType_Dictionary, expressionString }); + return this; + } + public QueryMethodInfo Where(List conditionalModels) + { + var method = QueryableObj.GetType().GetMyMethod("Where", 1, typeof(List)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { conditionalModels }); + return this; + } + + public QueryMethodInfo Where(IFuncModel model) + { + var method = QueryableObj.GetType().GetMyMethod("Where", 1, typeof(IFuncModel)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { model }); + return this; + } + + public QueryMethodInfo Where(List conditionalModels, bool isWrap) + { + var method = QueryableObj.GetType().GetMyMethod("Where", 2, typeof(List), typeof(bool)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { conditionalModels, isWrap }); + return this; + } + public QueryMethodInfo Where(string sql, object parameters = null) + { + var method = QueryableObj.GetType().GetMyMethodNoGen("Where", 2, typeof(string), typeof(object)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { sql, parameters }); + return this; + } + public QueryMethodInfo Having(IFuncModel model) + { + var method = QueryableObj.GetType().GetMyMethod("Having", 1, typeof(IFuncModel)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { model }); + return this; + } + public QueryMethodInfo Having(string sql, object parameters = null) + { + var method = QueryableObj.GetType().GetMyMethod("Having", 2, typeof(string), typeof(object)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { sql, parameters }); + return this; + } + public QueryMethodInfo SplitTable(Func, IEnumerable> getTableNamesFunc) + { + var method = QueryableObj.GetType().GetMyMethod("SplitTable", 1, typeof(Func, IEnumerable>)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { getTableNamesFunc }); + return this; + } + public QueryMethodInfo SplitTable(DateTime begintTime, DateTime endTime) + { + var method = QueryableObj.GetType().GetMyMethod("SplitTable", 2, typeof(DateTime), typeof(DateTime)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { begintTime, endTime }); + return this; + } + public QueryMethodInfo SplitTable() + { + var method = QueryableObj.GetType().GetMyMethod("SplitTable", 0); + this.QueryableObj = method.Invoke(QueryableObj, Array.Empty()); + return this; + } + public QueryMethodInfo Select(string expShortName, List columns, params object[] args) + { + var method = QueryableObj.GetType().GetMyMethod("Select", 3, typeof(string), typeof(List), typeof(object[])); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { expShortName, columns, args }); + return this; + } + public QueryMethodInfo Select(List models) + { + var method = QueryableObj.GetType().GetMyMethod("Select", 1, typeof(List)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { models }); + return this; + } + public QueryMethodInfo Select(string expShortName, FormattableString expSelect, Type resultType) + { + var method = QueryableObj.GetType().GetMyMethod("Select", 3, typeof(string), typeof(FormattableString), typeof(Type)); + method = method.MakeGenericMethod(resultType); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { expShortName, expSelect, resultType }); + return this; + } + public QueryMethodInfo Select(Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expSelect, Type resultType) + { + var method = QueryableObj.GetType().GetMyMethod("Select", 3, typeof(Dictionary), typeof(FormattableString), typeof(Type)); + method = method.MakeGenericMethod(resultType); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { keyIsShortName_ValueIsType_Dictionary, expSelect, resultType }); + return this; + } + public QueryMethodInfo Select(string selectorSql) + { + var method = QueryableObj.GetType().GetMyMethod("Select", 1, typeof(string)) + .MakeGenericMethod(EntityType); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { selectorSql }); + return this; + } + + public QueryMethodInfo Select(string selectorSql, Type selectType) + { + var method = QueryableObj.GetType().GetMyMethod("Select", 1, typeof(string)) + .MakeGenericMethod(selectType); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { selectorSql }); + return this; + } + + #endregion + + #region Nav + + public QueryMethodInfo IncludesAllFirstLayer(params string[] ignoreNavPropertyNames) + { + var method = QueryableObj.GetType().GetMyMethod("IncludesAllFirstLayer", 1, typeof(string[])); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { ignoreNavPropertyNames }); + return this; + } + public QueryMethodInfo Includes(string navProperyName) + { + var method = QueryableObj.GetType().GetMyMethod("IncludesByNameString", 1, typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { navProperyName }); + return this; + } + public QueryMethodInfo IgnoreColumns(params string[] ignoreColumns) + { + var method = QueryableObj.GetType().GetMyMethod("IgnoreColumns", 1, typeof(string[])); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { ignoreColumns }); + return this; + } + public QueryMethodInfo Includes(string navProperyName, string thenNavProperyName2) + { + var method = QueryableObj.GetType().GetMyMethod("IncludesByNameString", 2, typeof(string), typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { navProperyName, thenNavProperyName2 }); + return this; + } + public QueryMethodInfo Includes(string navProperyName, string thenNavProperyName2, string thenNavProperyName3) + { + var method = QueryableObj.GetType().GetMyMethod("IncludesByNameString", 3, typeof(string), typeof(string), typeof(string)); + this.QueryableObj = method.Invoke(QueryableObj, new object[] { navProperyName, thenNavProperyName2, thenNavProperyName3 }); + return this; + } + #endregion + + #region Result + + public void IntoTable(Type type, string tableName) + { + var method = QueryableObj.GetType().GetMyMethod("IntoTable", 2, typeof(Type), typeof(string)); + var reslt = method.Invoke(QueryableObj, new object[] { type, tableName }); + } + public object ToPageList(int pageNumber, int pageSize) + { + var method = QueryableObj.GetType().GetMyMethod("ToPageList", 2, typeof(int), typeof(int)); + var reslt = method.Invoke(QueryableObj, new object[] { pageNumber, pageSize }); + return reslt; + } + public object ToPageList(int pageNumber, int pageSize, ref int count) + { + var method = QueryableObj.GetType().GetMyMethod("ToPageList", 3, typeof(int), typeof(int), typeof(int).MakeByRefType()); + var parameters = new object[] { pageNumber, pageSize, count }; + var reslt = method.Invoke(QueryableObj, parameters); + count = parameters.Last().ObjToInt(); + return reslt; + } + public object ToList() + { + var method = QueryableObj.GetType().GetMyMethod("ToList", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return reslt; + } + public DataTable ToDataTablePage(int pageNumber, int pageSize, ref int count) + { + var method = QueryableObj.GetType().GetMyMethod("ToDataTablePage", 3, typeof(int), typeof(int), typeof(int).MakeByRefType()); + var parameters = new object[] { pageNumber, pageSize, count }; + var reslt = (DataTable)method.Invoke(QueryableObj, parameters); + count = parameters.Last().ObjToInt(); + return reslt; + } + public DataTable ToDataTable() + { + var method = QueryableObj.GetType().GetMyMethod("ToDataTable", 0); + var reslt = (DataTable)method.Invoke(QueryableObj, Array.Empty()); + return reslt; + } + public string ToSqlString() + { + var method = QueryableObj.GetType().GetMyMethod("ToSqlString", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return (string)reslt; + } + public KeyValuePair> ToSql() + { + var method = QueryableObj.GetType().GetMyMethod("ToSql", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return (KeyValuePair>)reslt; + } + public object InSingle(object pkValue) + { + var method = QueryableObj.GetType().GetMyMethod("InSingle", 1); + var reslt = method.Invoke(QueryableObj, new object[] { pkValue }); + return reslt; + } + public bool CreateView(string viewNameFomat) + { + if (viewNameFomat?.Contains("{0}") != true) + { + Check.ExceptionEasy("need{0}", "需要{0}表名的占位符"); + } + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(EntityType); + var viewName = string.Format(viewNameFomat, entityInfo.DbTableName); + if (!this.Context.DbMaintenance.GetViewInfoList().Any(it => it.Name.EqualCase(viewName))) + { + var method = QueryableObj.GetType().GetMyMethod("ToSqlString", 0); + var reslt = (string)method.Invoke(QueryableObj, Array.Empty()); + var sql = $"CREATE VIEW {viewName} AS {Environment.NewLine} {reslt}"; + this.Context.Ado.ExecuteCommand(sql); + return true; + } + else + { + return false; + } + } + public object First() + { + var method = QueryableObj.GetType().GetMyMethod("First", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return reslt; + } + public bool Any() + { + var method = QueryableObj.GetType().GetMyMethod("Any", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return Convert.ToBoolean(reslt); + } + public int Count() + { + var method = QueryableObj.GetType().GetMyMethod("Count", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return Convert.ToInt32(reslt); + } + public object ToTree(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName) + { + var method = QueryableObj.GetType().GetMyMethod("ToTree", 4, typeof(string), typeof(string), typeof(object), typeof(string)); + var reslt = method.Invoke(QueryableObj, new object[] { childPropertyName, parentIdPropertyName, rootValue, primaryKeyPropertyName }); + return reslt; + } + + #endregion + + #region Result Async + public async Task ToPageListAsync(int pageNumber, int pageSize) + { + var method = QueryableObj.GetType().GetMyMethod("ToPageListAsync", 2, typeof(int), typeof(int)); + Task task = (Task)method.Invoke(QueryableObj, new object[] { pageNumber, pageSize }); + return await GetTask(task).ConfigureAwait(false); + } + public async Task ToPageListAsync(int pageNumber, int pageSize, RefAsync count) + { + var method = QueryableObj.GetType().GetMyMethod("ToPageListAsync", 3, typeof(int), typeof(int), typeof(RefAsync)); + var parameters = new object[] { pageNumber, pageSize, count }; + var task = (Task)method.Invoke(QueryableObj, parameters); + return await GetTask(task).ConfigureAwait(false); + } + public async Task ToListAsync() + { + var method = QueryableObj.GetType().GetMyMethod("ToListAsync", 0); + var task = (Task)method.Invoke(QueryableObj, Array.Empty()); + return await GetTask(task).ConfigureAwait(false); + } + public async Task ToDataTablePageAsync(int pageNumber, int pageSize, RefAsync count) + { + var method = QueryableObj.GetType().GetMyMethod("ToDataTablePageAsync", 3, typeof(int), typeof(int), typeof(RefAsync)); + var parameters = new object[] { pageNumber, pageSize, count }; + var task = (Task)method.Invoke(QueryableObj, parameters); + count = parameters.Last().ObjToInt(); + return await GetTask(task).ConfigureAwait(false); + } + public async Task ToDataTableAsync() + { + var method = QueryableObj.GetType().GetMyMethod("ToDataTableAsync", 0); + var task = (Task)method.Invoke(QueryableObj, Array.Empty()); + return await GetTask(task).ConfigureAwait(false); + } + public async Task FirstAsync() + { + var method = QueryableObj.GetType().GetMyMethod("FirstAsync", 0); + var task = (Task)method.Invoke(QueryableObj, Array.Empty()); + return await GetTask(task).ConfigureAwait(false); + } + public async Task AnyAsync() + { + var method = QueryableObj.GetType().GetMyMethod("AnyAsync", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return await ((Task)reslt).ConfigureAwait(false); + } + public async Task CountAsync() + { + var method = QueryableObj.GetType().GetMyMethod("CountAsync", 0); + var reslt = method.Invoke(QueryableObj, Array.Empty()); + return await ((Task)reslt).ConfigureAwait(false); + } + public async Task InSingleAsync(object pkValue) + { + var method = QueryableObj.GetType().GetMyMethod("InSingleAsync", 1); + var task = (Task)method.Invoke(QueryableObj, new object[] { pkValue }); + return await GetTask(task).ConfigureAwait(false); + } + + public async Task ToTreeAsync(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName) + { + var method = QueryableObj.GetType().GetMyMethod("ToTreeAsync", 4, typeof(string), typeof(string), typeof(object), typeof(string)); + var task = (Task)method.Invoke(QueryableObj, new object[] { childPropertyName, parentIdPropertyName, rootValue, primaryKeyPropertyName }); + return await GetTask(task).ConfigureAwait(false); + } + #endregion + + #region Helper + private static async Task GetTask(Task task) + { + await task.ConfigureAwait(false); // 等待任务完成 + var resultProperty = task.GetType().GetProperty("Result"); + var result = resultProperty.GetValue(task); + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableAccessory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableAccessory.cs new file mode 100644 index 000000000..2c7a31235 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableAccessory.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public class QueryableAccessory + { + protected ILambdaExpressions _LambdaExpressions; + protected bool _RestoreMapping = true; + protected int _InQueryableIndex = 100; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableContext.cs new file mode 100644 index 000000000..6fcd602a7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableContext.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public class MapperContext + { + public ISqlSugarClient context { get; set; } + + public List list { get; set; } + public Dictionary TempChildLists { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableExecuteSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableExecuteSql.cs new file mode 100644 index 000000000..c7d66fffd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableExecuteSql.cs @@ -0,0 +1,948 @@ +using System.Data; +using System.Linq.Expressions; + +namespace SqlSugar +{ + + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public virtual T Single() + { + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; + } + var oldSkip = QueryBuilder.Skip; + var oldTake = QueryBuilder.Take; + var oldOrderBy = QueryBuilder.OrderByValue; + QueryBuilder.Skip = null; + QueryBuilder.Take = null; + QueryBuilder.OrderByValue = null; + var result = this.ToList(); + QueryBuilder.Skip = oldSkip; + QueryBuilder.Take = oldTake; + QueryBuilder.OrderByValue = oldOrderBy; + if (result == null || result.Count == 0) + { + return default(T); + } + else if (result.Count >= 2) + { + Check.Exception(true, ErrorMessage.GetThrowMessage(".Single() result must not exceed one . You can use.First()", "使用single查询结果集不能大于1,适合主键查询,如果大于1你可以使用Queryable.First")); + return default(T); + } + else + { + return result.SingleOrDefault(); + } + } + public virtual T Single(Expression> expression) + { + _Where(expression); + var result = Single(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public virtual T First() + { + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; + } + if (QueryBuilder.Skip.HasValue) + { + QueryBuilder.Take = 1; + return this.ToList().FirstOrDefault(); + } + else + { + QueryBuilder.Skip = 0; + QueryBuilder.Take = 1; + var result = this.ToList(); + if (result.HasValue()) + return result.FirstOrDefault(); + else + return default(T); + } + } + public virtual T First(Expression> expression) + { + _Where(expression); + var result = First(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public virtual bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public virtual bool Any() + { + return this.Clone().Take(1).Select("1").ToList().Count > 0; + } + + public virtual List ToList(Expression> expression) + { + if (this.QueryBuilder.Includes?.Count > 0) + { + return NavSelectHelper.GetList(expression, this); + // var list = this.ToList().Select(expression.Compile()).ToList(); + // return list; + } + else + { + var list = this.Select(expression).ToList(); + return list; + } + } + + public virtual int Count() + { + if (this.QueryBuilder.Skip == null && + this.QueryBuilder.Take == null && + this.QueryBuilder.OrderByValue == null && + this.QueryBuilder.PartitionByValue == null && + this.QueryBuilder.SelectValue == null && + this.QueryBuilder.Includes == null && + this.QueryBuilder.IsDistinct == false) + { + if (StaticConfig.EnableAot) + { + var sqlobj = this.Clone().Select(" COUNT(1) ").ToSql(); + return this.Context.Ado.GetInt(sqlobj.Key, sqlobj.Value); + } + return this.Clone().Select(" COUNT(1) ").ToList().FirstOrDefault(); + } + MappingTableList expMapping; + int result; + _CountBegin(out expMapping, out result); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context, CacheKey); + } + else + { + result = GetCount(); + } + _CountEnd(expMapping); + return result; + } + public virtual int Count(Expression> expression) + { + _Where(expression); + var result = Count(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public virtual TResult Max(string maxField) + { + this.Select(string.Format(QueryBuilder.MaxTemplate, maxField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Max(Expression> expression) + { + return _Max(expression); + } + + public virtual TResult Min(string minField) + { + this.Select(string.Format(QueryBuilder.MinTemplate, minField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Min(Expression> expression) + { + return _Min(expression); + } + + public virtual TResult Sum(string sumField) + { + this.Select(string.Format(QueryBuilder.SumTemplate, sumField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Sum(Expression> expression) + { + return _Sum(expression); + } + + public virtual TResult Avg(string avgField) + { + this.Select(string.Format(QueryBuilder.AvgTemplate, avgField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Avg(Expression> expression) + { + return _Avg(expression); + } + public virtual T[] ToArray() + { + + var result = this.ToList(); + if (result.HasValue()) + return result.ToArray(); + else + return null; + } + + public virtual string ToJson() + { + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + var result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => + { + return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); + }, CacheTime, this.Context, CacheKey); + return result; + } + else + { + return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); + } + } + public virtual string ToJsonPage(int pageIndex, int pageSize) + { + return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize), typeof(T)); + } + public virtual string ToJsonPage(int pageIndex, int pageSize, ref int totalNumber) + { + return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize, ref totalNumber), typeof(T)); + } + + #region 内存行转列 + + #region 同步 + public virtual DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return this.ToList().ToPivotTable(columnSelector, rowSelector, dataSelector); + } + public virtual List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return ToPivotEnumerable(columnSelector, rowSelector, dataSelector).ToList(); + } + public virtual IEnumerable ToPivotEnumerable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return this.ToList().ToPivotList(columnSelector, rowSelector, dataSelector); + } + public virtual string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + var list = ToPivotEnumerable(columnSelector, rowSelector, dataSelector).ToList(); + return this.Context.Utilities.SerializeObject(list); + } + #endregion + + #region 异步 + public virtual async Task ToPivotTableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await ToListAsync().ConfigureAwait(false)).ToPivotTable(columnSelector, rowSelector, dataSelector); + } + public virtual async Task> ToPivotListAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await ToPivotEnumerableAsync(columnSelector, rowSelector, dataSelector).ConfigureAwait(false)).ToList(); + } + public virtual async Task> ToPivotEnumerableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await ToListAsync().ConfigureAwait(false)).ToPivotList(columnSelector, rowSelector, dataSelector); + } + public virtual async Task ToPivotJsonAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + var list = (await ToPivotEnumerableAsync(columnSelector, rowSelector, dataSelector).ConfigureAwait(false)).ToList(); + return this.Context.Utilities.SerializeObject(list); + } + #endregion + + #endregion + + public List ToChildList(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = this.ToList(); + return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself); + } + public List ToChildList(Expression> parentIdExpression, object[] primaryKeyValues, bool isContainOneself = true) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = this.ToList(); + List result = new List(); + foreach (var item in primaryKeyValues) + { + result.AddRange(GetChildList(parentIdExpression, pk, list, item, isContainOneself)); + } + return result; + } + public List ToParentList(Expression> parentIdExpression, object primaryKeyValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); + if (isTreeKey) + { + return _ToParentListByTreeKey(parentIdExpression, primaryKeyValue); + } + List result = new List() { }; + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Any(), "No Primary key"); + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = this.Context.Queryable().AS(tableName).WithCacheIF(this.IsCache, this.CacheTime).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).ClearFilter(this.QueryBuilder.RemoveFilters).InSingle(primaryKeyValue); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && this.Context.Queryable().AS(tableName).WithCacheIF(this.IsCache, this.CacheTime).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).ClearFilter(this.QueryBuilder.RemoveFilters).In(parentId).Any()) + { + Check.Exception(i > 200, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(200),检查最顶层的ParentId是否是null或者0")); + var parent = this.Context.Queryable().AS(tableName).WithCacheIF(this.IsCache, this.CacheTime).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(parentId); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + public List ToParentList(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); + if (isTreeKey) + { + return _ToParentListByTreeKey(parentIdExpression, primaryKeyValue, parentWhereExpression); + } + List result = new List() { }; + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Any(), "No Primary key"); + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = this.Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(primaryKeyValue); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && this.Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).Any()) + { + Check.Exception(i > 200, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(200),检查最顶层的ParentId是否是null或者0")); + var parent = this.Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(parentId); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + + public List ToTree(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = primaryKeyPropertyName; + var list = this.ToList(); + Expression>> childListExpression = (Expression>>)ExpressionBuilderHelper.CreateExpressionSelectField(typeof(T), childPropertyName, typeof(IEnumerable)); + Expression> parentIdExpression = (Expression>)ExpressionBuilderHelper.CreateExpressionSelectFieldObject(typeof(T), parentIdPropertyName); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List(); + } + public List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, Expression> primaryKeyExpression) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = ExpressionTool.GetMemberName(primaryKeyExpression); + var list = this.ToList(); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List(); + } + public List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = this.ToList(); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List(); + } + public List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds) + { + var list = this.ToList(); + return TreeAndFilterIds(childListExpression, parentIdExpression, rootValue, childIds, ref list) ?? new List(); + } + public List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds, Expression> primaryKeyExpression) + { + var list = this.ToList(); + return TreeAndFilterIds(childListExpression, parentIdExpression, primaryKeyExpression, rootValue, childIds, ref list) ?? new List(); + } + public virtual DataTable ToDataTableByEntity() + { + var list = this.ToList(); + return this.Context.Utilities.ListToDataTable(list); + } + public virtual DataTable ToDataTable() + { + QueryBuilder.ResultType = typeof(SugarCacheDataTable); + InitMapping(); + var sqlObj = this.ToSql(); + RestoreMapping(); + DataTable result = null; + bool isChangeQueryableMasterSlave = GetIsMasterQuery(); + bool isChangeQueryableSlave = GetIsSlaveQuery(); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context, CacheKey); + } + else + { + result = this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); + } + RestChangeMasterQuery(isChangeQueryableMasterSlave); + RestChangeSlaveQuery(isChangeQueryableSlave); + return result; + } + public virtual DataTable ToDataTablePage(int pageIndex, int pageSize) + { + if (pageIndex == 0) + pageIndex = 1; + if (QueryBuilder.PartitionByValue.HasValue()) + { + QueryBuilder.ExternalPageIndex = pageIndex; + QueryBuilder.ExternalPageSize = pageSize; + } + else + { + QueryBuilder.Skip = (pageIndex - 1) * pageSize; + QueryBuilder.Take = pageSize; + } + return ToDataTable(); + } + + public DataTable ToOffsetDataTablePage(int pageNumber, int pageSize) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToDataTablePage(pageNumber, pageSize); + } + else + { + _ToOffsetPage(pageNumber, pageSize); + return this.ToDataTable(); + } + } + public DataTable ToOffsetDataTablePage(int pageNumber, int pageSize, ref int totalNumber) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToDataTablePage(pageNumber, pageSize, ref totalNumber); + } + else + { + totalNumber = this.Clone().Count(); + _ToOffsetPage(pageNumber, pageSize); + return this.Clone().ToDataTable(); + } + } + public DataTable ToOffsetDataTableByEntityPage(int pageNumber, int pageSize, ref int totalNumber) + { + return this.Context.Utilities.ListToDataTable(this.ToOffsetPage(pageNumber, pageSize, ref totalNumber)); + } + public DataTable ToOffsetDataTablePage(int pageNumber, int pageSize, ref int totalNumber, ref int totalPage) + { + return this.Context.Utilities.ListToDataTable(this.ToOffsetPage(pageNumber, pageSize, ref totalNumber, ref totalPage)); + } + + public DataTable ToDataTableByEntityPage(int pageNumber, int pageSize, ref int totalNumber) + { + var list = this.ToPageList(pageNumber, pageSize, ref totalNumber); + return this.Context.Utilities.ListToDataTable(list); + } + public virtual DataTable ToDataTablePage(int pageIndex, int pageSize, ref int totalNumber) + { + _RestoreMapping = false; + totalNumber = this.Clone().Count(); + _RestoreMapping = true; + var result = this.Clone().ToDataTablePage(pageIndex, pageSize); + return result; + } + public virtual DataTable ToDataTablePage(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) + { + var result = ToDataTablePage(pageIndex, pageSize, ref totalNumber); + totalPage = (totalNumber + pageSize - 1) / pageSize; + return result; + } + public Dictionary ToDictionary(Expression> key, Expression> value) + { + return this.ToDictionary(key, value).ToDictionary(it => it.Key, it => (ValueType)UtilMethods.ChangeType2(it.Value, typeof(ValueType))); + } + public Dictionary ToDictionary(Expression> key, Expression> value) + { + if (this.QueryBuilder.IsSingle() == false && (this.QueryBuilder.AsTables == null || this.QueryBuilder.AsTables.Count == 0)) + { + return this.MergeTable().ToDictionary(key, value); + } + this.QueryBuilder.ResultType = typeof(SugarCacheDictionary); + var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString(); + var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString(); + if (this.QueryBuilder.IsSingle() == false) + { + keyName = this.QueryBuilder.TableShortName + "." + keyName; + valueName = this.QueryBuilder.TableShortName + "." + valueName; + } + var isJson = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsJson && it.PropertyName == ExpressionTool.GetMemberName(value)).Any(); + if (isJson) + { + var result = this.Select(keyName + "," + valueName).ToList().ToDictionary(ExpressionTool.GetMemberName(key), ExpressionTool.GetMemberName(value)); + return result; + } + else if (valueName == null) + { + // 编译key和value的表达式树为委托 + var keySelector = key.Compile(); + var valueSelector = value.Compile(); + Dictionary objDic = this.ToList().ToDictionary(keySelector, valueSelector); + return objDic.ToDictionary(it => it.Key?.ToString(), it => it.Value); + } + else + { + var result = this.Select>(keyName + "," + valueName).ToList().ToDictionary(it => it.Key.ObjToString(), it => it.Value); + return result; + } + } + + public List> ToDictionaryList() + { + var list = this.ToList(); + if (list == null) + return null; + else + return this.Context.Utilities.DeserializeObject>>(this.Context.Utilities.SerializeObject(list)); + } + public async Task>> ToDictionaryListAsync() + { + var list = await ToListAsync().ConfigureAwait(false); + if (list == null) + return null; + else + return this.Context.Utilities.DeserializeObject>>(this.Context.Utilities.SerializeObject(list)); + } + + public virtual List ToList() + { + InitMapping(); + return _ToList(); + } + public List SetContext(Expression> whereExpression, ParameterT parameter) + { + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var rootList = queryableContext.list; + List> queryableList = new List>(); + var index = rootList.IndexOf(parameter); + var selector = this.Clone().QueryBuilder.GetSelectValue + $",{index} as "; + var sqlObj = this.Clone().Where(whereExpression).Select(selector + "") + .Select(it => (object)new { it, sql_sugar_index = index }); + queryableList.Add(sqlObj); + + var allList = this.Context.Union(queryableList) + .Select(it => new { it = default(T), sql_sugar_index = 0 }) + .Select("*").ToList(); + var result = new List(); + throw new Exception("开发中"); + } + public List SetContext(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter) + { + if (parameter == null) + { + return new List(); + } + List result = new List(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var pkName = ""; + if ((mappingFiled as LambdaExpression).Body is UnaryExpression) + { + pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var key = thisFiled.ToString() + mappingFiled.ToString() + typeof(ParameterT).FullName + typeof(T).FullName; + var ids = list.Where(it => it != null).Select(it => it.GetType().GetProperty(pkName).GetValue(it)).Distinct().ToArray(); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.TryGetValue(key, out object? value)) + { + result = (List)value; + } + else + { + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + this.Context.Utilities.PageEach(ids, 200, pageIds => + { + result.AddRange(this.Clone().In(thisFiled, pageIds).ToList()); + }); + queryableContext.TempChildLists[key] = result; + } + var name = ""; + if ((thisFiled as LambdaExpression).Body is UnaryExpression) + { + name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter); + result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList(); + return result; + } + public List SetContext(Expression> thisFiled1, Expression> mappingFiled1, + Expression> thisFiled2, Expression> mappingFiled2, + ParameterT parameter) + { + if (parameter == null) + { + return new List(); + } + var rightEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var leftEntity = this.Context.EntityMaintenance.GetEntityInfo(); + List result = new List(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var key = thisFiled1.ToString() + mappingFiled1.ToString() + + thisFiled2.ToString() + mappingFiled2.ToString() + + typeof(ParameterT).FullName + typeof(T).FullName; + MappingFieldsHelper fieldsHelper = new MappingFieldsHelper(); + var mappings = new List() { + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled1, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)), + RightColumnExpression=mappingFiled1, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1)) + }, + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled2, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)), + RightColumnExpression=mappingFiled2, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2)) + } + }; + var conditionals = fieldsHelper.GetMppingSql(list.Cast().ToList(), mappings); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.TryGetValue(key, out object? value)) + { + result = (List)value; + } + else + { + result = this.Clone().Where(conditionals, true).ToList(); + queryableContext.TempChildLists[key] = result; + } + List listObj = result.Select(it => (object)it).ToList(); + object obj = (object)parameter; + var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it => (T)it).ToList(); + return newResult; + } + public void ForEachDataReader(Action action) + { + var queryable = this.Clone(); + var sql = queryable.ToSql(); + var dr = this.Context.Ado.GetDataReader(sql.Key, sql.Value); + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + var columns = UtilMethods.GetColumnInfo(dr); + var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_")); + IDataReaderEntityBuilder entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate("cacheKey", () => + { + var cacheResult = new IDataReaderEntityBuilder(this.Context, dr, + columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T)); + return cacheResult; + }); + using (dr) + { + while (dr.Read()) + { + + var order = entytyList.Build(dr); + action(order); + } + } + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + this.Context.Ado.Close(); + } + } + public async Task ForEachDataReaderAsync(Action action) + { + var queryable = this.Clone(); + var sql = queryable.ToSql(); + var dr = await Context.Ado.GetDataReaderAsync(sql.Key, sql.Value).ConfigureAwait(false); + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + var columns = UtilMethods.GetColumnInfo(dr); + var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_")); + IDataReaderEntityBuilder entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate("cacheKey", () => + { + var cacheResult = new IDataReaderEntityBuilder(this.Context, dr, + columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T)); + return cacheResult; + }); + using (dr) + { + while (dr.Read()) + { + + var order = entytyList.Build(dr); + action(order); + } + } + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + this.Context.Ado.Close(); + } + } + public virtual void ForEach(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach")); + var totalNumber = 0; + var totalPage = 1; + for (int i = 1; i <= totalPage; i++) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + var queryable = this.Clone(); + var page = + totalPage == 1 ? + queryable.ToPageList(i, singleMaxReads, ref totalNumber, ref totalPage) : + queryable.ToPageList(i, singleMaxReads); + foreach (var item in page) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + + public virtual void ForEachByPage(Action action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + int count = this.Clone().Count(); + if (count > 0) + { + if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads) + { + Int32 Skip = (pageIndex - 1) * pageSize; + Int32 NowCount = count - Skip; + Int32 number = 0; + if (NowCount > pageSize) NowCount = pageSize; + while (NowCount > 0) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + if (number + singleMaxReads > pageSize) singleMaxReads = NowCount; + foreach (var item in this.Clone().Skip(Skip).Take(singleMaxReads).ToList()) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + NowCount -= singleMaxReads; + Skip += singleMaxReads; + number += singleMaxReads; + } + } + else + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + foreach (var item in this.Clone().ToPageList(pageIndex, pageSize)) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + totalNumber = count; + } + + public List ToOffsetPage(int pageIndex, int pageSize) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToPageList(pageIndex, pageSize); + } + else + { + _ToOffsetPage(pageIndex, pageSize); + return this.ToList(); + } + } + public virtual List ToOffsetPage(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) + { + var result = ToOffsetPage(pageIndex, pageSize, ref totalNumber); + totalPage = (totalNumber + pageSize - 1) / pageSize; + return result; + } + public List ToOffsetPage(int pageIndex, int pageSize, ref int totalNumber) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToPageList(pageIndex, pageSize, ref totalNumber); + } + else + { + totalNumber = this.Clone().Count(); + _ToOffsetPage(pageIndex, pageSize); + return this.Clone().ToList(); + } + } + public Task> ToOffsetPageAsync(int pageIndex, int pageSize) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToPageListAsync(pageIndex, pageSize); + } + else + { + _ToOffsetPage(pageIndex, pageSize); + return this.ToListAsync(); + } + } + + public virtual List ToPageList(int pageIndex, int pageSize) + { + pageIndex = _PageList(pageIndex, pageSize); + return ToList(); + } + public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber, Expression> expression) + { + if (this.QueryBuilder.Includes?.Count > 0) + { + if (pageIndex == 0) + pageIndex = 1; + var list = this.Clone().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(expression); + var countQueryable = this.Clone(); + countQueryable.QueryBuilder.Includes = null; + totalNumber = countQueryable.Count(); + return list; + } + else + { + var list = this.Select(expression).ToPageList(pageIndex, pageSize, ref totalNumber).ToList(); + return list; + } + } + public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber) + { + var oldMapping = this.Context.MappingTables; + var countQueryable = this.Clone(); + if (countQueryable.QueryBuilder.Offset == "true") + { + countQueryable.QueryBuilder.Offset = null; + } + totalNumber = countQueryable.Count(); + this.Context.MappingTables = oldMapping; + return this.Clone().ToPageList(pageIndex, pageSize); + } + public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) + { + var result = ToPageList(pageIndex, pageSize, ref totalNumber); + totalPage = (totalNumber + pageSize - 1) / pageSize; + return result; + } + public virtual string ToSqlString() + { + if (this.EntityInfo?.Type?.IsInterface == true) + { + this.QueryBuilder.SelectValue = " * "; + this.AsType(this.EntityInfo.Type); + } + var sqlObj = this.Clone().ToSql(); + var result = sqlObj.Key; + if (result == null) return null; + result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig, sqlObj); + return result; + } + + + public virtual KeyValuePair> ToSql() + { + if (!QueryBuilder.IsClone) + { + var newQueryable = this.Clone(); + newQueryable.QueryBuilder.IsClone = true; + return newQueryable.ToSql(); + } + else + { + return _ToSql(); + } + } + public string ToClassString(string className) + { + List columns = new List(); + var properties = typeof(T).GetProperties(); + foreach (var item in properties) + { + columns.Add(new DbColumnInfo() + { + DbColumnName = item.Name, + PropertyName = UtilMethods.GetUnderType(item.PropertyType).Name, + PropertyType = UtilMethods.GetUnderType(item.PropertyType) + }); + } + var result = ((this.Context.DbFirst) as DbFirstProvider).GetClassString(columns, ref className); + return result; + } + + public int IntoTable() + { + return IntoTable(typeof(TableEntityType)); + } + public int IntoTable(string TableName) + { + return IntoTable(typeof(TableEntityType), TableName); + } + public int IntoTable(Type TableEntityType) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(TableEntityType); + var name = this.SqlBuilder.GetTranslationTableName(entityInfo.DbTableName); + return IntoTable(TableEntityType, name); + } + public int IntoTable(Type TableEntityType, string TableName) + { + KeyValuePair> sqlInfo; + string sql; + OutIntoTableSql(TableName, out sqlInfo, out sql, TableEntityType); + return this.Context.Ado.ExecuteCommand(sql, sqlInfo.Value); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableExecuteSqlAsync.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableExecuteSqlAsync.cs new file mode 100644 index 000000000..7ffaf3652 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableExecuteSqlAsync.cs @@ -0,0 +1,785 @@ +using System.Data; +using System.Linq.Expressions; + +namespace SqlSugar +{ + + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public async virtual Task ToArrayAsync() + { + + var result = await ToListAsync().ConfigureAwait(false); + if (result.HasValue()) + return result.ToArray(); + else + return null; + } + + public virtual async Task InSingleAsync(object pkValue) + { + if (pkValue == null) + { + return default(T); + } + Check.Exception(this.QueryBuilder.SelectValue.HasValue(), "'InSingle' and' Select' can't be used together,You can use .Select(it=>...).Single(it.id==1)"); + var list = await In(pkValue).ToListAsync().ConfigureAwait(false); + if (list == null) return default(T); + else return list.SingleOrDefault(); + } + public async Task SingleAsync() + { + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; + } + var oldSkip = QueryBuilder.Skip; + var oldTake = QueryBuilder.Take; + var oldOrderBy = QueryBuilder.OrderByValue; + QueryBuilder.Skip = null; + QueryBuilder.Take = null; + QueryBuilder.OrderByValue = null; + var result = await ToListAsync().ConfigureAwait(false); + QueryBuilder.Skip = oldSkip; + QueryBuilder.Take = oldTake; + QueryBuilder.OrderByValue = oldOrderBy; + if (result == null || result.Count == 0) + { + return default(T); + } + else if (result.Count == 2) + { + Check.Exception(true, ErrorMessage.GetThrowMessage(".Single() result must not exceed one . You can use.First()", "使用single查询结果集不能大于1,适合主键查询,如果大于1你可以使用Queryable.First")); + return default(T); + } + else + { + return result.SingleOrDefault(); + } + } + public async Task SingleAsync(Expression> expression) + { + _Where(expression); + var result = await SingleAsync().ConfigureAwait(false); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public Task FirstAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return FirstAsync(); + } + public async Task FirstAsync() + { + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; + } + if (QueryBuilder.Skip.HasValue) + { + QueryBuilder.Take = 1; + var list = await ToListAsync().ConfigureAwait(false); + return list.FirstOrDefault(); + } + else + { + QueryBuilder.Skip = 0; + QueryBuilder.Take = 1; + var result = await ToListAsync().ConfigureAwait(false); + if (result.HasValue()) + return result.FirstOrDefault(); + else + return default(T); + } + } + public Task FirstAsync(Expression> expression, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return FirstAsync(expression); + } + public async Task FirstAsync(Expression> expression) + { + _Where(expression); + var result = await FirstAsync().ConfigureAwait(false); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public async Task AnyAsync(Expression> expression) + { + _Where(expression); + var result = await AnyAsync().ConfigureAwait(false); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public Task AnyAsync(Expression> expression, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return AnyAsync(expression); + } + + public async Task AnyAsync() + { + return (await Clone().Take(1).Select("1").ToListAsync().ConfigureAwait(false)).Count > 0; ; + } + + public Task CountAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return CountAsync(); + } + public async Task CountAsync() + { + if (this.QueryBuilder.Skip == null && + this.QueryBuilder.Take == null && + this.QueryBuilder.OrderByValue == null && + this.QueryBuilder.PartitionByValue == null && + this.QueryBuilder.SelectValue == null && + this.QueryBuilder.Includes == null && + this.QueryBuilder.IsDistinct == false) + { + var list = await Clone().Select(" COUNT(1) ").ToListAsync().ConfigureAwait(false); + return list.FirstOrDefault(); + } + MappingTableList expMapping; + int result; + _CountBegin(out expMapping, out result); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context, CacheKey); + } + else + { + result = await GetCountAsync().ConfigureAwait(false); + } + _CountEnd(expMapping); + return result; + } + public async Task CountAsync(Expression> expression) + { + _Where(expression); + var result = await CountAsync().ConfigureAwait(false); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public Task CountAsync(Expression> expression, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return CountAsync(expression); + } + + public async Task MaxAsync(string maxField) + { + this.Select(string.Format(QueryBuilder.MaxTemplate, maxField)); + var list = await _ToListAsync().ConfigureAwait(false); + var result = list.SingleOrDefault(); + return result; + } + + public Task MaxAsync(string maxField, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return MaxAsync(maxField); + } + + public Task MaxAsync(Expression> expression) + { + return _MaxAsync(expression); + } + + public Task MaxAsync(Expression> expression, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return MaxAsync(expression); + } + + public async Task MinAsync(string minField) + { + this.Select(string.Format(QueryBuilder.MinTemplate, minField)); + var list = await _ToListAsync().ConfigureAwait(false); + var result = list.SingleOrDefault(); + return result; + } + public Task MinAsync(Expression> expression) + { + return _MinAsync(expression); + } + + public async Task SumAsync(string sumField) + { + this.Select(string.Format(QueryBuilder.SumTemplate, sumField)); + var list = await _ToListAsync().ConfigureAwait(false); + var result = list.SingleOrDefault(); + return result; + } + public Task SumAsync(Expression> expression) + { + return _SumAsync(expression); + } + + public async Task AvgAsync(string avgField) + { + this.Select(string.Format(QueryBuilder.AvgTemplate, avgField)); + var list = await _ToListAsync().ConfigureAwait(false); + var result = list.SingleOrDefault(); + return result; + } + public Task AvgAsync(Expression> expression) + { + return _AvgAsync(expression); + } + + public async virtual Task> ToListAsync(Expression> expression) + { + if (this.QueryBuilder.Includes?.Count > 0) + { + return await NavSelectHelper.GetListAsync(expression, this).ConfigureAwait(false); + } + else + { + var list = await Select(expression).ToListAsync().ConfigureAwait(false); + return list; + } + } + public Task> ToListAsync() + { + InitMapping(); + return _ToListAsync(); + } + + public Task> ToListAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ToListAsync(); + } + public Task> ToPageListAsync(int pageNumber, int pageSize, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ToPageListAsync(pageNumber, pageSize); + } + public Task> ToPageListAsync(int pageIndex, int pageSize) + { + pageIndex = _PageList(pageIndex, pageSize); + return ToListAsync(); + } + public async virtual Task> ToPageListAsync(int pageIndex, int pageSize, RefAsync totalNumber, Expression> expression) + { + if (this.QueryBuilder.Includes?.Count > 0) + { + if (pageIndex == 0) + pageIndex = 1; + var list = await Clone().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(expression).ConfigureAwait(false); + var countQueryable = this.Clone(); + countQueryable.QueryBuilder.Includes = null; + totalNumber.Value = await countQueryable.CountAsync().ConfigureAwait(false); + return list; + } + else + { + var list = await Select(expression).ToPageListAsync(pageIndex, pageSize, totalNumber).ConfigureAwait(false); + return list; + } + } + public Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ToPageListAsync(pageNumber, pageSize, totalNumber); + } + public async Task> ToPageListAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + var oldMapping = this.Context.MappingTables; + var countQueryable = this.Clone(); + if (countQueryable.QueryBuilder.Offset == "true") + { + countQueryable.QueryBuilder.Offset = null; + } + totalNumber.Value = await countQueryable.CountAsync().ConfigureAwait(false); + this.Context.MappingTables = oldMapping; + return await Clone().ToPageListAsync(pageIndex, pageSize).ConfigureAwait(false); + } + public async Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage) + { + var result = await ToPageListAsync(pageNumber, pageSize, totalNumber).ConfigureAwait(false); + totalPage.Value = (totalNumber.Value + pageSize - 1) / pageSize; + return result; + } + + public Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ToPageListAsync(pageNumber, pageSize, totalNumber, totalPage); + } + + public async Task ToJsonAsync() + { + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + var result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => + { + return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); + }, CacheTime, this.Context, CacheKey); + return result; + } + else + { + return this.Context.Utilities.SerializeObject(await ToListAsync().ConfigureAwait(false), typeof(T)); + } + } + public async Task ToJsonPageAsync(int pageIndex, int pageSize) + { + return this.Context.Utilities.SerializeObject(await ToPageListAsync(pageIndex, pageSize).ConfigureAwait(false), typeof(T)); + } + public async Task ToJsonPageAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + var oldMapping = this.Context.MappingTables; + totalNumber.Value = await Clone().CountAsync().ConfigureAwait(false); + this.Context.MappingTables = oldMapping; + return await Clone().ToJsonPageAsync(pageIndex, pageSize).ConfigureAwait(false); + } + public async virtual Task ToDataTableByEntityAsync() + { + var list = await ToListAsync().ConfigureAwait(false); + return this.Context.Utilities.ListToDataTable(list); + } + + public Task ToOffsetDataTablePageAsync(int pageNumber, int pageSize) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToDataTablePageAsync(pageNumber, pageSize); + } + else + { + _ToOffsetPage(pageNumber, pageSize); + return this.ToDataTableAsync(); + } + } + public async Task ToOffsetDataTablePageAsync(int pageNumber, int pageSize, RefAsync totalNumber) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return await ToDataTablePageAsync(pageNumber, pageSize, totalNumber).ConfigureAwait(false); + } + else + { + totalNumber.Value = await Clone().CountAsync().ConfigureAwait(false); + _ToOffsetPage(pageNumber, pageSize); + return await Clone().ToDataTableAsync().ConfigureAwait(false); + } + } + public async Task ToOffsetDataTableByEntityPageAsync(int pageNumber, int pageSize, RefAsync totalNumber) + { + return this.Context.Utilities.ListToDataTable(await ToOffsetPageAsync(pageNumber, pageSize, totalNumber).ConfigureAwait(false)); + } + + public async Task ToDataTableAsync() + { + QueryBuilder.ResultType = typeof(SugarCacheDataTable); + InitMapping(); + var sqlObj = this._ToSql(); + RestoreMapping(); + DataTable result = null; + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context, CacheKey); + } + else + { + result = await Db.GetDataTableAsync(sqlObj.Key, sqlObj.Value.ToArray()).ConfigureAwait(false); + } + return result; + } + public Task ToDataTablePageAsync(int pageIndex, int pageSize) + { + pageIndex = _PageList(pageIndex, pageSize); + return ToDataTableAsync(); + } + public async Task ToDataTablePageAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + var oldMapping = this.Context.MappingTables; + totalNumber.Value = await Clone().CountAsync().ConfigureAwait(false); + this.Context.MappingTables = oldMapping; + return await Clone().ToDataTablePageAsync(pageIndex, pageSize).ConfigureAwait(false); + } + public async Task ToDataTableByEntityPageAsync(int pageNumber, int pageSize, RefAsync totalNumber) + { + var list = await ToPageListAsync(pageNumber, pageSize, totalNumber).ConfigureAwait(false); + return this.Context.Utilities.ListToDataTable(list); + } + public Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ToOffsetPageAsync(pageNumber, pageSize, totalNumber); + } + public Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage, CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ToOffsetPageAsync(pageNumber, pageSize, totalNumber, totalPage); + } + public async Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage) + { + var result = await ToOffsetPageAsync(pageNumber, pageSize, totalNumber).ConfigureAwait(false); + totalPage.Value = (totalNumber.Value + pageSize - 1) / pageSize; + return result; + } + public async Task> ToOffsetPageAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return await ToPageListAsync(pageIndex, pageSize, totalNumber).ConfigureAwait(false); + } + else + { + totalNumber.Value = await Clone().CountAsync().ConfigureAwait(false); + _ToOffsetPage(pageIndex, pageSize); + return await Clone().ToListAsync().ConfigureAwait(false); + } + } + + public virtual async Task ForEachAsync(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach")); + RefAsync totalNumber = 0; + RefAsync totalPage = 1; + for (int i = 1; i <= totalPage; i++) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + var queryable = this.Clone(); + var page = + totalPage == 1 ? + await queryable.ToPageListAsync(i, singleMaxReads, totalNumber, totalPage).ConfigureAwait(false) : + await queryable.ToPageListAsync(i, singleMaxReads).ConfigureAwait(false); + foreach (var item in page) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + public virtual async Task ForEachByPageAsync(Action action, int pageIndex, int pageSize, RefAsync totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + int count = this.Clone().Count(); + if (count > 0) + { + if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads) + { + Int32 Skip = (pageIndex - 1) * pageSize; + Int32 NowCount = count - Skip; + Int32 number = 0; + if (NowCount > pageSize) NowCount = pageSize; + while (NowCount > 0) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + if (number + singleMaxReads > pageSize) singleMaxReads = NowCount; + foreach (var item in await Clone().Skip(Skip).Take(singleMaxReads).ToListAsync().ConfigureAwait(false)) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + NowCount -= singleMaxReads; + Skip += singleMaxReads; + number += singleMaxReads; + } + } + else + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + foreach (var item in this.Clone().ToPageList(pageIndex, pageSize)) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + totalNumber.Value = count; + } + + public async Task> SetContextAsync(Expression> thisFiled1, Expression> mappingFiled1, +Expression> thisFiled2, Expression> mappingFiled2, +ParameterT parameter) + { + if (parameter == null) + { + return new List(); + } + var rightEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var leftEntity = this.Context.EntityMaintenance.GetEntityInfo(); + List result = new List(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var key = thisFiled1.ToString() + mappingFiled1.ToString() + + thisFiled2.ToString() + mappingFiled2.ToString() + + typeof(ParameterT).FullName + typeof(T).FullName; + MappingFieldsHelper fieldsHelper = new MappingFieldsHelper(); + var mappings = new List() { + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled1, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)), + RightColumnExpression=mappingFiled1, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1)) + }, + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled2, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)), + RightColumnExpression=mappingFiled2, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2)) + } + }; + var conditionals = fieldsHelper.GetMppingSql(list.Cast().ToList(), mappings); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.TryGetValue(key, out object? value)) + { + result = (List)value; + } + else + { + result = await Clone().Where(conditionals, true).ToListAsync().ConfigureAwait(false); + queryableContext.TempChildLists[key] = result; + } + List listObj = result.Select(it => (object)it).ToList(); + object obj = (object)parameter; + var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it => (T)it).ToList(); + return newResult; + } + public async Task> SetContextAsync(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter) + { + List result = new List(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var pkName = ""; + if ((mappingFiled as LambdaExpression).Body is UnaryExpression) + { + pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var key = thisFiled.ToString() + mappingFiled.ToString() + typeof(ParameterT).FullName + typeof(T).FullName; + var ids = list.Select(it => it.GetType().GetProperty(pkName).GetValue(it)).ToArray(); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.TryGetValue(key, out object? value)) + { + result = (List)value; + } + else + { + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + await Context.Utilities.PageEachAsync(ids, 200, async pageIds => + { + result.AddRange(await Clone().In(thisFiled, pageIds).ToListAsync().ConfigureAwait(false)); + }).ConfigureAwait(false); + queryableContext.TempChildLists[key] = result; + } + var name = ""; + if ((thisFiled as LambdaExpression).Body is UnaryExpression) + { + name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter); + result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList(); + return result; + } + public async Task> ToDictionaryAsync(Expression> key, Expression> value) + { + return (await ToDictionaryAsync(key, value).ConfigureAwait(false)).ToDictionary(it => it.Key, it => (ValueType)UtilMethods.ChangeType2(it.Value, typeof(ValueType))); + } + public async Task> ToDictionaryAsync(Expression> key, Expression> value) + { + if (this.QueryBuilder.IsSingle() == false && (this.QueryBuilder.AsTables == null || this.QueryBuilder.AsTables.Count == 0)) + { + return await MergeTable().ToDictionaryAsync(key, value).ConfigureAwait(false); + } + this.QueryBuilder.ResultType = typeof(SugarCacheDictionary); + var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString(); + var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString(); + var list = await Select>(keyName + "," + valueName).ToListAsync().ConfigureAwait(false); + var isJson = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsJson && it.PropertyName == ExpressionTool.GetMemberName(value)).Any(); + if (isJson) + { + var result = this.Select(keyName + "," + valueName).ToList().ToDictionary(ExpressionTool.GetMemberName(key), ExpressionTool.GetMemberName(value)); + return result; + } + else + { + var result = list.ToDictionary(it => it.Key.ObjToString(), it => it.Value); + return result; + } + } + public async Task> ToTreeAsync(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = primaryKeyPropertyName; + var list = await ToListAsync().ConfigureAwait(false); + Expression>> childListExpression = (Expression>>)ExpressionBuilderHelper.CreateExpressionSelectField(typeof(T), childPropertyName, typeof(IEnumerable)); + Expression> parentIdExpression = (Expression>)ExpressionBuilderHelper.CreateExpressionSelectFieldObject(typeof(T), parentIdPropertyName); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List(); + } + public async Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds) + { + var list = await ToListAsync().ConfigureAwait(false); + return TreeAndFilterIds(childListExpression, parentIdExpression, rootValue, childIds, ref list) ?? new List(); + } + public async Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds, Expression> primaryKeyExpression) + { + var list = await ToListAsync().ConfigureAwait(false); + return TreeAndFilterIds(childListExpression, parentIdExpression, primaryKeyExpression, rootValue, childIds, ref list) ?? new List(); + } + public async Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); ; + var list = await ToListAsync().ConfigureAwait(false); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List(); + } + public async Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, Expression> primaryKeyExpression) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = ExpressionTool.GetMemberName(primaryKeyExpression); ; + var list = await ToListAsync().ConfigureAwait(false); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List(); + } + public async Task> ToParentListAsync(Expression> parentIdExpression, object primaryKeyValue) + { + List result = new List() { }; + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); + if (isTreeKey) + { + return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue).ConfigureAwait(false); + } + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Any(), "No Primary key"); + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = await Context.Queryable().AS(tableName).WithCacheIF(IsCache, CacheTime).Filter(null, QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue).ConfigureAwait(false); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && await Context.Queryable().AS(tableName).Filter(null, QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync().ConfigureAwait(false)) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = await Context.Queryable().AS(tableName).WithCacheIF(IsCache, CacheTime).Filter(null, QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId).ConfigureAwait(false); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + public async Task> ToParentListAsync(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression) + { + List result = new List() { }; + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); + if (isTreeKey) + { + return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue, parentWhereExpression).ConfigureAwait(false); + } + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Any(), "No Primary key"); + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = await Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue).ConfigureAwait(false); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && await Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync().ConfigureAwait(false)) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = await Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId).ConfigureAwait(false); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + public async Task> ToChildListAsync(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = await ToListAsync().ConfigureAwait(false); + return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself); + } + + public async Task> ToChildListAsync(Expression> parentIdExpression, object[] primaryKeyValues, bool isContainOneself = true) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = await ToListAsync().ConfigureAwait(false); + List result = new List(); + foreach (var item in primaryKeyValues) + { + result.AddRange(GetChildList(parentIdExpression, pk, list, item, isContainOneself)); + } + return result; + } + public Task IntoTableAsync(CancellationToken cancellationToken = default) + { + return IntoTableAsync(typeof(TableEntityType), cancellationToken); + } + public Task IntoTableAsync(string TableName, CancellationToken cancellationToken = default) + { + return IntoTableAsync(typeof(TableEntityType), TableName, cancellationToken); + } + public Task IntoTableAsync(Type TableEntityType, CancellationToken cancellationToken = default) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(TableEntityType); + var name = this.SqlBuilder.GetTranslationTableName(entityInfo.DbTableName); + return IntoTableAsync(TableEntityType, name, cancellationToken); + } + public async Task IntoTableAsync(Type TableEntityType, string TableName, CancellationToken cancellationToken = default) + { + this.Context.Ado.CancellationToken = cancellationToken; + KeyValuePair> sqlInfo; + string sql; + OutIntoTableSql(TableName, out sqlInfo, out sql, TableEntityType); + return await Context.Ado.ExecuteCommandAsync(sql, sqlInfo.Value).ConfigureAwait(false); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableHelper.cs new file mode 100644 index 000000000..a80bb963e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableHelper.cs @@ -0,0 +1,2544 @@ +using Newtonsoft.Json.Linq; + +using System.Collections; +using System.Collections.ObjectModel; +using System.Data; +using System.Linq.Expressions; +using System.Reflection; +using System.Text.RegularExpressions; + + +namespace SqlSugar +{ + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + #region Tree + private List _ToParentListByTreeKey(Expression> parentIdExpression, object primaryKeyValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); + List result = new List() { }; + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = primaryKeyValue + "", + FieldName = treeKey.DbColumnName + } }).First(); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).Any()) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).First(); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + private List _ToParentListByTreeKey(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); + List result = new List() { }; + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = this.Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = primaryKeyValue + "", + FieldName = treeKey.DbColumnName + } }).First(); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && this.Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).Any()) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = this.Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).First(); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + + private async Task> _ToParentListByTreeKeyAsync(Expression> parentIdExpression, object primaryKeyValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); + List result = new List() { }; + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = await Context.Queryable().AS(tableName).Filter(null, QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = primaryKeyValue + "", + FieldName = treeKey.DbColumnName + } }).FirstAsync().ConfigureAwait(false); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && await Context.Queryable().AS(tableName).Filter(null, QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).AnyAsync().ConfigureAwait(false)) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = await Context.Queryable().AS(tableName).Filter(null, QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).FirstAsync().ConfigureAwait(false); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + + private async Task> _ToParentListByTreeKeyAsync(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); + List result = new List() { }; + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = await Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = primaryKeyValue + "", + FieldName = treeKey.DbColumnName + } }).FirstAsync().ConfigureAwait(false); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && await Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).AnyAsync().ConfigureAwait(false)) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = await Context.Queryable().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).FirstAsync().ConfigureAwait(false); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + + private List GetChildList(Expression> parentIdExpression, string pkName, List list, object rootValue, bool isContainOneself) + { + var exp = (parentIdExpression as LambdaExpression).Body; + if (exp is UnaryExpression) + { + exp = (exp as UnaryExpression).Operand; + } + var parentIdName = (exp as MemberExpression).Member.Name; + var result = BuildChildList(list, pkName, parentIdName, rootValue, isContainOneself); + return result; + } + + private static List BuildChildList(List list, string idName, string pIdName, object rootValue, bool isContainOneself) + { + var type = typeof(T); + var idProp = type.GetProperty(idName); + var pIdProp = type.GetProperty(pIdName); + + var kvpList = list.ToDictionary(x => x, v => idProp.GetValue(v).ObjToString()); + var groupKv = list.GroupBy(x => pIdProp.GetValue(x).ObjToString()).ToDictionary(k => k.Key, v => v.ToList()); + + Func> fc = null; + fc = (rootVal) => + { + var finalList = new List(); + if (groupKv.TryGetValue(rootVal, out var nextChildList)) + { + finalList.AddRange(nextChildList); + foreach (var child in nextChildList) + { + finalList.AddRange(fc(kvpList[child])); + } + } + return finalList; + }; + + var result = fc(rootValue.ObjToString()); + + if (isContainOneself) + { + var root = kvpList.FirstOrDefault(x => x.Value == rootValue.ObjToString()).Key; + if (root != null) + { + result.Insert(0, root); + } + } + + return result; + } + private List GetPrentIds(List list, object id, EntityColumnInfo pkName, EntityColumnInfo parentName) + { + var currentId = id; + List result = new List(); + result.Add(id); + while (list.Any(it => pkName.PropertyInfo.GetValue(it).ObjToString() == currentId.ObjToString())) + { + var data = list.First(it => pkName.PropertyInfo.GetValue(it).ObjToString() == currentId.ObjToString()); + currentId = parentName.PropertyInfo.GetValue(data); + result.Add(currentId); + } + return result; + } + private List TreeAndFilterIds(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds, ref List list) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var pkColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == pk); + var newIds = new List(); + string parentIdName = GetParentName(parentIdExpression); + var parentColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == parentIdName); + foreach (var id in childIds) + { + newIds.AddRange(GetPrentIds(list, id, pkColumn, parentColumn)); + } + list = list.Where(z => newIds.Any(it => it.ObjToString() == pkColumn.PropertyInfo.GetValue(z).ObjToString())).ToList(); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); + } + private List TreeAndFilterIds(Expression>> childListExpression, Expression> parentIdExpression, Expression> primaryKeyExpresion, object rootValue, object[] childIds, ref List list) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = ExpressionTool.GetMemberName(primaryKeyExpresion); + var pkColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == pk); + var newIds = new List(); + string parentIdName = GetParentName(parentIdExpression); + var parentColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == parentIdName); + foreach (var id in childIds) + { + newIds.AddRange(GetPrentIds(list, id, pkColumn, parentColumn)); + } + list = list.Where(z => newIds.Any(it => it.ObjToString() == pkColumn.PropertyInfo.GetValue(z).ObjToString())).ToList(); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); + } + + internal List GetTreeRoot(Expression>> childListExpression, Expression> parentIdExpression, string pk, List list, object rootValue) + { + var childName = ((childListExpression as LambdaExpression).Body as MemberExpression).Member.Name; + string parentIdName = GetParentName(parentIdExpression); + return UtilMethods.BuildTree(this.Context, list, pk, parentIdName, childName, rootValue)?.ToList() ?? default; + } + + private static string GetParentName(Expression> parentIdExpression) + { + var exp = (parentIdExpression as LambdaExpression).Body; + if (exp is UnaryExpression) + { + exp = (exp as UnaryExpression).Operand; + } + var parentIdName = (exp as MemberExpression).Member.Name; + return parentIdName; + } + + public List GetTreeChildList(List alllist, object pkValue, string pkName, string childName, string parentIdName) + { + var result = alllist.Where(it => + { + + var value = it.GetType().GetProperty(parentIdName).GetValue(it); + return value.ObjToString() == pkValue.ObjToString(); + + }).ToList(); + if (result?.Count > 0) + { + foreach (var item in result) + { + var itemPkValue = item.GetType().GetProperty(pkName).GetValue(item); + item.GetType().GetProperty(childName).SetValue(item, GetTreeChildList(alllist, itemPkValue, pkName, childName, parentIdName)); + } + } + return result; + } + private static string GetTreeKey(EntityInfo entity) + { + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey || it.IsTreeKey).Any(), "need IsPrimary=true Or IsTreeKey=true"); + string pk = entity.Columns.Where(it => it.IsTreeKey).FirstOrDefault()?.PropertyName; + if (pk == null) + pk = entity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault()?.PropertyName; + return pk; + } + #endregion + + #region Count + protected int GetCount() + { + var sql = string.Empty; + ToSqlBefore(); + sql = QueryBuilder.ToSqlString(); + sql = QueryBuilder.ToCountSql(sql); + var result = Context.Ado.GetInt(sql, QueryBuilder.Parameters.ToArray()); + return result; + } + protected async Task GetCountAsync() + { + var sql = string.Empty; + ToSqlBefore(); + sql = QueryBuilder.ToSqlString(); + sql = QueryBuilder.ToCountSql(sql); + var result = Convert.ToInt32(await Context.Ado.GetScalarAsync(sql, QueryBuilder.Parameters.ToArray()).ConfigureAwait(false)); + return result; + } + private void _CountEnd(MappingTableList expMapping) + { + RestoreMapping(); + QueryBuilder.IsCount = false; + if (expMapping.Count > 0) + { + if (this.QueryableMappingTableList == null) + { + this.QueryableMappingTableList = new MappingTableList(); + } + this.QueryableMappingTableList.Add(expMapping.First()); + } + } + private void _CountBegin(out MappingTableList expMapping, out int result) + { + expMapping = new MappingTableList(); + if (QueryBuilder.EntityName == "ExpandoObject" && this.Context.MappingTables.Any(it => it.EntityName == "ExpandoObject")) + { + expMapping.Add("ExpandoObject", this.Context.MappingTables.First(it => it.EntityName == "ExpandoObject").DbTableName); + } + InitMapping(); + QueryBuilder.IsCount = true; + result = 0; + } + #endregion + + #region Min Max Sum Gvg + protected TResult _Min(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Main"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var result = Min(lamResult.GetResultString()); + QueryBuilder.SelectValue = null; + return result; + } + protected async Task _MinAsync(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Main"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var result = await MinAsync(lamResult.GetResultString()).ConfigureAwait(false); + QueryBuilder.SelectValue = null; + return result; + } + protected TResult _Avg(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Avg"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + return Avg(lamResult.GetResultString()); + } + protected async Task _AvgAsync(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Avg"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + return await AvgAsync(lamResult.GetResultString()).ConfigureAwait(false); + } + protected TResult _Max(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Max"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var reslut = Max(lamResult.GetResultString()); + QueryBuilder.SelectValue = null; + return reslut; + } + protected async Task _MaxAsync(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Max"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var reslut = await MaxAsync(lamResult.GetResultString()).ConfigureAwait(false); + QueryBuilder.SelectValue = null; + return reslut; + } + protected TResult _Sum(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Sum"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var reslut = Sum(lamResult.GetResultString()); + QueryBuilder.SelectValue = null; + return reslut; + } + protected async Task _SumAsync(Expression expression) + { + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuery = false; + } + QueryBuilder.CheckExpression(expression, "Sum"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var reslut = await SumAsync(lamResult.GetResultString()).ConfigureAwait(false); + QueryBuilder.SelectValue = null; + return reslut; + } + #endregion + + #region Master Slave + private void RestChangeMasterQuery(bool isChangeQueryableMasterSlave) + { + if (isChangeQueryableMasterSlave) + this.Context.Ado.IsDisableMasterSlaveSeparation = false; + } + private bool GetIsMasterQuery() + { + var isChangeQueryableMasterSlave = + this.QueryBuilder.IsDisableMasterSlaveSeparation == true && + this.Context.Ado.IsDisableMasterSlaveSeparation == false && + this.Context.Ado.Transaction == null; + if (isChangeQueryableMasterSlave) + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + return isChangeQueryableMasterSlave; + } + private void RestChangeSlaveQuery(bool isChangeQueryableSlaveSlave) + { + if (isChangeQueryableSlaveSlave) + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + } + private bool GetIsSlaveQuery() + { + var isChangeQueryableMasterSlave = + this.QueryBuilder.IsEnableMasterSlaveSeparation == true && + this.Context.Ado.IsDisableMasterSlaveSeparation == true && + this.Context.Ado.Transaction == null; + if (isChangeQueryableMasterSlave) + this.Context.Ado.IsDisableMasterSlaveSeparation = false; + return isChangeQueryableMasterSlave; + } + #endregion + + #region Navigate + internal bool IsAppendNavColumns() + { + return this.QueryBuilder.Includes.HasValue() && this.QueryBuilder.AppendNavInfo == null; + } + + internal void SetAppendNavColumns(Expression expression) + { + var tResultType = expression.Type; + var dic = ExpressionTool.GetNewExpressionItemList(expression); + var navs = this.QueryBuilder.Includes; + var navManages = navs.Cast>(); + if (navManages.FirstOrDefault() == null) return; + this.QueryBuilder.AppendNavInfo = new AppendNavInfo(); + var navInfo = this.QueryBuilder.AppendNavInfo; + var entityColumns = this.EntityInfo.Columns; + var pkColumns = entityColumns.Where(it => it.IsPrimarykey); + AddAppendProperties(navManages, navInfo, entityColumns, pkColumns); + AddMappingNavProperties(dic, navInfo, entityColumns); + } + + private void AddMappingNavProperties(Dictionary dic, AppendNavInfo navInfo, List entityColumns) + { + foreach (var item in dic) + { + var value = item.Value; + var expressionTree = new ExpressionTreeVisitor().GetExpressions(value); + var isSqlMethod = expressionTree.Count != 0 && ExpressionTool.GetMethodName(expressionTree.Last()).IsIn("Any", "Count"); + if (expressionTree.Count != 0 && isSqlMethod == false) + { + + var name = ExpressionTool.GetMemberName(expressionTree.First()); + if (name != null && entityColumns.Any(it => it.Navigat != null && it.PropertyName == name)) + { + var mappingNavColumnInfo = new MappingNavColumnInfo() + { + ExpressionList = expressionTree, + Name = name + }; + navInfo.MappingNavProperties.Add(item.Key, mappingNavColumnInfo); + } + else if (ExpressionTool.IsNavMember(this.Context, value)) + { + var mappingNavColumnInfo = new MappingNavColumnInfo() + { + ExpressionList = expressionTree, + Name = name + }; + if (value is MemberExpression exp) + { + if (exp.Expression is MemberExpression expChild) + { + mappingNavColumnInfo.ParentName = expChild.Member.Name; + } + } + navInfo.MappingNavProperties.Add(item.Key, mappingNavColumnInfo); + } + } + + } + } + + private static void AddAppendProperties(IEnumerable> navManages, AppendNavInfo navInfo, List entityColumns, IEnumerable pkColumns) + { + foreach (var item in pkColumns) + { + navInfo.AppendProperties.Add(item.PropertyName, item.DbColumnName); + } + foreach (var item in navManages) + { + var FirstExp = item.Expressions.First(); + var navName = ExpressionTool.GetMemberName(FirstExp); + if (FirstExp is LambdaExpression && ExpressionTool.GetMethodName((FirstExp as LambdaExpression).Body) == "ToList") + { + navName = ExpressionTool.GetFirstTypeNameFromExpression(FirstExp); + } + var navColumn = entityColumns.Where(it => it.IsPrimarykey == false).Where(it => it.Navigat != null).FirstOrDefault(it => it.PropertyName == navName); + if (navColumn != null && navColumn.Navigat.NavigatType != NavigateType.ManyToMany) + { + var name1 = navColumn.Navigat.Name; + var name2 = navColumn.Navigat.Name2; + var name1Column = entityColumns.FirstOrDefault(it => it.PropertyName == name1); + var name2Column = entityColumns.FirstOrDefault(it => it.PropertyName == name2); + if (name1Column != null) + { + if (!navInfo.AppendProperties.ContainsKey(name1Column.PropertyName)) + navInfo.AppendProperties.Add(name1Column.PropertyName, name1Column.DbColumnName); + } + if (name2Column != null) + { + if (!navInfo.AppendProperties.ContainsKey(name2Column.PropertyName)) + navInfo.AppendProperties.Add(name2Column.PropertyName, name2Column.DbColumnName); + } + if (navColumn.Navigat.NavigatType == NavigateType.Dynamic && name1.HasValue()) + { + var jarray = JArray.Parse(name1); + foreach (var jitem in jarray) + { + var columnInfo = entityColumns.FirstOrDefault(it => + it.PropertyName.EqualCase(jitem["m"].ToString()) || + it.DbColumnName.EqualCase(jitem["m"].ToString())); + if (columnInfo != null) + { + if (!navInfo.AppendProperties.ContainsKey(columnInfo.PropertyName)) + navInfo.AppendProperties.Add(columnInfo.PropertyName, columnInfo.DbColumnName); + } + } + } + } + } + } + + private async Task _InitNavigatAsync(List result) + { + if (this.QueryBuilder.Includes != null) + { + await Task.Run(() => { _InitNavigat(result); }).ConfigureAwait(false); + } + } + private void _InitNavigat(List result) + { + if (this.QueryBuilder.Includes != null) + { + var managers = (this.QueryBuilder.Includes as List); + if (this.QueryBuilder.AppendNavInfo?.AppendProperties?.Count > 0) + { + if (result.HasValue()) + { + SelectNavQuery(result, managers); + } + } + else + { + foreach (var it in managers) + { + var manager = it as NavigatManager; + if (manager != null) + { + manager.RootList = result; + manager.Execute(); + } + } + } + } + } + + private void SelectNavQuery(List result, List managers) + { + if (result.Count != 0) + { + IList outList = null; + foreach (var it in managers) + { + var manager = it; + var p = it.GetType().GetProperty("RootList"); + var tType = it.GetType().GenericTypeArguments[0]; + var allColumns = this.Context.EntityMaintenance.GetEntityInfo(tType) + .Columns; + var columns = allColumns + .Where(a => this.QueryBuilder.AppendNavInfo.Result.First().result.ContainsKey("SugarNav_" + a.PropertyName)) + .ToList(); + var listType = typeof(List<>).MakeGenericType(tType); + if (outList == null) + { + outList = SelectNavQuery_SetList(result, it, p, tType, columns, listType); + } + else + { + p.SetValue(it, outList); + } + it.GetType().GetMethod("Execute").Invoke(it, null); + SelectNavQuery_MappingList(it, result, outList, allColumns.Where(a => a.Navigat != null).ToList()); + } + } + } + + private void SelectNavQuery_MappingList(object it, List result, IList outList, List columnInfos) + { + for (int i = 0; i < result.Count; i++) + { + var leftObject = result[i]; + var rightObject = outList[i]; + foreach (var item in this.QueryBuilder.AppendNavInfo.MappingNavProperties) + { + var rightName = item.Value.Name; + var rightColumnInfo = columnInfos.FirstOrDefault(a => a.PropertyName == rightName); + var anyParent = item.Value.ParentName.HasValue(); + if (anyParent) + { + rightColumnInfo = columnInfos.FirstOrDefault(a => a.PropertyName == item.Value.ParentName); + } + var rightValue = rightColumnInfo.PropertyInfo.GetValue(rightObject); + var leftName = item.Key; + if (anyParent) + { + if (rightValue == null) + { + rightValue = UtilMethods.GetDefaultValue(rightColumnInfo.PropertyInfo.PropertyType); + } + rightValue = rightValue.GetType().GetProperty(item.Value.Name).GetValue(rightValue); + } + //// var rightColumn=col + // object value = item; + if (item.Value.ExpressionList.Count > 1 && rightValue != null) + { + + //foreach (var callExp in item.Value.ExpressionList.Skip(1)) + //{ + try + { + MethodCallExpression meExp = (MethodCallExpression)item.Value.ExpressionList.Last(); + ParameterExpression ps = ExpressionTool.GetParameters(meExp).First(); + var comExp = Expression.Lambda(meExp, ps); + var obj = comExp.Compile(); + // 传递参数值 + var leftValue = obj.DynamicInvoke(rightObject); + UtilMethods.SetAnonymousObjectPropertyValue(leftObject, leftName, leftValue); + } + catch (Exception ex) + { + var errorExp = item.Value.ExpressionList.Last().ToString(); + Check.ExceptionEasy($"{errorExp} no support,{ex.Message}", $"{errorExp}语法不支持,请查SqlSugar文档询导航DTO用法,{ex.Message}"); + } + // // 重新构造Lambda表达式,将参数替换为新的参数,方法调用替换为新的方法调用 + // var newExpression = Expression.Lambda>>(newMethodCallExpr, paramExpr); + // Expression.Call(callExp, (callExp as MethodCallExpression).Method,new ) + // var propertyExpr = Expression.Property(paramExpr, rightName); + // } + } + else if (rightValue != null) + { + //leftObject.GetType().GetProperty(leftName).SetValue(leftObject, rightValue); + UtilMethods.SetAnonymousObjectPropertyValue(leftObject, leftName, rightValue); + } + } + } + } + + private IList SelectNavQuery_SetList(List result, object it, PropertyInfo p, Type tType, List columns, Type listType) + { + var outList = Activator.CreateInstance(listType); + p.SetValue(it, outList); + var index = 0; + foreach (var item in result) + { + var addItem = Activator.CreateInstance(tType); + var appendResult = this.QueryBuilder.AppendNavInfo.Result[index]; + foreach (var kv in appendResult.result) + { + var propertyName = kv.Key.Replace("SugarNav_", ""); + var propertyInfo = columns.First(i => i.PropertyName == propertyName).PropertyInfo; + if (kv.Value is decimal && UtilMethods.GetUnderType(propertyInfo.PropertyType).IsIn(typeof(int), typeof(long))) + { + + var changeValue = UtilMethods.ChangeType2(kv.Value, propertyInfo.PropertyType); + propertyInfo.SetValue(addItem, changeValue); + } + else if (kv.Value == DBNull.Value && UtilMethods.GetUnderType(propertyInfo.PropertyType).IsIn(typeof(int), typeof(long))) + { + + var changeValue = UtilMethods.ChangeType2(0, propertyInfo.PropertyType); + propertyInfo.SetValue(addItem, changeValue); + } + else if (kv.Value == DBNull.Value) + { + propertyInfo.SetValue(addItem, null); + } + else if (UtilMethods.GetUnderType(propertyInfo.PropertyType) == typeof(Guid) && kv.Value is string) + { + propertyInfo.SetValue(addItem, new Guid(kv.Value.ToString())); + } + else if (UtilMethods.GetUnderType(propertyInfo.PropertyType) == typeof(int) && kv.Value is long) + { + propertyInfo.SetValue(addItem, Convert.ToInt32(kv.Value)); + } + else if (propertyInfo.PropertyType.FullName == "System.Ulid") + { + propertyInfo.SetValue(addItem, UtilMethods.To(kv.Value, propertyInfo.PropertyType)); + } + else + { + propertyInfo.SetValue(addItem, kv.Value); + } + } + (outList as IList).Add(addItem); + index++; + } + return outList as IList; + } + + private bool IsSelectNavQuery() + { + return this.QueryBuilder.SelectValue.HasValue() && this.QueryBuilder.NoCheckInclude == false; + } + + protected void _Mapper(List result) + { + if (this.EntityInfo.Columns.Any(it => it.IsTranscoding)) + { + foreach (var item in result) + { + foreach (var column in this.EntityInfo.Columns.Where(it => it.IsTranscoding)) + { + var value = column.PropertyInfo.GetValue(item, null); + if (value != null) + { + column.PropertyInfo.SetValue(item, UtilMethods.DecodeBase64(value.ToString()), null); + } + } + } + } + if (this.Mappers.HasValue()) + { + foreach (var mapper in this.Mappers) + { + if (typeof(TResult) == typeof(T)) + { + mapper(result.Select(it => (T)Convert.ChangeType(it, typeof(T))).ToList()); + } + else + { + Check.Exception(true, "{0} and {1} are not a type, Try .select().mapper().ToList", typeof(TResult).FullName, typeof(T).FullName); + } + } + } + if (this.MapperAction != null) + { + foreach (TResult item in result) + { + if (typeof(TResult) == typeof(T)) + { + foreach (var mapper in this.MapperAction) + { + mapper((T)(item as object)); + } + } + else + { + Check.Exception(true, "{0} and {1} are not a type, Try .select().mapper().ToList", typeof(TResult).FullName, typeof(T).FullName); + } + } + } + if (this.MapperActionWithCache != null) + { + if (typeof(TResult) == typeof(T)) + { + var list = (List)Convert.ChangeType(result, typeof(List)); + var mapperCache = new MapperCache(list, this.Context); + foreach (T item in list) + { + mapperCache.GetIndex = 0; + this.MapperActionWithCache(item, mapperCache); + } + } + else + { + Check.Exception(true, "{0} and {1} are not a type, Try .select().mapper().ToList", typeof(TResult).FullName, typeof(T).FullName); + } + } + } + private QueryableProvider _Mapper(Expression mapperObject, Expression mapperField) + { + if ((mapperObject as LambdaExpression).Body is UnaryExpression) + { + mapperObject = ((mapperObject as LambdaExpression).Body as UnaryExpression).Operand; + } + else + { + mapperObject = (mapperObject as LambdaExpression).Body; + } + if ((mapperField as LambdaExpression).Body is UnaryExpression) + { + mapperField = ((mapperField as LambdaExpression).Body as UnaryExpression).Operand; + } + else + { + mapperField = (mapperField as LambdaExpression).Body; + } + Check.Exception(mapperObject is MemberExpression == false || mapperField is MemberExpression == false, ".Mapper() parameter error"); + var mapperObjectExp = mapperObject as MemberExpression; + var mapperFieldExp = mapperField as MemberExpression; + Check.Exception(mapperFieldExp.Type.IsClass(), ".Mapper() parameter error"); + var objType = mapperObjectExp.Type; + var filedType = mapperFieldExp.Expression.Type; + Check.Exception(objType != typeof(TObject) && objType != typeof(List), ".Mapper() parameter error"); + if (objType == typeof(List)) + { + objType = typeof(TObject); + } + var filedName = mapperFieldExp.Member.Name; + var objName = mapperObjectExp.Member.Name; + var filedEntity = this.Context.EntityMaintenance.GetEntityInfo(objType); + var objEntity = this.Context.EntityMaintenance.GetEntityInfo(filedType); + var isSelf = filedType == typeof(T); + if (Mappers == null) + Mappers = new List>>(); + if (isSelf) + { + Action> mapper = (entitys) => + { + if (entitys.IsNullOrEmpty() || entitys.Count == 0) return; + var entity = entitys.First(); + var whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(filedName, StringComparison.CurrentCultureIgnoreCase)); + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + } + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); + } + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + Check.Exception(true, ".Mapper() parameter error"); + } + List inValues = entitys.Select(it => it.GetType().GetProperty(filedName).GetValue(it, null).ObjToString()).ToList(); + if (inValues != null && inValues.Count != 0 && UtilMethods.GetUnderType(entitys.First().GetType().GetProperty(filedName).PropertyType) == UtilConstants.GuidType) + { + inValues = inValues.Select(x => string.IsNullOrEmpty(x) ? "null" : x).Distinct().ToList(); + } + List wheres = new List() + { + new ConditionalModel() + { + FieldName=this.SqlBuilder.GetTranslationColumnName(whereCol.DbColumnName), + ConditionalType= ConditionalType.In, + FieldValue=string.Join(",",inValues.Distinct()), + CSharpTypeName=whereCol.PropertyInfo.PropertyType.Name + } + }; + var list = this.Context.Queryable().Where(wheres).ToList(); + foreach (var item in entitys) + { + var whereValue = item.GetType().GetProperty(filedName).GetValue(item, null); + var setValue = list.Where(x => x.GetType().GetProperty(whereCol.PropertyName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); + var setObject = item.GetType().GetProperty(objName); + if (setObject.PropertyType.FullName.IsCollectionsList()) + { + setObject.SetValue(item, setValue.ToList(), null); + } + else + { + setObject.SetValue(item, setValue.FirstOrDefault(), null); + } + } + }; + Mappers.Add(mapper); + } + else + { + Action> mapper = (entitys) => + { + if (entitys.IsNullOrEmpty() || entitys.Count == 0) return; + var entity = entitys.First(); + var tEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(filedName, StringComparison.CurrentCultureIgnoreCase)); + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + } + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); + } + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + Check.Exception(true, ".Mapper() parameter error"); + } + List inValues = entitys.Select(it => it.GetType().GetProperty(whereCol.PropertyName).GetValue(it, null).ObjToString()).ToList(); + var dbColumnName = filedEntity.Columns.FirstOrDefault(it => it.PropertyName == filedName).DbColumnName; + List wheres = new List() + { + new ConditionalModel() + { + FieldName=dbColumnName, + ConditionalType= ConditionalType.In, + FieldValue=string.Join(",",inValues) + } + }; + var list = this.Context.Queryable().Where(wheres).ToList(); + foreach (var item in entitys) + { + var whereValue = item.GetType().GetProperty(whereCol.PropertyName).GetValue(item, null); + var setValue = list.Where(x => x.GetType().GetProperty(filedName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); + var setObject = item.GetType().GetProperty(objName); + if (setObject.PropertyType.FullName.IsCollectionsList()) + { + setObject.SetValue(item, setValue.ToList(), null); + } + else + { + setObject.SetValue(item, setValue.FirstOrDefault(), null); + } + } + }; + Mappers.Add(mapper); + } + + return this; + } + private QueryableProvider _Mapper(Expression mapperObject, Expression mainField, Expression childField) + { + if ((mapperObject as LambdaExpression).Body is UnaryExpression) + { + mapperObject = ((mapperObject as LambdaExpression).Body as UnaryExpression).Operand; + } + else + { + mapperObject = (mapperObject as LambdaExpression).Body; + } + if ((mainField as LambdaExpression).Body is UnaryExpression) + { + mainField = ((mainField as LambdaExpression).Body as UnaryExpression).Operand; + } + else + { + mainField = (mainField as LambdaExpression).Body; + } + if ((childField as LambdaExpression).Body is UnaryExpression) + { + childField = ((childField as LambdaExpression).Body as UnaryExpression).Operand; + } + else + { + childField = (childField as LambdaExpression).Body; + } + Check.Exception(mapperObject is MemberExpression == false || mainField is MemberExpression == false, ".Mapper() parameter error"); + var mapperObjectExp = mapperObject as MemberExpression; + var mainFieldExp = mainField as MemberExpression; + var childFieldExp = childField as MemberExpression; + Check.Exception(mainFieldExp.Type.IsClass(), ".Mapper() parameter error"); + Check.Exception(childFieldExp.Type.IsClass(), ".Mapper() parameter error"); + var objType = mapperObjectExp.Type; + var filedType = mainFieldExp.Expression.Type; + Check.Exception(objType != typeof(TObject) && objType != typeof(List), ".Mapper() parameter error"); + if (objType == typeof(List)) + { + objType = typeof(TObject); + } + var mainFiledName = mainFieldExp.Member.Name; + var childFiledName = childFieldExp.Member.Name; + var objName = mapperObjectExp.Member.Name; + var filedEntity = this.Context.EntityMaintenance.GetEntityInfo(objType); + var objEntity = this.Context.EntityMaintenance.GetEntityInfo(filedType); + var isSelf = filedType == typeof(T); + if (Mappers == null) + Mappers = new List>>(); + if (isSelf) + { + Action> mapper = (entitys) => + { + if (entitys.IsNullOrEmpty() || entitys.Count == 0) return; + var entity = entitys.First(); + var whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(childFiledName, StringComparison.CurrentCultureIgnoreCase)); + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + } + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); + } + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + whereCol = filedEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + Check.Exception(true, ".Mapper() parameter error"); + } + List inValues = entitys.Select(it => it.GetType().GetProperty(mainFiledName).GetValue(it, null).ObjToString()).ToList(); + List wheres = new List() + { + new ConditionalModel() + { + FieldName=whereCol.DbColumnName, + ConditionalType= ConditionalType.In, + FieldValue=string.Join(",",inValues.Distinct()) + } + }; + var list = this.Context.Queryable().Where(wheres).ToList(); + foreach (var item in entitys) + { + var whereValue = item.GetType().GetProperty(mainFiledName).GetValue(item, null); + var setValue = list.Where(x => x.GetType().GetProperty(whereCol.PropertyName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); + var setObject = item.GetType().GetProperty(objName); + if (setObject.PropertyType.FullName.IsCollectionsList()) + { + setObject.SetValue(item, setValue.ToList(), null); + } + else + { + setObject.SetValue(item, setValue.FirstOrDefault(), null); + } + } + }; + Mappers.Add(mapper); + } + else + { + Action> mapper = (entitys) => + { + if (entitys.IsNullOrEmpty() || entitys.Count == 0) return; + var entity = entitys.First(); + var tEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(childFiledName, StringComparison.CurrentCultureIgnoreCase)); + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + } + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); + } + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + whereCol = tEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); + } + if (whereCol == null) + { + Check.Exception(true, ".Mapper() parameter error"); + } + List inValues = entitys.Select(it => it.GetType().GetProperty(whereCol.PropertyName).GetValue(it, null).ObjToString()).ToList(); + var dbColumnName = filedEntity.Columns.FirstOrDefault(it => it.PropertyName == mainFiledName).DbColumnName; + List wheres = new List() + { + new ConditionalModel() + { + FieldName=dbColumnName, + ConditionalType= ConditionalType.In, + FieldValue=string.Join(",",inValues) + } + }; + var list = this.Context.Queryable().Where(wheres).ToList(); + foreach (var item in entitys) + { + var whereValue = item.GetType().GetProperty(whereCol.PropertyName).GetValue(item, null); + var setValue = list.Where(x => x.GetType().GetProperty(mainFiledName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); + var setObject = item.GetType().GetProperty(objName); + if (setObject.PropertyType.FullName.IsCollectionsList()) + { + setObject.SetValue(item, setValue.ToList(), null); + } + else + { + setObject.SetValue(item, setValue.FirstOrDefault(), null); + } + } + }; + Mappers.Add(mapper); + } + + return this; + } + private void SetContextModel(List result, Type entityType) + { + if (result.HasValue()) + { + if (UtilMethods.GetRootBaseType(entityType).HasValue() && UtilMethods.GetRootBaseType(entityType) == UtilConstants.ModelType) + { + foreach (var item in result) + { + var contextProperty = item.GetType().GetProperty("Context"); + SqlSugarProvider newClient = this.Context.Utilities.CopyContext(); + newClient.Ado.IsDisableMasterSlaveSeparation = true; + if (newClient.CurrentConnectionConfig.AopEvents == null) + newClient.CurrentConnectionConfig.AopEvents = new AopEvents(); + contextProperty.SetValue(item, newClient, null); + } + } + } + } + #endregion + + #region Mapping Type + protected void RestoreMapping() + { + if (IsAs && _RestoreMapping) + { + this.Context.MappingTables = OldMappingTableList == null ? new MappingTableList() : OldMappingTableList; + } + } + protected void InitMapping() + { + if (this.QueryableMappingTableList != null) + this.Context.MappingTables = this.QueryableMappingTableList; + } + #endregion + + #region Other + + private bool IsSingleWithChildTableQuery() + { + return this.QueryBuilder.IsSingle() && this.QueryBuilder.TableShortName.HasValue(); + } + + private Expression> ReplaceMasterTableParameters(Expression> expression) + { + var parameterName = (expression as LambdaExpression)?.Parameters?.FirstOrDefault()?.Name; + if (parameterName != null && parameterName != this.QueryBuilder.TableShortName) + { + expression = ExpressionTool.ChangeLambdaExpression(expression, parameterName, this.QueryBuilder.TableShortName); + } + + return expression; + } + private void orderPropertyNameByJoin(string orderPropertyName, OrderByType? orderByType) + { + var shortName = orderPropertyName.Split('.').FirstOrDefault(); + orderPropertyName = orderPropertyName.Split('.').Last(); + var entityType = this.QueryBuilder.JoinQueryInfos.FirstOrDefault(it => it.ShortName.EqualCase(shortName))?.EntityType; + if (entityType == null) + { + entityType = this.EntityInfo.Type; + } + if (this.Context.EntityMaintenance.GetEntityInfoWithAttr(entityType).Columns.Any(it => + it.DbColumnName?.EqualCase(orderPropertyName) == true + || it.PropertyName?.EqualCase(orderPropertyName) == true)) + { + var name = this.Context.EntityMaintenance.GetEntityInfoWithAttr(entityType).Columns.FirstOrDefault(it => + it.DbColumnName?.EqualCase(orderPropertyName) == true + || it.PropertyName?.EqualCase(orderPropertyName) == true)?.DbColumnName; + this.OrderBy(this.SqlBuilder.GetTranslationColumnName(shortName) + "." + this.SqlBuilder.GetTranslationColumnName(name) + " " + orderByType); + } + else + { + Check.ExceptionEasy($"OrderByPropertyName error.{orderPropertyName} does not exist in the entity class", $"OrderByPropertyName出错实体类中不存在{orderPropertyName}"); + } + } + + private void OutIntoTableSql(string TableName, out KeyValuePair> sqlInfo, out string sql, Type tableInfo) + { + var columnList = this.Context.EntityMaintenance.GetEntityInfo(tableInfo).Columns; + //var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(TableEntityType); + sqlInfo = this.ToSql(); + var name = this.SqlBuilder.GetTranslationTableName(TableName); + var columns = ""; + sql = ""; + var isSqlFunc = this.QueryBuilder.SelectValue is Expression; + if (isSqlFunc) + { + columns = "("; + foreach (var item in ExpressionTool.GetNewExpressionItemList((Expression)this.QueryBuilder.SelectValue)) + { + var column = item.Key; + var columnInfo = columnList.FirstOrDefault(it => it.PropertyName == item.Key); + if (columnInfo != null) + { + column = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + } + columns += $"{column},"; + } + columns = columns.TrimEnd(',') + ")"; + sql = $" INSERT INTO {name} {columns} " + sqlInfo.Key; + } + else + { + //if (this.QueryBuilder.GetSelectValue != null && this.QueryBuilder.GetSelectValue.Contains(",")) ; + //{ + columns = "("; + foreach (var item in this.QueryBuilder.GetSelectValue.Split(',')) + { + var column = Regex.Split(item, " AS ").Last().Trim(); + var columnInfo = columnList.FirstOrDefault(it => SqlBuilder.GetTranslationColumnName(it.PropertyName) == column); + if (columnInfo != null) + { + column = SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + } + columns += $"{column},"; + } + columns = columns.TrimEnd(',') + ")"; + //} + sql = $" INSERT INTO {name} {columns} " + sqlInfo.Key; + } + } + + internal string GetTableName(EntityInfo entity, string tableName) + { + var oldTableName = tableName; + var attr = entity?.Type?.GetCustomAttribute(); + var configId = ((object)this.Context.CurrentConnectionConfig.ConfigId).ObjToString(); + if (attr != null && configId != attr.configId.ObjToString()) + { + var dbName = this.Context.Root.GetConnection(attr.configId).Ado.Connection.Database; + var guidPoint = Guid.NewGuid().ObjToString(); + dbName = dbName.Replace(".", guidPoint); + tableName = this.Context.Root.GetConnection(attr.configId).EntityMaintenance.GetEntityInfo(entity.Type).DbTableName; + oldTableName = tableName; + tableName = this.QueryBuilder.LambdaExpressions.DbMehtods.GetTableWithDataBase + (this.QueryBuilder.Builder.GetTranslationColumnName(dbName), this.QueryBuilder.Builder.GetTranslationColumnName(tableName)); + tableName = tableName.Replace(guidPoint, "."); + } + + if (attr != null && configId != attr.configId.ObjToString()) + { + var dbLinkName = this.Context.Root.GetConnection(attr.configId).CurrentConnectionConfig.DbLinkName; + if (dbLinkName != null) + { + if (dbLinkName.First() == '@') + { + tableName = this.QueryBuilder.Builder.GetTranslationColumnName(oldTableName) + dbLinkName; + } + else if (dbLinkName.Last() == '_') + { + tableName = dbLinkName + oldTableName; + } + else + { + tableName = dbLinkName + "." + this.QueryBuilder.Builder.GetTranslationColumnName(oldTableName); + } + } + } + if (tableName == null) + { + tableName = entity.DbTableName; + } + return tableName; + } + protected string AppendSelect(List entityColumnInfos, string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1) + { + //var lowerSql = sql.ToLower(); + //var isSubquery = lowerSql.Contains("select ") && ExpressionTool.IsMemberInit(this.QueryBuilder.SelectValue); + //if (isSubquery) + //{ + return AppendSelectWithSubQuery(entityColumnInfos, sql, parameters, columnsResult, parameterIndex1); + //} + //var columns = entityColumnInfos; + //var parameterName = parameters[parameterIndex1]; + //foreach (var item in columns) + //{ + // if (item.IsIgnore == false && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !lowerSql.Contains(SqlBuilder.GetTranslationColumnName(item.PropertyName.ToLower()))) + // { + // if (item.EntityName == this.QueryBuilder.EntityName&&sql.StartsWith("*,")) + // { + // continue; + // } + // sql = $" {sql},{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; + // } + //} + + //return sql; + } + private string AppendSelectWithSubQuery(List entityColumnInfos, string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1, string parameterName) + { + var list = ExpressionTool.GetMemberInit(this.QueryBuilder.SelectValue)?.Bindings?.Cast() + ?.Select(it => it.Member.Name)?.ToList() ?? new List(); + var columns = entityColumnInfos; + //var parameterName = parameters[parameterIndex1]; + if (this.QueryBuilder.AutoAppendedColumns == null) + { + this.QueryBuilder.AutoAppendedColumns = new List(); + } + foreach (var item in columns) + { + if (item.IsIgnore == false && !this.QueryBuilder.AutoAppendedColumns.Contains(item.PropertyName) && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !list.Any(it => it.EqualCase(item.PropertyName))) + { + if (!sql.Contains($"{SqlBuilder.GetTranslationColumnName(parameterName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}") && + !sql.Contains($"{SqlBuilder.GetTranslationColumnName(parameterName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")) + { + sql = $" {sql},{SqlBuilder.GetTranslationColumnName(parameterName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; + this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName); + } + } + } + return sql; + } + + private string AppendSelectWithSubQuery(List entityColumnInfos, string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1) + { + var list = ExpressionTool.GetMemberInit(this.QueryBuilder.SelectValue).Bindings.Cast() + .Select(it => it.Member.Name).ToList(); + var columns = entityColumnInfos; + var parameterName = parameters[parameterIndex1]; + if (this.QueryBuilder.AutoAppendedColumns == null) + { + this.QueryBuilder.AutoAppendedColumns = new List(); + } + foreach (var item in columns) + { + if (item.IsIgnore == false && !this.QueryBuilder.AutoAppendedColumns.Contains(item.PropertyName) && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !list.Any(it => it.EqualCase(item.PropertyName))) + { + if (!sql.Contains($"{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}") && + !sql.Contains($"{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")) + { + + if (parameterIndex1 == 0 && this.QueryBuilder.JoinQueryInfos.Count != 0) + { + sql = $" {sql},{SqlBuilder.GetTranslationColumnName(this.QueryBuilder.TableShortName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; + this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName); + } + else + { + sql = $" {sql},{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; + this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName); + } + } + } + } + return sql; + } + + protected string AppendSelect(string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1) + { + var columns = this.Context.EntityMaintenance.GetEntityInfoWithAttr(typeof(EntityType)).Columns; + //var lowerSql = sql.ToLower(); + //var isSubquery = lowerSql.Contains("select ") && ExpressionTool.IsMemberInit(this.QueryBuilder.SelectValue); + //if (isSubquery) + //{ + return AppendSelectWithSubQuery(columns, sql, parameters, columnsResult, parameterIndex1, parameters[parameterIndex1].Name); + //} + //var parameterName = parameters[parameterIndex1].Name; + //if (parameterName.HasValue()) + //{ + // parameterName = this.SqlBuilder.GetTranslationColumnName(parameterName); + //} + //foreach (var item in columns) + //{ + // if (item.IsIgnore == false && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !sql.ToLower().Contains(SqlBuilder.GetTranslationColumnName(item.PropertyName).ToLower())) + // { + // if (!sql.Contains($"{parameterName}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")&& + // !sql.Contains($"{parameterName}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")) + // { + // sql = $" {sql},{parameterName}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; + // } + // } + //} + + //return sql; + } + + internal JoinQueryInfo GetJoinInfo(Expression joinExpression, JoinType joinType) + { + QueryBuilder.CheckExpressionNew(joinExpression, "Join"); + QueryBuilder.JoinExpression = joinExpression; + var express = LambdaExpression.Lambda(joinExpression).Body; + var lastPareamter = (express as LambdaExpression).Parameters.Last(); + var expResult = this.QueryBuilder.GetExpressionValue(joinExpression, ResolveExpressType.WhereMultiple); + this.Context.InitMappingInfo(lastPareamter.Type); + var result = new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinQueryInfos.Count, + JoinType = joinType, + JoinWhere = expResult.GetResultString(), + ShortName = lastPareamter.Name, + EntityType = lastPareamter.Type, + TableName = null + }; + if (QueryBuilder.IsCrossQueryWithAttr) + { + result.TableName = GetTableName(this.Context.EntityMaintenance.GetEntityInfoWithAttr(lastPareamter.Type), result.TableName); + } + else + { + result.TableName = this.Context.EntityMaintenance.GetTableName(lastPareamter.Type); + } + if (this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower == false) + { + result.ShortName = this.SqlBuilder.GetTranslationColumnName(result.ShortName); + } + if (this.EntityInfo.Type == result.EntityType && this.QueryBuilder?.AsTables?.Count == 1) + { + var tableName = this.QueryBuilder.AsTables.First().Value; + if (tableName.EndsWith(" MergeTable ") && tableName?.Trim() == this.QueryBuilder.GetTableNameString?.Trim()) + { + this.QueryBuilder.MasterDbTableName = " (SELECT * FROM " + tableName + ")"; + this.QueryBuilder.AsTables?.Clear(); + } + } + if (result.JoinIndex == 0) + { + var firstPareamter = (express as LambdaExpression).Parameters.First(); + this.QueryBuilder.TableShortName = firstPareamter.Name; + if (this.QueryBuilder.AsTables?.Count == 1) + { + var tableinfo = this.QueryBuilder.AsTables.First(); + if (this.QueryBuilder.TableWithString != SqlWith.Null && this.Context.CurrentConnectionConfig?.MoreSettings?.IsWithNoLockQuery == true && this.QueryBuilder.AsTables.First().Value.ObjToString().Contains(SqlWith.NoLock) == false) + { + if (this.QueryBuilder.AsTables.First().Value.EndsWith(") unionTable ")) + { + this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + this.QueryBuilder.AsTables.First().Value + ")"; + } + else if (this.QueryBuilder.AsTables.First().Value.EndsWith(") MergeTable ")) + { + this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + this.QueryBuilder.AsTables.First().Value + ")"; + } + else + { + this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + this.QueryBuilder.AsTables.First().Value + $" {SqlWith.NoLock} )"; + } + } + else if (this.QueryBuilder.IsSqlQuery && this.QueryBuilder.AsTables.First().Value.ObjToString().StartsWith('(')) + { + var tableName = this.QueryBuilder.AsTables.First().Value; + this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + tableName + ")" + this.QueryBuilder.TableShortName; + } + else + { + var tableName = this.QueryBuilder.AsTables.First().Value; + if (tableName != null && Regex.IsMatch(tableName.Replace(".", "").Replace("-", ""), @"^\w+$")) + { + tableName = SqlBuilder.GetTranslationTableName(tableName); + } + this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + tableName + ")"; + } + this.QueryBuilder.SelectValue = this.SqlBuilder.GetTranslationColumnName(this.QueryBuilder.TableShortName) + ".*"; + } + } + Check.Exception(result.JoinIndex > 10, ErrorMessage.GetThrowMessage("只支持12个表", "Only 12 tables are supported")); + return result; + } + protected ISugarQueryable _Select(Expression expression) + { + QueryBuilder.CheckExpression(expression, "Select"); + this.Context.InitMappingInfo(typeof(TResult)); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.Context = this.Context; + result.SqlBuilder = this.SqlBuilder; + result.SqlBuilder.QueryBuilder.Parameters = QueryBuilder.Parameters; + result.SqlBuilder.QueryBuilder.SelectValue = expression; + result.SqlBuilder.QueryBuilder.IsSelectSingleFiledJson = UtilMethods.IsJsonMember(expression, this.Context); + result.SqlBuilder.QueryBuilder.IsSelectSingleFiledArray = UtilMethods.IsArrayMember(expression, this.Context); + if (this.IsCache) + { + result.WithCache(this.CacheTime); + } + if (this.QueryBuilder.IsSqlQuery) + { + this.QueryBuilder.IsSqlQuerySelect = true; + } + return result; + } + protected void _Where(Expression expression) + { + QueryBuilder.CheckExpression(expression, "Where"); + var isSingle = QueryBuilder.IsSingle(); + var result = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); + QueryBuilder.WhereInfos.Add(SqlBuilder.AppendWhereOrAnd(QueryBuilder.WhereInfos.IsNullOrEmpty(), result.GetResultString())); + } + protected ISugarQueryable _OrderBy(Expression expression, OrderByType type = OrderByType.Asc) + { + QueryBuilder.CheckExpression(expression, "OrderBy"); + var isSingle = QueryBuilder.IsSingle(); + var member = ExpressionTool.RemoveConvert(ExpressionTool.GetLambdaExpressionBody(expression)) is MemberExpression; + if (member == false && expression.ToString().IsContainsIn("Desc(", "Asc(")) + { + var orderValue = ""; + var newExp = (expression as LambdaExpression).Body as NewExpression; + if (newExp == null) + { + orderValue = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString(); + return OrderBy(orderValue); + } + foreach (var item in newExp.Arguments) + { + if (item is MemberExpression) + { + orderValue += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + ","; + } + else + { + orderValue += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + ","; + } + } + orderValue = orderValue.TrimEnd(','); + OrderBy(orderValue); + return this; + } + else if ((expression as LambdaExpression).Body is NewExpression) + { + var newExp = (expression as LambdaExpression).Body as NewExpression; + var result = ""; + foreach (var item in newExp.Arguments) + { + if (item is MemberExpression && type == OrderByType.Asc) + { + result += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + ","; + } + else if (item is MemberExpression && type == OrderByType.Desc) + { + result += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + " Desc,"; + } + else if (type == OrderByType.Desc) + { + result += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + " Desc ,"; + } + else + { + result += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + ","; + } + } + result = result.TrimEnd(','); + OrderBy(result); + return this; + } + else + { + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + OrderBy(lamResult.GetResultString() + UtilConstants.Space + type.ToString().ToUpper()); + return this; + } + } + private void _ToOffsetPage(int pageIndex, int pageSize) + { + QueryBuilder.Offset = $" OFFSET {(pageIndex - 1) * pageSize} ROWS FETCH NEXT {pageSize} ROWS ONLY"; + } + private int _PageList(int pageIndex, int pageSize) + { + if (pageIndex == 0) + pageIndex = 1; + if (QueryBuilder.PartitionByValue.HasValue()) + { + QueryBuilder.ExternalPageIndex = pageIndex; + QueryBuilder.ExternalPageSize = pageSize; + } + else + { + QueryBuilder.Skip = (pageIndex - 1) * pageSize; + QueryBuilder.Take = pageSize; + } + + return pageIndex; + } + protected ISugarQueryable _GroupBy(Expression expression) + { + var oldParameterNames = this.QueryBuilder.Parameters?.Select(it => it.ParameterName) + ?.ToList(); + QueryBuilder.CheckExpression(expression, "GroupBy"); + LambdaExpression lambda = expression as LambdaExpression; + expression = lambda.Body; + var isSingle = QueryBuilder.IsSingle(); + ExpressionResult lamResult = null; + string result = null; + if (expression is NewExpression) + { + var newExp = expression as NewExpression; + foreach (var item in newExp.Arguments) + { + if (item is MemberExpression) + { + result += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + ","; + } + else + { + result += + QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + ","; + } + } + result = result.TrimEnd(','); + } + else + { + expression = ExpressionTool.RemoveConvert(expression); + lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + result = lamResult.GetResultString(); + } + if (oldParameterNames != null && this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + var newParas = this.QueryBuilder.Parameters.Where(it => !oldParameterNames.Contains(it.ParameterName)).ToList(); + this.QueryBuilder.GroupParameters = newParas; + var groupBySql = UtilMethods.GetSqlString(DbType.SqlServer, result, newParas.ToArray()); + this.QueryBuilder.GroupBySql = groupBySql; + this.QueryBuilder.GroupBySqlOld = result; + GroupBy(result); + } + else + { + GroupBy(result); + } + return this; + } + protected ISugarQueryable _As(string tableName, string entityName) + { + if (this.QueryBuilder.AsTables?.Any(it => it.Key == entityName) == true) + { + if (this.QueryBuilder.JoinQueryInfos.Count(it => it.TableName.EqualCase(tableName)) > 1) + { + Check.ExceptionEasy($"if same entity name ,.LeftJoin(db.Queryable<{entityName}>,(x,y..)=>....).As(\"{tableName}\")", $"存在相同实体,请使用.LeftJoin(db.Queryable<{entityName}>).As(\"{tableName}\",(x,y..)=>...)"); + } + Check.Exception(true, ErrorMessage.GetThrowMessage($"use As<{tableName}>(\"{tableName}\")", $"请把 As(\"{tableName}\"), 改成 As<{tableName}实体>(\"{tableName}\")")); + } + else + { + this.QueryBuilder.AsTables.Add(entityName, tableName); + } + return this; + } + protected void _Filter(string FilterName, bool isDisabledGobalFilter) + { + QueryBuilder.IsDisabledGobalFilter = isDisabledGobalFilter; + if (this.Context.QueryFilter.GetFilterList.HasValue() && FilterName.HasValue()) + { + var list = this.Context.QueryFilter.GetFilterList.Where(it => it.FilterName == FilterName && it.IsJoinQuery == !QueryBuilder.IsSingle()); + foreach (var item in list) + { + var filterResult = item.FilterValue(this.Context); + Where(filterResult.Sql + UtilConstants.Space, filterResult.Parameters); + } + } + } + public ISugarQueryable _PartitionBy(Expression expression) + { + QueryBuilder.CheckExpression(expression, "PartitionBy"); + LambdaExpression lambda = expression as LambdaExpression; + expression = lambda.Body; + var isSingle = QueryBuilder.IsSingle(); + ExpressionResult lamResult = null; + string result = null; + if (expression is NewExpression) + { + lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.ArraySingle : ResolveExpressType.ArrayMultiple); + result = string.Join(",", lamResult.GetResultArray()); + } + else + { + lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + result = lamResult.GetResultString(); + } + PartitionBy(result); + return this; + } + protected ISugarQueryable _Having(Expression expression) + { + QueryBuilder.CheckExpression(expression, "Having"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); + Having(lamResult.GetResultString()); + return this; + } + protected List _ToList() + { + List result = null; + var sqlObj = this._ToSql(); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate>(cacheService, this.QueryBuilder, () => { return GetData(sqlObj); }, CacheTime, this.Context, CacheKey); + } + else + { + result = GetData(sqlObj); + } + RestoreMapping(); + _InitNavigat(result); + _SubQuery(result); + _Mapper(result); + return result; + } + + + + protected async Task> _ToListAsync() + { + List result = null; + var sqlObj = this._ToSql(); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate>(cacheService, this.QueryBuilder, () => { return GetData(sqlObj); }, CacheTime, this.Context, CacheKey); + } + else + { + result = await GetDataAsync(sqlObj).ConfigureAwait(false); + } + RestoreMapping(); + await _InitNavigatAsync(result).ConfigureAwait(false); + await _SubQueryAsync(result).ConfigureAwait(false); + _Mapper(result); + return result; + } + private void ToSqlBefore() + { + var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; + if (moreSetts?.IsWithNoLockQuery == true && string.IsNullOrEmpty(QueryBuilder.TableWithString)) + { + if (moreSetts.DisableWithNoLockWithTran && this.Context.Ado.IsAnyTran()) + { + //No With(nolock) + } + else + { + this.With(SqlWith.NoLock); + } + } + } + protected List GetData(KeyValuePair> sqlObj) + { + List result; + var isComplexModel = QueryBuilder.IsComplexModel(sqlObj.Key); + var entityType = typeof(TResult); + bool isChangeQueryableSlave = GetIsSlaveQuery(); + bool isChangeQueryableMasterSlave = GetIsMasterQuery(); + string sqlString = sqlObj.Key; + SugarParameter[] parameters = sqlObj.Value.ToArray(); + var dataReader = this.Db.GetDataReader(sqlString, parameters); + this.Db.GetDataBefore(sqlString, parameters); + if (entityType.IsInterface) + { + result = GetData(isComplexModel, this.QueryBuilder.AsType, dataReader); + } + else + { + result = GetData(isComplexModel, entityType, dataReader); + } + this.Db.GetDataAfter(sqlString, parameters); + RestChangeMasterQuery(isChangeQueryableMasterSlave); + RestChangeSlaveQuery(isChangeQueryableSlave); + return result; + } + protected async Task> GetDataAsync(KeyValuePair> sqlObj) + { + List result; + var isComplexModel = QueryBuilder.IsComplexModel(sqlObj.Key); + var entityType = typeof(TResult); + bool isChangeQueryableSlave = GetIsSlaveQuery(); + bool isChangeQueryableMasterSlave = GetIsMasterQuery(); + string sqlString = sqlObj.Key; + SugarParameter[] parameters = sqlObj.Value.ToArray(); + var dataReader = await Db.GetDataReaderAsync(sqlString, parameters).ConfigureAwait(false); + this.Db.GetDataBefore(sqlString, parameters); + if (entityType.IsInterface) + { + result = await GetDataAsync(isComplexModel, QueryBuilder.AsType, dataReader).ConfigureAwait(false); + } + else + { + result = await GetDataAsync(isComplexModel, entityType, dataReader).ConfigureAwait(false); + } + this.Db.GetDataAfter(sqlString, parameters); + RestChangeMasterQuery(isChangeQueryableMasterSlave); + RestChangeSlaveQuery(isChangeQueryableSlave); + return result; + } + private List GetData(bool isComplexModel, Type entityType, IDataReader dataReader) + { + List result; + this.Bind.QueryBuilder = this.QueryBuilder; + this.Context.Utilities.QueryBuilder = this.QueryBuilder; + if (entityType == UtilConstants.DynamicType) + { + result = this.Context.Utilities.DataReaderToExpandoObjectList(dataReader) as List; + } + else if (entityType.Name?.StartsWith("ValueTuple`") == true) + { + result = Db.Context.Utilities.DataReaderToValueTupleType(dataReader); + } + else if (entityType == UtilConstants.ObjType) + { + result = this.Context.Utilities.DataReaderToExpandoObjectList(dataReader).Select(it => ((TResult)(object)it)).ToList(); + } + else if (QueryBuilder.IsSelectSingleFiledJson) + { + result = this.Context.Utilities.DataReaderToSelectJsonList(dataReader); + } + else if (QueryBuilder.IsSelectSingleFiledArray) + { + result = this.Context.Utilities.DataReaderToSelectArrayList(dataReader); + } + else if (QueryBuilder.IsParameterizedConstructor || entityType.IsAnonymousType() || isComplexModel || StaticConfig.EnableAot) + { + if (entityType.IsClass() == false && StaticConfig.EnableAot) + { + result = this.Bind.DataReaderToList(entityType, dataReader); + } + else + { + result = this.Context.Utilities.DataReaderToList(dataReader); + if (StaticConfig.EnableAot) + ResetNavigationPropertiesForAot(result); + } + } + else + { + result = this.Bind.DataReaderToList(entityType, dataReader); + } + SetContextModel(result, entityType); + return result; + } + private async Task> GetDataAsync(bool isComplexModel, Type entityType, IDataReader dataReader) + { + List result; + this.Bind.QueryBuilder = this.QueryBuilder; + this.Context.Utilities.QueryBuilder = this.QueryBuilder; + if (entityType == UtilConstants.DynamicType) + { + result = await Context.Utilities.DataReaderToExpandoObjectListAsync(dataReader).ConfigureAwait(false) as List; + } + else if (entityType.Name?.StartsWith("ValueTuple`") == true) + { + result = await Db.Context.Utilities.DataReaderToValueTupleTypeAsync(dataReader).ConfigureAwait(false); + } + else if (entityType == UtilConstants.ObjType) + { + var expObj = await Context.Utilities.DataReaderToExpandoObjectListAsync(dataReader).ConfigureAwait(false); + result = expObj.Select(it => ((TResult)(object)it)).ToList(); + } + else if (QueryBuilder.IsSelectSingleFiledJson) + { + result = await Context.Utilities.DataReaderToSelectJsonListAsync(dataReader).ConfigureAwait(false); + } + else if (QueryBuilder.IsSelectSingleFiledArray) + { + result = await Context.Utilities.DataReaderToSelectArrayListAsync(dataReader).ConfigureAwait(false); + } + else if (entityType.IsAnonymousType() || isComplexModel || StaticConfig.EnableAot) + { + if (entityType.IsClass() == false && StaticConfig.EnableAot) + { + result = await Bind.DataReaderToListAsync(entityType, dataReader).ConfigureAwait(false); + } + else + { + result = await Context.Utilities.DataReaderToListAsync(dataReader).ConfigureAwait(false); + if (StaticConfig.EnableAot) + ResetNavigationPropertiesForAot(result); + } + } + else + { + result = await Bind.DataReaderToListAsync(entityType, dataReader).ConfigureAwait(false); + } + SetContextModel(result, entityType); + return result; + } + private void ResetNavigationPropertiesForAot(List result) + { + if (StaticConfig.EnableAot) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + var navColumnList = entityInfo.Columns.Where(it => it.Navigat != null); + if (navColumnList.Any()) + { + foreach (var item in result) + { + foreach (var columnInfo in navColumnList) + { + columnInfo.PropertyInfo.SetValue(item, null); + } + } + } + } + } + protected void _InQueryable(Expression expression, KeyValuePair> sqlObj) + { + QueryBuilder.CheckExpression(expression, "In"); + string sql = sqlObj.Key; + if (sqlObj.Value.HasValue()) + { + this.SqlBuilder.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), 100); + this.QueryBuilder.Parameters.AddRange(sqlObj.Value); + } + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + var whereSql = string.Format(this.QueryBuilder.InTemplate, fieldName, sql); + this.QueryBuilder.WhereInfos.Add(SqlBuilder.AppendWhereOrAnd(this.QueryBuilder.WhereInfos.IsNullOrEmpty(), whereSql)); + base._InQueryableIndex += 100; + } + protected List GetPrimaryKeys() + { + + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + protected virtual List GetIdentityKeys() + { + return this.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); + } + protected void CopyQueryBuilder(QueryBuilder asyncQueryableBuilder) + { + var pars = new List(); + if (this.QueryBuilder.Parameters != null) + { + pars = this.QueryBuilder.Parameters.Select(it => new SugarParameter(it.ParameterName, it.Value) + { + DbType = it.DbType, + Value = it.Value, + ParameterName = it.ParameterName, + Direction = it.Direction, + IsArray = it.IsArray, + IsJson = it.IsJson, + IsNullable = it.IsNullable, + IsRefCursor = it.IsRefCursor, + Size = it.Size, + SourceColumn = it.SourceColumn, + SourceColumnNullMapping = it.SourceColumnNullMapping, + SourceVersion = it.SourceVersion, + TempDate = it.TempDate, + TypeName = it.TypeName, + UdtTypeName = it.UdtTypeName, + IsNvarchar2 = it.IsNvarchar2, + _Size = it._Size + }).ToList(); + } + asyncQueryableBuilder.IsEnableMasterSlaveSeparation = this.QueryBuilder.IsEnableMasterSlaveSeparation; + asyncQueryableBuilder.TranLock = this.QueryBuilder.TranLock; + asyncQueryableBuilder.IsDisableMasterSlaveSeparation = this.QueryBuilder.IsDisableMasterSlaveSeparation; + asyncQueryableBuilder.IsQueryInQuery = this.QueryBuilder.IsQueryInQuery; + asyncQueryableBuilder.Includes = this.QueryBuilder.Includes; + asyncQueryableBuilder.Take = this.QueryBuilder.Take; + asyncQueryableBuilder.Skip = this.QueryBuilder.Skip; + asyncQueryableBuilder.SelectValue = this.QueryBuilder.SelectValue; + asyncQueryableBuilder.WhereInfos = this.Context.Utilities.TranslateCopy(this.QueryBuilder.WhereInfos); + asyncQueryableBuilder.EasyJoinInfos = this.Context.Utilities.TranslateCopy(this.QueryBuilder.EasyJoinInfos); + asyncQueryableBuilder.JoinQueryInfos = QueryBuilder.JoinQueryInfos.Select(it => CopyJoinInfo(it)).ToList(); + asyncQueryableBuilder.WhereIndex = this.QueryBuilder.WhereIndex; + asyncQueryableBuilder.EntityType = this.QueryBuilder.EntityType; + asyncQueryableBuilder.EntityName = this.QueryBuilder.EntityName; + asyncQueryableBuilder.Parameters = pars; + asyncQueryableBuilder.TableShortName = this.QueryBuilder.TableShortName; + asyncQueryableBuilder.TableWithString = this.QueryBuilder.TableWithString; + asyncQueryableBuilder.GroupByValue = this.QueryBuilder.GroupByValue; + asyncQueryableBuilder.IsDistinct = this.QueryBuilder.IsDistinct; + asyncQueryableBuilder.OrderByValue = this.QueryBuilder.OrderByValue; + asyncQueryableBuilder.IsDisabledGobalFilter = this.QueryBuilder.IsDisabledGobalFilter; + asyncQueryableBuilder.PartitionByValue = this.QueryBuilder.PartitionByValue; + asyncQueryableBuilder.JoinExpression = this.QueryBuilder.JoinExpression; + asyncQueryableBuilder.WhereIndex = this.QueryBuilder.WhereIndex; + asyncQueryableBuilder.HavingInfos = this.QueryBuilder.HavingInfos; + asyncQueryableBuilder.AsType = this.QueryBuilder.AsType; + asyncQueryableBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + asyncQueryableBuilder.IgnoreColumns = this.Context.Utilities.TranslateCopy(this.QueryBuilder.IgnoreColumns); + asyncQueryableBuilder.AsTables = this.Context.Utilities.TranslateCopy(this.QueryBuilder.AsTables); + asyncQueryableBuilder.DisableTop = this.QueryBuilder.DisableTop; + asyncQueryableBuilder.Offset = this.QueryBuilder.Offset; + asyncQueryableBuilder.IsSqlQuery = this.QueryBuilder.IsSqlQuery; + asyncQueryableBuilder.IsSqlQuerySelect = this.QueryBuilder.IsSqlQuerySelect; + asyncQueryableBuilder.OldSql = this.QueryBuilder.OldSql; + asyncQueryableBuilder.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; + asyncQueryableBuilder.CrossQueryItems = this.QueryBuilder.CrossQueryItems; + asyncQueryableBuilder.SubToListParameters = this.Context.Utilities.TranslateCopy(this.QueryBuilder.SubToListParameters); + asyncQueryableBuilder.AppendColumns = this.Context.Utilities.TranslateCopy(this.QueryBuilder.AppendColumns); + asyncQueryableBuilder.AppendValues = this.Context.Utilities.TranslateCopy(this.QueryBuilder.AppendValues); + asyncQueryableBuilder.RemoveFilters = this.QueryBuilder.RemoveFilters?.ToArray(); + asyncQueryableBuilder.Hints = this.QueryBuilder.Hints; + asyncQueryableBuilder.MasterDbTableName = this.QueryBuilder.MasterDbTableName; + asyncQueryableBuilder.IsParameterizedConstructor = this.QueryBuilder.IsParameterizedConstructor; + asyncQueryableBuilder.GroupParameters = this.QueryBuilder.GroupParameters; + asyncQueryableBuilder.GroupBySql = this.QueryBuilder.GroupBySql; + asyncQueryableBuilder.GroupBySqlOld = this.QueryBuilder.GroupBySqlOld; + if (this.QueryBuilder.AppendNavInfo != null) + { + asyncQueryableBuilder.AppendNavInfo = new AppendNavInfo() + { + AppendProperties = this.QueryBuilder.AppendNavInfo.AppendProperties.ToDictionary(it => it.Key, it => it.Value), + MappingNavProperties = this.QueryBuilder.AppendNavInfo.MappingNavProperties.ToDictionary(it => it.Key, it => it.Value) + }; + } + } + + private static JoinQueryInfo CopyJoinInfo(JoinQueryInfo it) + { + return new JoinQueryInfo() + { + EntityType = it.EntityType, + JoinIndex = it.JoinIndex, + JoinType = it.JoinType, + JoinWhere = it.JoinWhere, + ShortName = it.ShortName, + TableName = it.TableName + }; + } + + protected int SetCacheTime(int cacheDurationInSeconds) + { + if (cacheDurationInSeconds == int.MaxValue && this.Context.CurrentConnectionConfig.MoreSettings?.DefaultCacheDurationInSeconds > 0) + { + cacheDurationInSeconds = this.Context.CurrentConnectionConfig.MoreSettings.DefaultCacheDurationInSeconds; + } + + return cacheDurationInSeconds; + } + public virtual KeyValuePair> _ToSql() + { + InitMapping(); + ToSqlBefore(); + string sql = QueryBuilder.ToSqlString(); + RestoreMapping(); + return new KeyValuePair>(sql, QueryBuilder.Parameters); + } + #endregion + + #region Subquery + private bool IsSubToList() + { + return this.QueryBuilder.SubToListParameters?.Count > 0; + } + + public virtual ISugarQueryable MergeTableWithSubToListJoin() + { + //_ToSql(); + var clone = this.Clone(); + + clone.QueryBuilder.AppendValues = null; + clone.QueryBuilder.SubToListParameters = null; + clone.QueryBuilder.AppendColumns = null; + Check.Exception(this.MapperAction != null || this.MapperActionWithCache != null, ErrorMessage.GetThrowMessage("'Mapper’ needs to be written after ‘MergeTable’ ", "Mapper 只能在 MergeTable 之后使用")); + //Check.Exception(this.QueryBuilder.SelectValue.IsNullOrEmpty(),ErrorMessage.GetThrowMessage( "MergeTable need to use Queryable.Select Method .", "使用MergeTable之前必须要有Queryable.Select方法")); + //Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0 || this.QueryBuilder.OrderByValue.HasValue(),ErrorMessage.GetThrowMessage( "MergeTable Queryable cannot Take Skip OrderBy PageToList ", "使用 MergeTable不能有 Take Skip OrderBy PageToList 等操作,你可以在Mergetable之后操作")); + var sqlobj = clone.ToSql(); + var index = QueryBuilder.WhereIndex + 1; + var result = this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); + result.QueryBuilder.WhereIndex = index; + result.QueryBuilder.LambdaExpressions.ParameterIndex = QueryBuilder.LambdaExpressions.ParameterIndex++; + result.QueryBuilder.LambdaExpressions.Index = QueryBuilder.LambdaExpressions.Index++; + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + result.Select("MergeTable.*"); + } + result.QueryBuilder.AppendValues = this.QueryBuilder.AppendValues; + result.QueryBuilder.SubToListParameters = this.QueryBuilder.SubToListParameters; + result.QueryBuilder.AppendColumns = this.QueryBuilder.AppendColumns; + return result; + } + public virtual ISugarQueryable MergeTableWithSubToList() + { + _ToSql(); + var clone = this.Clone(); + + clone.QueryBuilder.AppendValues = null; + clone.QueryBuilder.SubToListParameters = null; + clone.QueryBuilder.AppendColumns = null; + Check.Exception(this.MapperAction != null || this.MapperActionWithCache != null, ErrorMessage.GetThrowMessage("'Mapper’ needs to be written after ‘MergeTable’ ", "Mapper 只能在 MergeTable 之后使用")); + //Check.Exception(this.QueryBuilder.SelectValue.IsNullOrEmpty(),ErrorMessage.GetThrowMessage( "MergeTable need to use Queryable.Select Method .", "使用MergeTable之前必须要有Queryable.Select方法")); + //Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0 || this.QueryBuilder.OrderByValue.HasValue(),ErrorMessage.GetThrowMessage( "MergeTable Queryable cannot Take Skip OrderBy PageToList ", "使用 MergeTable不能有 Take Skip OrderBy PageToList 等操作,你可以在Mergetable之后操作")); + var sqlobj = clone.ToSql(); + var index = QueryBuilder.WhereIndex + 1; + var result = this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); + result.QueryBuilder.WhereIndex = index; + result.QueryBuilder.LambdaExpressions.ParameterIndex = QueryBuilder.LambdaExpressions.ParameterIndex++; + result.QueryBuilder.LambdaExpressions.Index = QueryBuilder.LambdaExpressions.Index++; + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + result.Select("MergeTable.*"); + } + result.QueryBuilder.AppendValues = this.QueryBuilder.AppendValues; + result.QueryBuilder.SubToListParameters = this.QueryBuilder.SubToListParameters; + result.QueryBuilder.AppendColumns = this.QueryBuilder.AppendColumns; + return result; + } + + private void _SubQuery(List result) + { + if (result == null || result.Count == 0) + { + return; + } + var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Count != 0; + if (!isSubToList) + { + return; + } + var appendValues = this.QueryBuilder.AppendValues; + var subParamters = this.QueryBuilder.SubToListParameters; + foreach (var subPara in subParamters) + { + if (appendValues != null) + AppendSubWhereToList(result, appendValues, subPara); + else + AppendSubToList(result, appendValues, subPara); + } + + } + + private void AppendSubToList(List result, List> appendValues, KeyValuePair subPara) + { + var ps = this.QueryBuilder.Parameters; + var itemProperty = typeof(TResult).GetProperty(subPara.Key); + var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault(); + var isFirst = false; + if (callType == null) + { + callType = itemProperty.PropertyType; + isFirst = true; + } + var sql = subPara.Value.ObjToString().Replace("@sugarIndex", "0"); + sql = SqlBuilder.RemoveParentheses(sql); + var methodParamters = new object[] { sql, ps }; + var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList"); + for (var i = 0; i < result.Count; i++) + { + var item = result[i]; + var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList; + if (typeof(TResult).IsAnonymousType()) + { + if (isFirst) + { + var jobj = JObject.FromObject(item); + var prop = jobj.Property(itemProperty.Name); + prop.Value = JObject.FromObject((subList as IList).Cast().FirstOrDefault()); + result[i] = jobj.ToObject(); + } + else + { + var jobj = JObject.FromObject(item); + var prop = jobj.Property(itemProperty.Name); + prop.Value = JArray.FromObject(subList); + result[i] = jobj.ToObject(); + } + } + else + { + if (isFirst) + { + if ((subList as IList).Count > 0) + { + itemProperty.SetValue(item, (subList as IList)[0]); + } + } + else + { + itemProperty.SetValue(item, subList); + } + } + } + } + + private void AppendSubWhereToList(List result, List> appendValues, KeyValuePair subPara) + { + var ps = this.QueryBuilder.Parameters; + var index = 0; + List sqls = new List(); + foreach (var item in result) + { + + var sql = subPara.Value.ObjToString(); + var replaceValues = appendValues[index]; + foreach (var re in replaceValues) + { + var config = this.Context.CurrentConnectionConfig; + var p = new SugarParameter[] { + new SugarParameter("@p",re.Value) + }; + var isNvarchar = true; + if (this.Context.CurrentConnectionConfig?.DbType == DbType.SqlServer + && this.Context.CurrentConnectionConfig?.MoreSettings?.DisableNvarchar != true) + { + isNvarchar = false; + } + var value = UtilMethods.GetSqlString(config.DbType, "@p", p, isNvarchar); + sql = sql.Replace(re.Name, value); + + } + sql = SqlBuilder.RemoveParentheses(sql); + sql = sql.Replace("@sugarIndex", index + ""); + sqls.Add(sql); + + index++; + } + var itemProperty = typeof(TResult).GetProperty(subPara.Key); + var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault(); + var isFirst = false; + if (callType == null) + { + callType = itemProperty.PropertyType; + isFirst = true; + } + var sqlstring = string.Join(" \r\n UNION ALL ", sqls); + if (callType?.IsClass() == false) + { + Regex regex = new Regex(@"\,\d{1,10} as sugarIndex"); + sqlstring = regex.Replace(sqlstring, it => (" as id " + it.Value)); + callType = typeof(SubQueryToListDefaultT); + } + var methodParamters = new object[] { sqlstring, ps.ToArray() }; + this.QueryBuilder.SubToListParameters = null; + this.QueryBuilder.AppendColumns = new List() { + new QueryableAppendColumn(){ Name="sugarIndex",AsName="sugarIndex" } + }; + this.QueryBuilder.AppendValues = null; + var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList"); + var appendValue = this.QueryBuilder.AppendValues; + var list = (subList as IEnumerable).Cast().ToList(); + if (isFirst && !typeof(TResult).IsAnonymousType()) + { + SetSubListWithClassFirst(result, itemProperty, appendValue, list, 0); + } + else if (isFirst && typeof(TResult).IsAnonymousType()) + { + SetSubListWithAnonymousTypeFirst(result, itemProperty, appendValue, list, 0); + } + else if (typeof(TResult).IsAnonymousType()) + { + SetSubListWithAnonymousType(result, itemProperty, appendValue, list, 0); + } + else + { + SetSubListWithClass(result, itemProperty, appendValue, list, 0); + } + } + private static int SetSubListWithAnonymousType(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) + { + for (int i = 0; i < result.Count; i++) + { + var item = result[i]; + var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList; + if (appendValue != null) + { + var appindex = 0; + foreach (var appValue in appendValue) + { + if (appValue[0].Value.ObjToInt() == i) + { + var addItem = list[appindex]; + if (addItem is SubQueryToListDefaultT) + { + addItem = (addItem as SubQueryToListDefaultT).id; + } + setValue.Add(addItem); + } + appindex++; + } + } + var jobj = JObject.FromObject(item); + var prop = jobj.Property(itemProperty.Name); + prop.Value = JArray.FromObject(setValue); + result[i] = jobj.ToObject(); + //itemProperty.SetValue(item, setValue); + } + return resIndex; + } + private static int SetSubListWithAnonymousTypeFirst(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) + { + for (int i = 0; i < result.Count; i++) + { + var item = result[i]; + object setValue = null; + if (appendValue != null) + { + var appindex = 0; + foreach (var appValue in appendValue) + { + if (appValue[0].Value.ObjToInt() == i) + { + setValue = list[appindex]; + //setValue.Add(addItem); + } + appindex++; + } + } + var jobj = JObject.FromObject(item); + var prop = jobj.Property(itemProperty.Name); + if (setValue != null) + { + prop.Value = JObject.FromObject(setValue); + } + result[i] = jobj.ToObject(); + //itemProperty.SetValue(item, setValue); + } + return resIndex; + } + private static int SetSubListWithClassFirst(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) + { + foreach (var item in result) + { + //var setValue = Activator.CreateInstance(itemProperty.PropertyType, true); + if (appendValue != null) + { + var appindex = 0; + foreach (var appValue in appendValue) + { + if (appValue[0].Value.ObjToInt() == resIndex) + { + var addItem = list[appindex]; + itemProperty.SetValue(item, addItem); + } + appindex++; + } + } + //itemProperty.SetValue(item, setValue); + resIndex++; + } + + return resIndex; + } + + private static int SetSubListWithClass(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) + { + foreach (var item in result) + { + var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList; + if (appendValue != null) + { + var appindex = 0; + foreach (var appValue in appendValue) + { + if (appValue[0].Value.ObjToInt() == resIndex) + { + var addItem = list[appindex]; + if (addItem is SubQueryToListDefaultT) + { + addItem = ((SubQueryToListDefaultT)addItem).id; + } + if (addItem != null && addItem is string && itemProperty?.PropertyType?.GenericTypeArguments?.FirstOrDefault() == UtilConstants.GuidType) + { + addItem = Guid.Parse(addItem + ""); + } + setValue.Add(addItem); + } + appindex++; + } + } + itemProperty.SetValue(item, setValue); + resIndex++; + } + + return resIndex; + } + + private async Task _SubQueryAsync(List result) + { + var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Count != 0; + if (!isSubToList) + { + return; + } + await Task.Run(() => { _SubQuery(result); }).ConfigureAwait(false); + } + public List SubQueryList(string sql, object parameters) + { + return this.Context.Ado.SqlQuery(sql, parameters); + } + #endregion + + #region Bool + + private bool MasterHasWhereFirstJoin() + { + if (this.QueryBuilder.IsSingle() == false && this.QueryBuilder.SelectValue is LambdaExpression exp && this.QueryBuilder.AsTables?.Count == 0) + { + if (exp.Parameters.Count == this.QueryBuilder.JoinQueryInfos.Count + 1) + { + return true; + } + } + return this.QueryBuilder.JoinIndex == 0 && + this.QueryBuilder.IsSqlQuery == false && + this.QueryBuilder.AsTables.Count == 0 && + this.QueryBuilder.IsSingle() && + (this.QueryBuilder.WhereInfos.Count != 0 || this.QueryBuilder.SelectValue is Expression); + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProperties.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProperties.cs new file mode 100644 index 000000000..d613a6395 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProperties.cs @@ -0,0 +1,21 @@ +namespace SqlSugar +{ + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public SqlSugarProvider Context { get; set; } + public IAdo Db { get { return Context.Ado; } } + public IDbBind Bind { get { return this.Db.DbBind; } } + public ISqlBuilder SqlBuilder { get; set; } + public MappingTableList OldMappingTableList { get; set; } + public MappingTableList QueryableMappingTableList { get; set; } + public List> MapperAction { get; set; } + public Action> MapperActionWithCache { get; set; } + public List>> Mappers { get; set; } + public bool IsCache { get; set; } + public int CacheTime { get; set; } + public string CacheKey { get; set; } + public bool IsAs { get; set; } + public QueryBuilder QueryBuilder { get { return this.SqlBuilder.QueryBuilder; } set { this.SqlBuilder.QueryBuilder = value; } } + public EntityInfo EntityInfo { get { return this.Context.EntityMaintenance.GetEntityInfo(); } } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider.cs new file mode 100644 index 000000000..e1ff14a8e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -0,0 +1,1830 @@ +using System.Collections; +using System.Data; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + + public ISugarQueryable CrossQuery(string configId) + { + return this.CrossQuery(typeof(Type), configId); + } + public ISugarQueryable CrossQuery(Type type, string configId) + { + if (this.QueryBuilder.CrossQueryItems == null) + { + this.QueryBuilder.CrossQueryItems = new Dictionary(); + } + QueryBuilder.CrossQueryItems.TryAdd(type.FullName, configId); + return this; + } + public ISugarQueryable IncludeLeftJoin(Expression> leftObjectExp) + { + MemberExpression memberExpression; + string navObjectName; + EntityColumnInfo navColumn, navPkColumn; + EntityInfo navEntityInfo; + ExpressionTool.GetOneToOneInfo(this.Context, leftObjectExp, out memberExpression, out navObjectName, out navColumn, out navEntityInfo, out navPkColumn); + var shortName = $"pnv_{navObjectName}"; + var mainShortName = memberExpression.Expression.ToString(); + this.QueryBuilder.TableShortName = mainShortName; + var onWhere = $"{SqlBuilder.GetTranslationColumnName(shortName)}.{SqlBuilder.GetTranslationColumnName(navPkColumn.DbColumnName)}={SqlBuilder.GetTranslationColumnName(mainShortName)}.{SqlBuilder.GetTranslationColumnName(navColumn.DbColumnName)}"; + UtilMethods.IsNullReturnNew(this.Context.TempItems); + this.AddJoinInfo(GetTableName(navEntityInfo, navEntityInfo.DbTableName), shortName, onWhere, JoinType.Left); + this.QueryBuilder.JoinQueryInfos.Last().EntityType = navEntityInfo.Type; + return this; + } + public ISugarQueryable IncludeInnerJoin(Expression> innerObjectExt) + { + MemberExpression memberExpression; + string navObjectName; + EntityColumnInfo navColumn, navPkColumn; + EntityInfo navEntityInfo; + ExpressionTool.GetOneToOneInfo(this.Context, innerObjectExt, out memberExpression, out navObjectName, out navColumn, out navEntityInfo, out navPkColumn); + var shortName = $"pnv_{navObjectName}"; + var mainShortName = memberExpression.Expression.ToString(); + this.QueryBuilder.TableShortName = mainShortName; + var onWhere = $"{SqlBuilder.GetTranslationColumnName(shortName)}.{SqlBuilder.GetTranslationColumnName(navPkColumn.DbColumnName)}={SqlBuilder.GetTranslationColumnName(mainShortName)}.{SqlBuilder.GetTranslationColumnName(navColumn.DbColumnName)}"; + UtilMethods.IsNullReturnNew(this.Context.TempItems); + this.AddJoinInfo(GetTableName(navEntityInfo, navEntityInfo.DbTableName), shortName, onWhere, JoinType.Inner); + this.QueryBuilder.JoinQueryInfos.Last().EntityType = navEntityInfo.Type; + return this; + } + public ISugarQueryable IncludeFullJoin(Expression> fullObjectExp) + { + MemberExpression memberExpression; + string navObjectName; + EntityColumnInfo navColumn, navPkColumn; + EntityInfo navEntityInfo; + ExpressionTool.GetOneToOneInfo(this.Context, fullObjectExp, out memberExpression, out navObjectName, out navColumn, out navEntityInfo, out navPkColumn); + var shortName = $"pnv_{navObjectName}"; + var mainShortName = memberExpression.Expression.ToString(); + this.QueryBuilder.TableShortName = mainShortName; + var onWhere = $"{SqlBuilder.GetTranslationColumnName(shortName)}.{SqlBuilder.GetTranslationColumnName(navPkColumn.DbColumnName)}={SqlBuilder.GetTranslationColumnName(mainShortName)}.{SqlBuilder.GetTranslationColumnName(navColumn.DbColumnName)}"; + UtilMethods.IsNullReturnNew(this.Context.TempItems); + this.AddJoinInfo(GetTableName(navEntityInfo, navEntityInfo.DbTableName), shortName, onWhere, JoinType.Full); + this.QueryBuilder.JoinQueryInfos.Last().EntityType = navEntityInfo.Type; + return this; + } + public ISugarQueryable IncludeRightJoin(Expression> rightObjectExp) + { + MemberExpression memberExpression; + string navObjectName; + EntityColumnInfo navColumn, navPkColumn; + EntityInfo navEntityInfo; + ExpressionTool.GetOneToOneInfo(this.Context, rightObjectExp, out memberExpression, out navObjectName, out navColumn, out navEntityInfo, out navPkColumn); + var shortName = $"pnv_{navObjectName}"; + var mainShortName = memberExpression.Expression.ToString(); + this.QueryBuilder.TableShortName = mainShortName; + var onWhere = $"{SqlBuilder.GetTranslationColumnName(shortName)}.{SqlBuilder.GetTranslationColumnName(navPkColumn.DbColumnName)}={SqlBuilder.GetTranslationColumnName(mainShortName)}.{SqlBuilder.GetTranslationColumnName(navColumn.DbColumnName)}"; + UtilMethods.IsNullReturnNew(this.Context.TempItems); + this.AddJoinInfo(GetTableName(navEntityInfo, navEntityInfo.DbTableName), shortName, onWhere, JoinType.Right); + this.QueryBuilder.JoinQueryInfos.Last().EntityType = navEntityInfo.Type; + return this; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().LeftJoin(joinQueryable, joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().InnerJoin(joinQueryable, joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().RightJoin(joinQueryable, joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable FullJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().FullJoin(joinQueryable, joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Full); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var oldAsName = this.QueryBuilder.AsTables?.ToDictionary(it => it.Key, it => it.Value); + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + result.QueryBuilder.AsTables = oldAsName; + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var oldAsName = this.QueryBuilder.AsTables?.ToDictionary(it => it.Key, it => it.Value); + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + result.QueryBuilder.AsTables = oldAsName; + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().LeftJoin(joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + this.QueryBuilder.IsSqlQuery = false; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().FullJoin(joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().RightJoin(joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + + if (MasterHasWhereFirstJoin()) + { + return this.MergeTable().InnerJoin(joinExpression); + } + + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public void Clear() + { + QueryBuilder.Clear(); + } + public ISugarQueryable IgnoreColumns(Expression> columns) + { + var ignoreColumns = QueryBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it).ToLower()).ToList(); + return IgnoreColumns(ignoreColumns.ToArray()); + } + public ISugarQueryable IgnoreColumns(params string[] columns) + { + if (QueryBuilder.IgnoreColumns.IsNullOrEmpty()) + { + QueryBuilder.IgnoreColumns = new List(); + } + QueryBuilder.IgnoreColumns.AddRange(columns); + return this; + } + public void AddQueue() + { + var sqlObj = this.ToSql(); + this.Context.Queues.Add(sqlObj.Key, sqlObj.Value); + } + public ISugarQueryable Clone() + { + var queryable = this.Context.Queryable().AsType(this.QueryBuilder.AsType).Select().WithCacheIF(IsCache, CacheTime); + CopyQueryBuilder(queryable.QueryBuilder); + ((QueryableProvider)queryable).CacheKey = this.CacheKey; + ((QueryableProvider)queryable).MapperAction = this.MapperAction; + ((QueryableProvider)queryable).MapperActionWithCache = this.MapperActionWithCache; + ((QueryableProvider)queryable).Mappers = this.Mappers; + return queryable; + } + public ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public virtual ISugarQueryable AS(string tableName) + { + var entityName = typeof(T2).Name; + return _As(tableName, entityName); + } + public ISugarQueryable AS(string tableName) + { + if (tableName == null) return this; + var entityName = typeof(T).Name; + return _As(tableName, entityName); + } + + public ISugarQueryable IF(bool condition, Action> action) + { + if (condition) + action(this); + return this; + } + public ISugarQueryable AsWithAttr() + { + var asName = GetTableName(this.EntityInfo, this.EntityInfo.DbTableName); + this.QueryBuilder.IsCrossQueryWithAttr = true; + return this.AS(asName); + } + public ISugarQueryable Cast() + { + var selectValue = this.Clone().QueryBuilder.GetSelectValue; + return this.Select().Select(selectValue); + } + public ISugarQueryable AsType(Type tableNameType) + { + if (tableNameType == null) + { + return this; + } + this.QueryBuilder.AsType = tableNameType; + return AS(this.Context.EntityMaintenance.GetEntityInfo(tableNameType).DbTableName); + } + public virtual ISugarQueryable With(string withString) + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + QueryBuilder.TableWithString = withString; + } + return this; + } + + public virtual ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + public ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public ISugarQueryable ClearFilter(params Type[] types) + { + if (types == null || types.Length == 0) + { + return this; + } + this.QueryBuilder.RemoveFilters = types; + this.Filter(null, true); + this.QueryBuilder.IsDisabledGobalFilter = false; + return this; + } + public ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + public ISugarQueryable Filter(Type type) + { + if (type == null) + { + return this; + } + this.Context.InitMappingInfo(type); + var whereString = QueryBuilder.GetFilters(type); + if (whereString.HasValue()) + { + this.Where(whereString); + } + UtilMethods.AddDiscrimator(type, this); + return this; + } + + public virtual ISugarQueryable Mapper(Action mapperAction) + { + this.MapperAction = UtilMethods.IsNullReturnNew(this.MapperAction); + this.MapperAction.Add(mapperAction); + return this; + } + public ISugarQueryable Mapper(Expression> expression) + { + var args = ((expression as LambdaExpression).Body as MethodCallExpression).Arguments; + + Type aType = typeof(AType); + Type bType = typeof(BType); + Type bListType = typeof(List); + + this.Context.InitMappingInfo(aType); + this.Context.InitMappingInfo(bType); + this.Context.InitMappingInfo(typeof(MappingType)); + + //Mapping + var mappingEntity = this.Context.EntityMaintenance.GetEntityInfo(typeof(MappingType)); + string m_aPropertyName = (args[0] as MemberExpression).Member.Name; + string m_bPropertyName = (args[1] as MemberExpression).Member.Name; + var m_aDbField = mappingEntity.Columns.First(it => it.PropertyName == m_aPropertyName).DbColumnName; + var m_bDbField = mappingEntity.Columns.First(it => it.PropertyName == m_bPropertyName).DbColumnName; + + //A + var aEntity = this.Context.EntityMaintenance.GetEntityInfo(aType); + var aPropertyName = aEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true)?.PropertyName; + Check.Exception(aPropertyName == null, aEntity.EntityName + " no primary key"); + + //B + var bEntity = this.Context.EntityMaintenance.GetEntityInfo(bType); + var bProperty = bEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true)?.PropertyName; + Check.Exception(bProperty == null, bEntity.EntityName + " no primary key"); + var bDbFiled = bEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true).DbColumnName; + this.Mapper((it, cache) => + { + var list = cache.Get>>(oldList => + { + + + //query mapping by a + var cons = new List() { + new ConditionalModel(){ + ConditionalType=ConditionalType.In, + FieldName= m_aDbField, + FieldValue=string.Join(",",oldList.Select(z=>UtilMethods.GetPropertyValue(z,aPropertyName)).Distinct()) + } + }; + var mappingList = this.Context.Queryable().Where(cons).ToList(); + var bids = mappingList.Select(z => UtilMethods.GetPropertyValue(z, m_bPropertyName)).Distinct().ToList(); + + //queryable b by mapping + cons = new List() { + new ConditionalModel(){ + ConditionalType=ConditionalType.In, + FieldName= bDbFiled, + FieldValue=string.Join(",",mappingList.Select(z=>UtilMethods.GetPropertyValue(z,m_bPropertyName)).Distinct()) + } + }; + List bList = new List(); + if (mappingList.Count != 0) + { + bList = this.Context.Queryable().Where(cons).ToList(); + } + + //get result + Dictionary> result = new Dictionary>(); + var group = mappingList.GroupBy(z => UtilMethods.GetPropertyValue(z, m_aPropertyName)); + foreach (var item in group) + { + var currentBids = item.Select(z => UtilMethods.GetPropertyValue(z, m_bPropertyName)).ToList(); + result.Add(item.Key, bList.Where(z => currentBids.Contains(UtilMethods.GetPropertyValue(z, bProperty))).ToList()); + } + return result; + + }, expression.ToString()); + foreach (var item in aEntity.Columns) + { + var aid = UtilMethods.GetPropertyValue(it, aPropertyName); + if (list.ContainsKey(aid)) + { + if (item.PropertyInfo.PropertyType == bType) + { + var b = UtilMethods.ChangeType(list[aid].FirstOrDefault()); + item.PropertyInfo.SetValue(it, b); + } + else if (item.PropertyInfo.PropertyType == bListType) + { + var bList = UtilMethods.ChangeType>(list[aid]); + item.PropertyInfo.SetValue(it, bList); + } + } + } + }); + return this; + } + + public virtual ISugarQueryable Mapper(Action> mapperAction) + { + this.MapperActionWithCache += mapperAction; + return this; + } + public ISugarQueryable Mapper(Expression> mapperObject, Expression> mainField, Expression> childField) + { + Check.Exception(mapperObject.ReturnType.Name == "IList`1", "Mapper no support IList , Use List"); + if (CallContext.MapperExpression.Value == null) + { + CallContext.MapperExpression.Value = new List(); + } + CallContext.MapperExpression.Value.Add(new MapperExpression() { SqlBuilder = SqlBuilder, QueryBuilder = this.QueryBuilder, Type = MapperExpressionType.oneToOne, FillExpression = mapperObject, MappingField1Expression = mainField, MappingField2Expression = childField, Context = this.Context }); + return _Mapper(mapperObject, mainField, childField); + } + public ISugarQueryable Mapper(Expression>> mapperObject, Expression> mainField, Expression> childField) + { + return _Mapper(mapperObject, mainField, childField); + } + public virtual ISugarQueryable Mapper(Expression>> mapperObject, Expression> mapperField) + { + Check.Exception(mapperObject.ReturnType.Name == "IList`1", "Mapper no support IList , Use List"); + if (CallContext.MapperExpression.Value == null) + { + CallContext.MapperExpression.Value = new List(); + } + CallContext.MapperExpression.Value.Add(new MapperExpression() { SqlBuilder = SqlBuilder, QueryBuilder = this.QueryBuilder, Type = MapperExpressionType.oneToN, FillExpression = mapperObject, MappingField1Expression = mapperField, Context = this.Context }); + return _Mapper(mapperObject, mapperField); + } + public virtual ISugarQueryable Mapper(Expression> mapperObject, Expression> mapperField) + { + if (CallContext.MapperExpression.Value == null) + { + CallContext.MapperExpression.Value = new List(); + } + CallContext.MapperExpression.Value.Add(new MapperExpression() { SqlBuilder = SqlBuilder, QueryBuilder = this.QueryBuilder, Type = MapperExpressionType.oneToOne, FillExpression = mapperObject, MappingField1Expression = mapperField, Context = this.Context }); + return _Mapper(mapperObject, mapperField); + } + public ISugarQueryable Where(string fieldName, string conditionalType, object fieldValue) + { + string parameterName = fieldName.Replace(".", "_") + this.QueryBuilder.WhereIndex; + var whereSql = this.SqlBuilder.GetWhere(fieldName, conditionalType, this.QueryBuilder.WhereIndex); + this.Where(whereSql); + this.QueryBuilder.WhereIndex++; + this.QueryBuilder.Parameters.Add(new SugarParameter(parameterName, fieldValue)); + return this; + } + public virtual ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public virtual ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public virtual ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public virtual ISugarQueryable AddParameters(SugarParameter parameter) + { + if (parameter != null) + QueryBuilder.Parameters.Add(parameter); + return this; + } + public ISugarQueryable AddJoinInfo(Type JoinType, Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString onExpString, JoinType type = JoinType.Left) + { + var whereExp = DynamicCoreHelper.GetWhere(keyIsShortName_ValueIsType_Dictionary, onExpString); + var name = whereExp.Parameters.Last(it => it.Type == JoinType).Name; + this.Context.InitMappingInfo(JoinType); + var sql = this.QueryBuilder.GetExpressionValue(whereExp, ResolveExpressType.WhereMultiple).GetResultString(); + return AddJoinInfo(JoinType, name, sql, type); + } + public ISugarQueryable AddJoinInfo(Type JoinType, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + this.Context.InitMappingInfo(JoinType); + var tableName = this.Context.EntityMaintenance.GetEntityInfo(JoinType).DbTableName; + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere, + EntityType = JoinType + }); + return this; + } + public virtual ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + return WhereClass(new List() { whereClass }, ignoreDefaultValue); + } + public ISugarQueryable WhereClassByPrimaryKey(List list) + { + _WhereClassByPrimaryKey(list); + return this; + } + + public ISugarQueryable WhereClassByWhereColumns(List list, string[] whereColumns) + { + _WhereClassByWhereColumns(list, whereColumns); + return this; + } + public ISugarQueryable WhereClassByPrimaryKey(T data) + { + _WhereClassByPrimaryKey(new List() { data }); + return this; + } + public ISugarQueryable TranLock(DbLockType? LockType = DbLockType.Wait) + { + if (LockType == null) return this; + Check.ExceptionEasy(this.Context.Ado.Transaction == null, "need BeginTran", "需要事务才能使用TranLock"); + Check.ExceptionEasy(this.QueryBuilder.IsSingle() == false, "TranLock, can only be used for single table query", "TranLock只能用在单表查询"); + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + if (LockType == DbLockType.Wait) + { + this.With("WITH(UpdLock,RowLock)"); + } + else + { + this.With("WITH(UpdLock,RowLock,NoWait)"); + } + } + else + { + this.QueryBuilder.TranLock = (LockType == DbLockType.Error ? " for update nowait" : " for update"); + } + return this; + } + public ISugarQueryable WhereColumns(Dictionary dictionary) + { + return WhereColumns(new List> { dictionary }); + } + public ISugarQueryable WhereColumns(Dictionary columns, bool ignoreDefaultValue) + { + if (ignoreDefaultValue == false || columns == null) + { + return WhereColumns(columns); + } + else + { + var newColumns = new Dictionary(); + foreach (var item in columns) + { + if (!UtilMethods.IsDefaultValue(item.Value)) + { + newColumns.Add(item.Key, item.Value); + } + } + return WhereColumns(newColumns); + } + } + public ISugarQueryable WhereColumns(List> list) + { + List conditionalModels = new List(); + foreach (var model in list) + { + int i = 0; + var clist = new List>(); + foreach (var item in model.Keys) + { + var value = model[item] == null ? "null" : model[item].ObjToString(); + var csType = model[item] == null ? null : model[item].GetType().Name; + if (model[item] is Enum && this.Context?.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true) + { + value = Convert.ToInt64(model[item]) + ""; + csType = "Int64"; + } + clist.Add(new KeyValuePair(i == 0 ? WhereType.Or : WhereType.And, new ConditionalModel() + { + FieldName = item, + ConditionalType = ConditionalType.Equal, + FieldValue = value, + CSharpTypeName = csType + })); + i++; + } + conditionalModels.Add(new ConditionalCollections() + { + ConditionalList = clist + }); + } + return this.Where(conditionalModels); + } + + /// + /// if a property that is primary key is a condition + /// + /// + /// + public ISugarQueryable _WhereClassByPrimaryKey(List whereClassTypes) + { + + if (whereClassTypes.HasValue()) + { + var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsIgnore == false && it.IsPrimarykey == true).ToList(); + Check.Exception(columns == null || columns.Count == 0, "{0} no primary key, Can not use WhereClassByPrimaryKey ", typeof(T).Name); + Check.Exception(this.QueryBuilder.IsSingle() == false, "No support join query"); + List whereModels = new List(); + foreach (var item in whereClassTypes) + { + var cons = new ConditionalCollections(); + foreach (var column in columns) + { + WhereType WhereType = WhereType.And; + var value = column.PropertyInfo.GetValue(item, null); + if (cons.ConditionalList == null) + { + cons.ConditionalList = new List>(); + if (QueryBuilder.WhereInfos.IsNullOrEmpty() && whereModels.IsNullOrEmpty()) + { + + } + else + { + WhereType = WhereType.Or; + } + } + var data = new KeyValuePair(WhereType, new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + FieldName = this.QueryBuilder.Builder.GetTranslationColumnName(column.DbColumnName), + FieldValue = value.ObjToStringNew(), + CSharpTypeName = column.UnderType.Name + }); + if (value is Enum && this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true) + { + data.Value.FieldValue = Convert.ToInt64(value).ObjToString(); + data.Value.CSharpTypeName = "int"; + } + else if (value != null && column.UnderType == UtilConstants.DateType) + { + data.Value.FieldValue = Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + //if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + //{ + // data.Value.FieldValueConvertFunc = it => + // { + // return UtilMethods.ChangeType2(it, value.GetType()); + // }; + //} + cons.ConditionalList.Add(data); + } + if (cons.HasValue()) + { + whereModels.Add(cons); + } + } + this.Where(whereModels, true); + } + else + { + this.Where(" 1=2 "); + } + return this; + } + /// + /// if a property that is whereColumns key is a condition + /// + /// + /// + /// + public ISugarQueryable _WhereClassByWhereColumns(List whereClassTypes, string[] whereColumns) + { + + if (whereClassTypes.HasValue()) + { + var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => whereColumns.Any(x => x == it.PropertyName) || whereColumns.Any(x => x.EqualCase(it.DbColumnName))).ToList(); + Check.Exception(columns == null || columns.Count == 0, "{0} no primary key, Can not use whereColumns ", typeof(T).Name); + Check.Exception(this.QueryBuilder.IsSingle() == false, "No support join query"); + List whereModels = new List(); + foreach (var item in whereClassTypes) + { + var cons = new ConditionalCollections(); + foreach (var column in columns) + { + WhereType WhereType = WhereType.And; + var value = column.PropertyInfo.GetValue(item, null); + if (cons.ConditionalList == null) + { + cons.ConditionalList = new List>(); + if (QueryBuilder.WhereInfos.IsNullOrEmpty() && whereModels.IsNullOrEmpty()) + { + + } + else + { + WhereType = WhereType.Or; + } + } + var disableQueryWhereColumnRemoveTrim = this.Context.CurrentConnectionConfig?.MoreSettings?.DisableQueryWhereColumnRemoveTrim == true; + var data = new KeyValuePair(WhereType, new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + FieldName = this.QueryBuilder.Builder.GetTranslationColumnName(column.DbColumnName), + FieldValue = disableQueryWhereColumnRemoveTrim ? value.ObjToStringNoTrim() : value.ObjToStringNew(), + CSharpTypeName = column.PropertyInfo.PropertyType.Name + }); + if (value == null) + { + data.Value.FieldValue = null; + data.Value.ConditionalType = ConditionalType.EqualNull; + } + if (value is Enum && this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true) + { + data.Value.FieldValue = Convert.ToInt64(value).ObjToString(); + data.Value.CSharpTypeName = "int"; + } + //if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + //{ + // data.Value.FieldValueConvertFunc = it => + // { + // return UtilMethods.ChangeType2(it, value.GetType()); + // }; + //} + cons.ConditionalList.Add(data); + } + if (cons.HasValue()) + { + whereModels.Add(cons); + } + } + this.Where(whereModels, true); + } + else + { + this.Where(" 1=2 "); + } + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + if (whereClassTypes.HasValue()) + { + var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsIgnore == false).ToList(); + List whereModels = new List(); + foreach (var item in whereClassTypes) + { + var cons = new ConditionalCollections(); + foreach (var column in columns) + { + + var value = column.PropertyInfo.GetValue(item, null); + WhereType WhereType = WhereType.And; + var isNotNull = ignoreDefaultValue == false && value != null; + var isNotNullAndDefault = ignoreDefaultValue && value != null && value.ObjToString() != UtilMethods.DefaultForType(column.PropertyInfo.PropertyType).ObjToString(); + if (isNotNull || isNotNullAndDefault) + { + if (cons.ConditionalList == null) + { + cons.ConditionalList = new List>(); + if (QueryBuilder.WhereInfos.IsNullOrEmpty() && whereModels.IsNullOrEmpty()) + { + + } + else + { + WhereType = WhereType.Or; + } + + } + var data = new KeyValuePair(WhereType, new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + FieldName = column.DbColumnName, + FieldValue = value.ObjToString(), + CSharpTypeName = column.UnderType.Name + }); + if (value?.GetType().IsEnum() == true) + { + if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString == true) + { + + } + else + { + data.Value.FieldValue = Convert.ToInt64(value).ObjToString(); + } + + } + else if (value != null && column.PropertyInfo.PropertyType == UtilConstants.DateType) + { + data.Value.FieldValue = value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.ffffff"); + } + cons.ConditionalList.Add(data); + if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + data.Value.FieldValueConvertFunc = it => + { + return UtilMethods.ChangeType2(it, value.GetType()); + }; + } + } + } + if (cons.HasValue()) + { + whereModels.Add(cons); + } + } + this.Where(whereModels); + } + return this; + } + public ISugarQueryable Where(Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(keyIsShortName_ValueIsType_Dictionary, expressionString); + _Where(exp); + return this; + } + public virtual ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + if (expressionString == null && !Regex.IsMatch(expShortName, @"^\w$")) + { + return this.Where(expShortName, new { }); + } + + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public virtual ISugarQueryable Where(Expression> expression) + { + if (IsSingleWithChildTableQuery()) + { + expression = ReplaceMasterTableParameters(expression); + } + this._Where(expression); + return this; + } + + public virtual ISugarQueryable Where(string whereString, object whereObj = null) + { + if (whereString.HasValue()) + this.Where(whereString, whereObj); + return this; + } + public virtual ISugarQueryable Where(IFuncModel funcModel) + { + var obj = this.SqlBuilder.FuncModelToSql(funcModel); + return this.Where(obj.Key, obj.Value); + } + public virtual ISugarQueryable Where(List conditionalModels) + { + if (conditionalModels.IsNullOrEmpty()) return this; + var sqlObj = this.SqlBuilder.ConditionalModelToSql(conditionalModels, 0); + if (sqlObj.Value != null && this.QueryBuilder.Parameters != null) + { + if (sqlObj.Value.Any(it => this.QueryBuilder.Parameters.Any(z => z.ParameterName.EqualCase(it.ParameterName)))) + { + var sql = sqlObj.Key; + this.SqlBuilder.RepairReplicationParameters(ref sql, sqlObj.Value, this.QueryBuilder.Parameters.Count * 10); + return this.Where(sql, sqlObj.Value); + } + } + return this.Where(sqlObj.Key, sqlObj.Value); + } + public ISugarQueryable Where(List conditionalModels, bool isWrap) + { + if (conditionalModels.IsNullOrEmpty()) return this; + var sqlObj = this.SqlBuilder.ConditionalModelToSql(conditionalModels, 0); + if (isWrap) + { + return this.Where("(" + sqlObj.Key + ")", sqlObj.Value); + } + else + { + return this.Where(sqlObj.Key, sqlObj.Value); + } + } + public virtual ISugarQueryable Where(string whereString, object whereObj = null) + { + var whereValue = QueryBuilder.WhereInfos; + whereValue.Add(SqlBuilder.AppendWhereOrAnd(whereValue.Count == 0, whereString + UtilConstants.Space)); + if (whereObj != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(whereObj)); + return this; + } + + public virtual ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable Having(string whereString, object parameters = null) + { + + QueryBuilder.HavingInfos = SqlBuilder.AppendHaving(whereString); + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + + public virtual ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (!isWhere) return this; + if (IsSingleWithChildTableQuery()) + { + expression = ReplaceMasterTableParameters(expression); + } + _Where(expression); + return this; + } + public virtual ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj = null) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + + public virtual T InSingle(object pkValue) + { + if (pkValue == null) + { + pkValue = -1; + } + Check.Exception(this.QueryBuilder.SelectValue.HasValue(), "'InSingle' and' Select' can't be used together,You can use .Select(it=>...).Single(it.id==1)"); + var list = In(pkValue).ToList(); + if (list == null) return default(T); + else return list.SingleOrDefault(); + } + public ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues) + { + if (isIn) + { + return In(fieldName, pkValues); + } + else + { + return this; + } + } + public ISugarQueryable InIF(bool isIn, params TParamter[] pkValues) + { + if (isIn) + { + In(pkValues); + } + return this; + } + public virtual ISugarQueryable In(params TParamter[] pkValues) + { + if (pkValues == null || pkValues.Length == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + if (pkValues.Length == 1 && pkValues.First().GetType().FullName.IsCollectionsList() || (pkValues.First() is IEnumerable && pkValues.First().GetType() != UtilConstants.StringType)) + { + var newValues = new List(); + foreach (var item in pkValues.First() as IEnumerable) + { + newValues.Add(item); + } + return In(newValues); + } + var pks = GetPrimaryKeys().Select(it => SqlBuilder.GetTranslationTableName(it)).ToList(); + Check.Exception(pks == null || pks.Count != 1, "Queryable.In(params object[] pkValues): Only one primary key"); + string filed = pks.FirstOrDefault(); + string shortName = QueryBuilder.TableShortName == null ? null : (QueryBuilder.TableShortName + "."); + filed = shortName + filed; + return In(filed, pkValues); + } + public virtual ISugarQueryable In(string filed, params FieldType[] inValues) + { + if (inValues.Length == 1) + { + if (inValues.GetType().IsArray) + { + var whereIndex = QueryBuilder.WhereIndex; + string parameterName = this.SqlBuilder.SqlParameterKeyWord + "InPara" + whereIndex; + this.AddParameters(new SugarParameter(parameterName, inValues[0])); + this.Where(string.Format(QueryBuilder.EqualTemplate, SqlBuilder.GetTranslationColumnName(filed), parameterName)); + QueryBuilder.WhereIndex++; + } + else + { + var values = new List(); + foreach (var item in ((IEnumerable)inValues[0])) + { + if (item != null) + { + values.Add(item.ToString().ToSqlValue()); + } + } + this.Where(string.Format(QueryBuilder.InTemplate, SqlBuilder.GetTranslationColumnName(filed), string.Join(",", values))); + } + } + else + { + var values = new List(); + foreach (var item in inValues) + { + if (item != null) + { + if (UtilMethods.IsNumber(item.GetType().Name)) + { + values.Add(item.ToString()); + } + else + { + values.Add(item.ToString().ToSqlValue()); + } + } + } + this.Where(string.Format(QueryBuilder.InTemplate, SqlBuilder.GetTranslationColumnName(filed), string.Join(",", values))); + + } + return this; + } + public virtual ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + var propertyName = ExpressionTool.GetMemberName(expression); + var propertyColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == propertyName); + if (inValues?.Length == 1 && inValues[0]?.GetType()?.FullName?.IsCollectionsList() == true && propertyColumn != null && propertyColumn?.UnderType?.FullName?.IsCollectionsList() != true) + { + return In(fieldName, UtilMethods.ConvertToListOfObjects(inValues[0])); + } + else if (inValues?.Length == 1 && inValues[0]?.GetType()?.IsArray == true && propertyColumn != null && propertyColumn?.UnderType?.IsArray != true) + { + return In(fieldName, UtilMethods.ConvertToListOfObjects(inValues[0])); + } + else + { + return In(fieldName, inValues); + } + } + public virtual ISugarQueryable In(List pkValues) + { + if (pkValues == null || pkValues.Count == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + return In(pkValues.ToArray()); + } + public virtual ISugarQueryable In(string InFieldName, List inValues) + { + if (inValues == null || inValues.Count == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + return In(InFieldName, inValues.ToArray()); + } + public virtual ISugarQueryable In(Expression> expression, List inValues) + { + if (inValues == null || inValues.Count == 0) + { + Where(SqlBuilder.SqlFalse); + return this; + } + return In(expression, inValues.ToArray()); + } + + public ISugarQueryable InIF(bool isWhere, Expression> expression, ISugarQueryable childQueryExpression) + { + if (isWhere) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + } + return this; + } + + public virtual ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + public ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType) + { + SampleByUnit sampleBy = timeType; + if (timeType == SampleByUnit.Month) + { + string sql = "SAMPLE BY " + timeNumber + sampleBy.ToString().Substring(0, 1); + this.QueryBuilder.SampleBy = sql; + } + else if (timeType == SampleByUnit.Millisecond) + { + string sql = "SAMPLE BY " + timeNumber + " T "; + this.QueryBuilder.SampleBy = sql; + } + else if (timeType == SampleByUnit.Microsecond) + { + string sql = "SAMPLE BY " + timeNumber + " U "; + this.QueryBuilder.SampleBy = sql; + } + else + { + string sql = "SAMPLE BY " + timeNumber + sampleBy.ToString().Substring(0, 1).ToLower(); + this.QueryBuilder.SampleBy = sql; + } + return this; + } + public ISugarQueryable SampleBy(int timeNumber, string timeType) + { + string sql = "SAMPLE BY " + timeType; + this.QueryBuilder.SampleBy = sql; + return this; + } + public ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + if (orderPropertyName.HasValue()) + { + if (orderPropertyName.Contains(',')) + { + foreach (var item in orderPropertyName.Split(',')) + { + this.OrderByPropertyName(item, orderByType); + } + return this; + } + if (this.QueryBuilder.IsSingle() == false && orderPropertyName.Contains('.')) + { + orderPropertyNameByJoin(orderPropertyName, orderByType); + return this; + } + if (this.Context.EntityMaintenance.GetEntityInfoWithAttr(typeof(T)).Columns.Any(it => + it.DbColumnName?.EqualCase(orderPropertyName) == true + || it.PropertyName?.EqualCase(orderPropertyName) == true)) + { + var name = this.Context.EntityMaintenance.GetEntityInfoWithAttr(typeof(T)).Columns.FirstOrDefault(it => + it.DbColumnName?.EqualCase(orderPropertyName) == true + || it.PropertyName?.EqualCase(orderPropertyName) == true)?.DbColumnName; + return this.OrderBy(this.SqlBuilder.GetTranslationColumnName(name) + " " + orderByType); + } + else + { + Check.ExceptionEasy($"OrderByPropertyName error.{orderPropertyName} does not exist in the entity class", $"OrderByPropertyName出错实体类中不存在{orderPropertyName}"); + } + } + return this; + } + public virtual ISugarQueryable OrderBy(string orderByFields) + { + orderByFields = orderByFields.ToCheckField(); + var orderByValue = QueryBuilder.OrderByValue; + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.OrderByTemplate; + } + QueryBuilder.OrderByValue += string.IsNullOrEmpty(orderByValue) ? orderByFields : ("," + orderByFields); + return this; + } + public virtual ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + this._OrderBy(expression, type); + return this; + } + public virtual ISugarQueryable OrderBy(string expShortName, FormattableString expOrderBy, OrderByType type = OrderByType.Asc) + { + var exp = DynamicCoreHelper.GetMember(typeof(T), typeof(object), expShortName, expOrderBy); + this._OrderBy(exp, type); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + + public ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + + return this; + } + + + public virtual ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + return this.OrderBy(orderByFields); + else + return this; + } + public virtual ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + return this.OrderBy(expression, type); + else + return this; + } + + public virtual ISugarQueryable GroupBy(string groupFileds) + { + groupFileds = groupFileds.ToCheckField(); + var croupByValue = QueryBuilder.GroupByValue; + if (QueryBuilder.GroupByValue.IsNullOrEmpty()) + { + QueryBuilder.GroupByValue = QueryBuilder.GroupByTemplate; + } + QueryBuilder.GroupByValue += string.IsNullOrEmpty(croupByValue) ? groupFileds : ("," + groupFileds); + return this; + } + + public virtual ISugarQueryable PartitionBy(Expression> expression) + { + if (QueryBuilder.Take == null) + QueryBuilder.Take = 1; + _PartitionBy(expression); + QueryBuilder.DisableTop = true; + return this; + } + public virtual ISugarQueryable PartitionBy(string groupFileds) + { + var partitionByValue = QueryBuilder.PartitionByValue; + if (QueryBuilder.PartitionByValue.IsNullOrEmpty()) + { + QueryBuilder.PartitionByValue = QueryBuilder.PartitionByTemplate; + } + QueryBuilder.PartitionByValue += string.IsNullOrEmpty(partitionByValue) ? groupFileds : ("," + groupFileds); + return this; + } + + public virtual ISugarQueryable Skip(int num) + { + QueryBuilder.Skip = num; + return this; + } + public virtual ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public virtual ISugarQueryable Select(Expression expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expSelect, Type resultType) + { + var exp = DynamicCoreHelper.GetMember(keyIsShortName_ValueIsType_Dictionary, resultType, expSelect); + return _Select(exp); + } + public ISugarQueryable Select(string expShortName, FormattableString expSelect, Type resultType) + { + var exp = DynamicCoreHelper.GetMember(typeof(TResult), resultType, expShortName, expSelect); + return _Select(exp); + } + public ISugarQueryable Select(string expShortName, FormattableString expSelect, Type EntityType, Type resultType) + { + var exp = DynamicCoreHelper.GetMember(EntityType, resultType, expShortName, expSelect); + return _Select(exp); + } + public ISugarQueryable Select(string expShortName, FormattableString expSelect, Type resultType) + { + return Select(expShortName, expSelect, resultType); + } + public DynamicCoreSelectModel Select(string expShortName, List columns, params object[] args) + { + DynamicCoreSelectModel dynamicCoreSelectModel = new DynamicCoreSelectModel(); + if (!string.IsNullOrEmpty(this.QueryBuilder.TableShortName) && expShortName != this.QueryBuilder.TableShortName) + { + if (columns.Any(it => it.Contains(expShortName + " "))) + { + var pattern = $@"\b{Regex.Escape(expShortName)}\s*\."; // 匹配 expShortName 后面跟任意空格和点 + var replacement = this.QueryBuilder.TableShortName + "."; + + columns = columns.Select(it => Regex.Replace(it, pattern, replacement)).ToList(); + expShortName = this.QueryBuilder.TableShortName; + } + else + { + columns = columns.Select(it => it.Replace(expShortName + ".", this.QueryBuilder.TableShortName + ".")).ToList(); + expShortName = this.QueryBuilder.TableShortName; + } + } + var selectObj = DynamicCoreHelper.BuildPropertySelector( + expShortName, typeof(T), + columns, + args); + if (IsAppendNavColumns()) + { + SetAppendNavColumns(selectObj.Exp); + } + var exp = selectObj.Exp; + var method = GetType().GetMethod("_Select", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) + .MakeGenericMethod(selectObj.ResultNewType); + dynamicCoreSelectModel.Value = method.Invoke(this, new object[] { exp }); + return dynamicCoreSelectModel; + } + public virtual ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + if (typeof(TResult).IsAnonymousType()) + { + return Select(expression); + } + var clone = this.Select(expression).Clone(); + clone.QueryBuilder.IsDistinct = false; + //clone.QueryBuilder.LambdaExpressions.Index = QueryBuilder.LambdaExpressions.Index+1; + var ps = clone.QueryBuilder; + var sql = ps.GetSelectValue; + if (string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + this.QueryBuilder.SelectValue = null; + return this.Select(); + } + if (sql.StartsWith("*,")) + { + var columns = this.Context.EntityMaintenance.GetEntityInfo() + .Columns.Where(it => typeof(TResult).GetProperties().Any(s => s.Name.EqualCase(it.PropertyName))).Where(it => it.IsIgnore == false).ToList(); + if (columns.Count != 0) + { + sql = string.Join(",", columns.Select(it => $"{SqlBuilder.GetTranslationColumnName(it.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(it.PropertyName)} ")) + + "," + sql.TrimStart('*').TrimStart(','); + } + } + if (this.QueryBuilder.TableShortName.IsNullOrEmpty()) + { + this.QueryBuilder.TableShortName = clone.QueryBuilder.TableShortName; + } + this.QueryBuilder.Parameters = ps.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(this.EntityInfo.Columns, sql, parameters, columnsResult, 0); + return this.Select(sql); + } + + public virtual ISugarQueryable Select() + { + var isJoin = this.QueryBuilder.JoinExpression != null; + if (isJoin) + { + var selectValue = new SugarMapper(this.Context).GetSelectValue(this.QueryBuilder); + return this.Select(selectValue); + } + else if (this.QueryBuilder.EntityType == UtilConstants.ObjType || (this.QueryBuilder.AsTables?.Count == 1) || this.QueryBuilder.EntityName != this.QueryBuilder.EntityType.Name) + { + if (typeof(TResult).IsInterface && this.QueryBuilder.AsType == null) + { + Check.ExceptionEasy("Select< interface > requires a full example of AsType(type) db.Queryable().AsType(type).Select().ToList()" + , "Select<接口>需要AsType(type)完整示例db.Queryable().AsType(type).Select().ToList()"); + } + if (this.QueryBuilder.SelectValue.HasValue() && this.QueryBuilder.SelectValue.ObjToString().Contains("AS")) + { + return this.Select(this.QueryBuilder.SelectValue + ""); + } + else + { + if (this.QueryBuilder.IsSingle() && this.EntityInfo?.Type?.GetCustomAttribute() != null && this.QueryBuilder?.SelectValue?.ToString() == "*") + { + var columnAarray = this.Context.EntityMaintenance.GetEntityInfo().Columns; + var sql = string.Empty; + var columns = columnAarray.Where(it => typeof(TResult).GetProperties().Any(s => s.Name.EqualCase(it.PropertyName))).Where(it => it.IsIgnore == false).ToList(); + if (columns.Count != 0) + { + sql = string.Join(",", columns.Select(it => $"{SqlBuilder.GetTranslationColumnName(it.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(it.PropertyName)} ")); + } + return this.Select(sql); + } + else + { + return this.Select(this.SqlBuilder.SqlSelectAll); + } + } + } + else + { + if (typeof(TResult).IsInterface && typeof(TResult).IsAssignableFrom(this.EntityInfo.Type)) + { + if (this.QueryBuilder.AsTables.Count == 0) + { + this.AsType(this.EntityInfo.Type); + } + } + var selects = this.QueryBuilder.GetSelectValueByString(); + if (selects.ObjToString().ToLower().IsContainsIn(".", "(", " as ")) + { + return this.Select(selects); + } + var resultColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns; + var dbColumns = this.EntityInfo.Columns.Where(it => !it.IsIgnore); + StringBuilder sb = new StringBuilder(); + foreach (var item in resultColumns) + { + var firstColumn = dbColumns.FirstOrDefault(z => + z.PropertyName.EqualCase(item.PropertyName) || + z.DbColumnName.EqualCase(item.PropertyName)); + if (firstColumn != null) + { + var dbColumnName = firstColumn.DbColumnName; + var AsName = item.PropertyName; + sb.Append($"{this.SqlBuilder.GetTranslationColumnName(dbColumnName)} AS {this.SqlBuilder.GetTranslationColumnName(AsName)} ,"); + } + } + selects = sb.ToString().TrimEnd(','); + if (string.IsNullOrEmpty(selects)) + { + selects = "*"; + } + return this.Select(selects); + } + } + + public virtual ISugarQueryable Select(string selectValue) + { + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.Context = this.Context; + result.SqlBuilder = this.SqlBuilder; + result.QueryBuilder.ResultType = this.QueryBuilder.ResultType; + result.IsCache = this.IsCache; + result.CacheTime = this.CacheTime; + QueryBuilder.SelectValue = selectValue; + if (this.IsAs) + { + ((QueryableProvider)result).IsAs = true; + } + return result; + } + public virtual ISugarQueryable Select(string selectValue) + { + QueryBuilder.SelectValue = selectValue; + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public virtual ISugarQueryable MergeTable() + { + if (IsSubToList()) + { + return MergeTableWithSubToList(); + } + Check.Exception(this.MapperAction != null || this.MapperActionWithCache != null, ErrorMessage.GetThrowMessage("'Mapper’ needs to be written after ‘MergeTable’ ", "Mapper 只能在 MergeTable 之后使用")); + //Check.Exception(this.QueryBuilder.SelectValue.IsNullOrEmpty(),ErrorMessage.GetThrowMessage( "MergeTable need to use Queryable.Select Method .", "使用MergeTable之前必须要有Queryable.Select方法")); + //Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0 || this.QueryBuilder.OrderByValue.HasValue(),ErrorMessage.GetThrowMessage( "MergeTable Queryable cannot Take Skip OrderBy PageToList ", "使用 MergeTable不能有 Take Skip OrderBy PageToList 等操作,你可以在Mergetable之后操作")); + var sqlobj = this._ToSql(); + if (IsSubToList()) + { + return MergeTableWithSubToListJoin(); + } + var index = QueryBuilder.WhereIndex + 1; + var result = + this.EntityInfo.Discrimator.HasValue() ? + this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null) + : + this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); + result.QueryBuilder.WhereIndex = index; + result.QueryBuilder.NoCheckInclude = true; + result.QueryBuilder.Includes = this.QueryBuilder.Includes; + result.QueryBuilder.AppendNavInfo = this.QueryBuilder.AppendNavInfo; + result.QueryBuilder.LambdaExpressions.ParameterIndex = QueryBuilder.LambdaExpressions.ParameterIndex++; + result.QueryBuilder.LambdaExpressions.Index = QueryBuilder.LambdaExpressions.Index++; + result.QueryBuilder.IsCrossQueryWithAttr = QueryBuilder.IsCrossQueryWithAttr; + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + result.Select("MergeTable.*"); + } + return result; + } + public ISugarQueryable SplitTable() + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + //all table + return this.SplitTable(tag => tag); + } + public ISugarQueryable SplitTable(DateTime beginTime, DateTime endTime) + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + var splitColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.GetCustomAttribute() != null); + Check.ExceptionEasy(splitColumn == null, "[SplitFieldAttribute] need to be added to the table field", "需要在分表字段加上属性[SplitFieldAttribute]"); + var columnName = this.SqlBuilder.GetTranslationColumnName(splitColumn.DbColumnName); + var sqlParameterKeyWord = this.SqlBuilder.SqlParameterKeyWord; + var resultQueryable = this.Where($" {columnName}>={sqlParameterKeyWord}spBeginTime AND {columnName}<= {sqlParameterKeyWord}spEndTime", new { spBeginTime = beginTime, spEndTime = endTime }).SplitTable(tas => + { + var result = tas; + var type = this.EntityInfo.Type.GetCustomAttribute(); + Check.ExceptionEasy(type == null, $"{this.EntityInfo.EntityName}need SplitTableAttribute", $"{this.EntityInfo.EntityName}需要特性 SplitTableAttribute"); + if (SplitType.Month == type.SplitType) + { + result = result.Where(y => y.Date >= beginTime.ToString("yyyy-MM").ObjToDate() && y.Date <= endTime.Date.ToString("yyyy-MM").ObjToDate().AddMonths(1).AddDays(-1)).ToList(); + } + else if (SplitType.Year == type.SplitType) + { + result = result.Where(y => y.Date.Year >= beginTime.Year && y.Date.Year <= endTime.Year).ToList(); + } + else if (SplitType.Week == type.SplitType) + { + var begtinWeek = UtilMethods.GetWeekFirstDayMon(beginTime).Date; + var endWeek = UtilMethods.GetWeekLastDaySun(endTime).Date; + result = result.Where(y => + y.Date >= begtinWeek && y.Date <= endWeek).ToList(); + } + else if (SplitType.Month_6 == type.SplitType) + { + var begtinWeek = beginTime.Month <= 6 ? beginTime.ToString("yyyy-01-01") : beginTime.ToString("yyyy-06-01"); + var endWeek = endTime.Month <= 6 ? endTime.ToString("yyyy-07-01") : endTime.ToString("yyyy-12-01"); + result = result.Where(y => + y.Date >= begtinWeek.ObjToDate() && y.Date <= endWeek.ObjToDate().AddMonths(1).AddDays(-1)).ToList(); + } + else if (SplitType.Season == type.SplitType) + { + + var beginSeason = Convert.ToDateTime(beginTime.AddMonths(0 - ((beginTime.Month - 1) % 3)).ToString("yyyy-MM-01")).Date; + var endSeason = DateTime.Parse(endTime.AddMonths(3 - ((endTime.Month - 1) % 3)).ToString("yyyy-MM-01")).AddDays(-1).Date; + result = result.Where(y => + y.Date >= beginSeason && y.Date <= endSeason).ToList(); + } + else + { + result = result.Where(y => y.Date >= beginTime.Date && y.Date <= endTime.Date).ToList(); + } + return result; + }); + if (splitColumn.SqlParameterDbType is System.Data.DbType) + { + foreach (var item in resultQueryable.QueryBuilder.Parameters) + { + if (item.ParameterName.IsContainsIn("spBeginTime", "spEndTime")) + { + item.DbType = (System.Data.DbType)splitColumn.SqlParameterDbType; + } + } + } + return resultQueryable; + } + public ISugarQueryable SplitTable(Func, IEnumerable> getTableNamesFunc) + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + SplitTableContext helper = new SplitTableContext(Context) + { + EntityInfo = this.EntityInfo + }; + this.Context.MappingTables.Add(this.EntityInfo.EntityName, this.EntityInfo.DbTableName); + var tables = getTableNamesFunc(helper.GetTables()); + List> tableQueryables = new List>(); + foreach (var item in tables) + { + tableQueryables.Add(this.Clone().AS(item.TableName)); + } + if (tableQueryables.Count == 0) + { + var result = this.Context.SqlQueryable("-- No table ").Select(); + result.QueryBuilder.SelectValue = null; + return result; + } + else + { + //if (this.Context.QueryFilter.Any()) + //{ + // foreach (var item in tableQueryables) + // { + // item.QueryBuilder.AppendFilter(); + // } + //} + var unionall = this.Context._UnionAll(tableQueryables.ToArray()); + unionall.QueryBuilder.Includes = this.QueryBuilder.Includes; + unionall.QueryBuilder.EntityType = typeof(T); + unionall.QueryBuilder.IsDisableMasterSlaveSeparation = this.QueryBuilder.IsDisableMasterSlaveSeparation; + unionall.QueryBuilder.IsDisabledGobalFilter = this.QueryBuilder.IsDisabledGobalFilter; + if (unionall.QueryBuilder.Includes?.Count > 0) + { + unionall.QueryBuilder.NoCheckInclude = true; + } + return unionall; + } + //var values= unionall.QueryBuilder.GetSelectValue; + //unionall.QueryBuilder.SelectValue = values; + } + + public ISugarQueryable WithCache(string cacheKey, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + Check.ArgumentNullException(this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService, "Use Cache ConnectionConfig.ConfigureExternalServices.DataInfoCacheService is required "); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + this.CacheKey = cacheKey; + return this; + } + public ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + Check.ArgumentNullException(this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService, "Use Cache ConnectionConfig.ConfigureExternalServices.DataInfoCacheService is required "); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (isCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider02-05.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider02-05.cs new file mode 100644 index 000000000..e8415de52 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider02-05.cs @@ -0,0 +1,3229 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + #region T2 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable IF(bool condition, Action> action) + { + throw new Exception("Only Queryable().IF is supported, and Queryable().IF is not supported"); + } + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, string timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + + public ISugarQueryable FullJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Full); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + + public ISugarQueryable LeftJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable FullJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable RightJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + #region Where + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(IFuncModel funcModel) + { + var obj = this.SqlBuilder.FuncModelToSql(funcModel); + return this.Where(obj.Key, obj.Value); + } + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + #endregion + + #region Order + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new ISugarQueryable PartitionBy(Expression> expression) + { + if (QueryBuilder.Take == null) + QueryBuilder.Take = 1; + _PartitionBy(expression); + QueryBuilder.DisableTop = true; + return this; + } + public ISugarQueryable PartitionBy(Expression> expression) + { + if (QueryBuilder.Take == null) + QueryBuilder.Take = 1; + _PartitionBy(expression); + QueryBuilder.DisableTop = true; + return this; + } + public new ISugarQueryable PartitionBy(string groupFileds) + { + base.PartitionBy(groupFileds); + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + + public new ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public new ISugarQueryable Having(string whereString, object whereObj) + { + base.Having(whereString, whereObj); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + public Task MaxAsync(Expression> expression) + { + return _MaxAsync(expression); + } + public Task MinAsync(Expression> expression) + { + return _MinAsync(expression); + } + public Task SumAsync(Expression> expression) + { + return _SumAsync(expression); + } + public Task AvgAsync(Expression> expression) + { + return _AvgAsync(expression); + } + #endregion + + #region In + public new ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues) + { + if (isIn) + { + In(fieldName, pkValues); + } + return this; + } + public new ISugarQueryable InIF(bool isIn, params TParamter[] pkValues) + { + if (isIn) + { + In(pkValues); + } + return this; + } + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + + public ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (isCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + #endregion + } + #endregion + #region T3 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable IF(bool condition, Action> action) + { + throw new Exception("Only Queryable().IF is supported, and Queryable().IF is not supported"); + } + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, string timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable FullJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Full); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + + + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + + } + + public ISugarQueryable LeftJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable FullJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable RightJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + + + #region Group + public new ISugarQueryable PartitionBy(Expression> expression) + { + if (QueryBuilder.Take == null) + QueryBuilder.Take = 1; + _PartitionBy(expression); + QueryBuilder.DisableTop = true; + return this; + } + public ISugarQueryable PartitionBy(Expression> expression) + { + if (QueryBuilder.Take == null) + QueryBuilder.Take = 1; + _PartitionBy(expression); + QueryBuilder.DisableTop = true; + return this; + } + public ISugarQueryable PartitionBy(Expression> expression) + { + if (QueryBuilder.Take == null) + QueryBuilder.Take = 1; + _PartitionBy(expression); + QueryBuilder.DisableTop = true; + return this; + } + public new ISugarQueryable PartitionBy(string groupFileds) + { + base.PartitionBy(groupFileds); + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + + public new ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public new ISugarQueryable Having(string whereString, object whereObj) + { + base.Having(whereString, whereObj); + return this; + } + public new virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + #endregion + + #region Order + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + #endregion + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable Where(IFuncModel funcModel) + { + var obj = this.SqlBuilder.FuncModelToSql(funcModel); + return this.Where(obj.Key, obj.Value); + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + public Task MaxAsync(Expression> expression) + { + return _MaxAsync(expression); + } + public Task MinAsync(Expression> expression) + { + return _MinAsync(expression); + } + public Task SumAsync(Expression> expression) + { + return _SumAsync(expression); + } + public Task AvgAsync(Expression> expression) + { + return _AvgAsync(expression); + } + #endregion + + #region In + public new ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues) + { + if (isIn) + { + In(fieldName, pkValues); + } + return this; + } + public new ISugarQueryable InIF(bool isIn, params TParamter[] pkValues) + { + if (isIn) + { + In(pkValues); + } + return this; + } + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + + public ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + + public ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + #endregion + } + #endregion + #region T4 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable IF(bool condition, Action> action) + { + throw new Exception("Only Queryable().IF is supported, and Queryable().IF is not supported"); + } + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, string timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable FullJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable RightJoinIF(bool isJoin, Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable Where(IFuncModel funcModel) + { + var obj = this.SqlBuilder.FuncModelToSql(funcModel); + return this.Where(obj.Key, obj.Value); + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public new ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public new ISugarQueryable Having(string whereString, object whereObj) + { + base.Having(whereString, whereObj); + return this; + } + + public new virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues) + { + if (isIn) + { + In(fieldName, pkValues); + } + return this; + } + public new ISugarQueryable InIF(bool isIn, params TParamter[] pkValues) + { + if (isIn) + { + In(pkValues); + } + return this; + } + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + + public ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + + public ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + + public ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, List inValues) + { + QueryBuilder.CheckExpression(expression, "In"); + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + + #region Other + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + #endregion + } + #endregion + #region T5 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable IF(bool condition, Action> action) + { + throw new Exception("Only Queryable().IF is supported, and Queryable().IF is not supported"); + } + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public new ISugarQueryable SampleBy(int timeNumber, string timeType) + { + base.SampleBy(timeNumber, timeType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable Where(IFuncModel funcModel) + { + var obj = this.SqlBuilder.FuncModelToSql(funcModel); + return this.Where(obj.Key, obj.Value); + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public new ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public new ISugarQueryable Having(string whereString, object whereObj) + { + base.Having(whereString, whereObj); + return this; + } + + public new virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + #endregion + } + #endregion +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider06-10.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider06-10.cs new file mode 100644 index 000000000..0530d5bd4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider06-10.cs @@ -0,0 +1,4082 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + #region T6 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable IF(bool condition, Action> action) + { + throw new Exception("Only Queryable().IF is supported, and Queryable().IF is not supported"); + } + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable Where(IFuncModel funcModel) + { + var obj = this.SqlBuilder.FuncModelToSql(funcModel); + return this.Where(obj.Key, obj.Value); + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + #endregion + + #region Select + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public new ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + public ISugarQueryable Having(Expression> expression) + { + this._Having(expression); + return this; + } + + public new ISugarQueryable Having(string whereString, object whereObj) + { + base.Having(whereString, whereObj); + return this; + } + + public new virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + #endregion + } + #endregion + #region T7 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + #endregion + + #region Select + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + sql = AppendSelect(sql, parameters, columnsResult, 6); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new virtual ISugarQueryable GroupByIF(bool isGroupBy, string groupFields) + { + if (isGroupBy) + { + GroupBy(groupFields); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public virtual ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression) + { + if (isGroupBy) + { + GroupBy(expression); + } + return this; + } + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public new virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + public virtual ISugarQueryable HavingIF(bool isHaving, Expression> expression) + { + if (isHaving) + this._Having(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + #endregion + } + #endregion + #region T8 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new() + { + base.WhereClass(whereClass, ignoreDefaultValue); + return this; + } + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + public new ISugarQueryable WhereClass(List whereClassTypes, bool ignoreDefaultValue = false) where ClassType : class, new() + { + + base.WhereClass(whereClassTypes, ignoreDefaultValue); + return this; + } + #endregion + + #region Select + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + sql = AppendSelect(sql, parameters, columnsResult, 6); + sql = AppendSelect(sql, parameters, columnsResult, 7); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + + public bool Any(Expression> expression) + { + _Where(expression); + var result = Any(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + #endregion + } + #endregion + #region T9 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + sql = AppendSelect(sql, parameters, columnsResult, 6); + sql = AppendSelect(sql, parameters, columnsResult, 7); + sql = AppendSelect(sql, parameters, columnsResult, 8); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + #endregion + + #region OrderBy + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + #endregion + } + #endregion + #region T10 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + sql = AppendSelect(sql, parameters, columnsResult, 6); + sql = AppendSelect(sql, parameters, columnsResult, 7); + sql = AppendSelect(sql, parameters, columnsResult, 8); + sql = AppendSelect(sql, parameters, columnsResult, 9); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + if (IsAppendNavColumns()) + { + SetAppendNavColumns(expression); + } + return _Select(expression); + } + #endregion + + #region OrderBy + public new virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public virtual ISugarQueryable OrderByDescending(Expression> expression) + { + this._OrderBy(expression, OrderByType.Desc); + return this; + } + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9, t10) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + #endregion + } + #endregion +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider11-12.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider11-12.cs new file mode 100644 index 000000000..4eac1034c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/QueryableProvider/QueryableProvider11-12.cs @@ -0,0 +1,1436 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + #region T11 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + public ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression) + { + var result = LeftJoin(joinExpression); + if (isLeftJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression) + { + var result = InnerJoin(joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Left); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Inner); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + var joinInfo = GetJoinInfo(joinExpression, JoinType.Right); + var sqlObject = joinQueryable.ToSql(); + string sql = sqlObject.Key; + this.QueryBuilder.LambdaExpressions.ParameterIndex += 100; + UtilMethods.RepairReplicationParameters(ref sql, sqlObject.Value.ToArray(), this.QueryBuilder.LambdaExpressions.ParameterIndex, ""); + joinInfo.TableName = "(" + sql + ")"; + this.QueryBuilder.Parameters.AddRange(sqlObject.Value); + result.QueryBuilder.JoinQueryInfos.Add(joinInfo); + result.QueryBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; + return result; + } + public ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = LeftJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression) + { + var result = InnerJoin(joinQueryable, joinExpression); + if (isJoin == false) + { + result.QueryBuilder.JoinQueryInfos.Remove(result.QueryBuilder.JoinQueryInfos.Last()); + } + return result; + } + public ISugarQueryable LeftJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Left)); + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Full)); + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Right)); + return result; + } + + public ISugarQueryable InnerJoin(Expression> joinExpression) + { + this.Context.InitMappingInfo(); + var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); + result.SqlBuilder = this.SqlBuilder; + result.Context = this.Context; + result.QueryBuilder.JoinQueryInfos.Add(GetJoinInfo(joinExpression, JoinType.Inner)); + return result; + } + + public ISugarQueryable LeftJoin(Expression> joinExpression, string tableName) + { + var result = LeftJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable FullJoin(Expression> joinExpression, string tableName) + { + var result = FullJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable InnerJoin(Expression> joinExpression, string tableName) + { + var result = InnerJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + public ISugarQueryable RightJoin(Expression> joinExpression, string tableName) + { + var result = RightJoin(joinExpression); + result.QueryBuilder.JoinQueryInfos.Last().TableName = tableName; + return result; + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + #endregion + + #region Select + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + sql = AppendSelect(sql, parameters, columnsResult, 6); + sql = AppendSelect(sql, parameters, columnsResult, 7); + sql = AppendSelect(sql, parameters, columnsResult, 8); + sql = AppendSelect(sql, parameters, columnsResult, 9); + sql = AppendSelect(sql, parameters, columnsResult, 10); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9, t10, t11) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + #endregion + } + #endregion + #region T12 + public partial class QueryableProvider : QueryableProvider, ISugarQueryable + { + public new ISugarQueryable Hints(string hints) + { + this.QueryBuilder.Hints = hints; + return this; + } + public new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null) + { + if (isOrderBy) + { + return this.OrderByPropertyName(orderPropertyName, orderByType); + } + return this; + } + public new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null) + { + base.OrderByPropertyName(orderPropertyName, orderByType); + return this; + } + public virtual ISugarQueryable SelectMergeTable(Expression> expression) + { + return this.Select(expression).MergeTable(); + } + + #region Where + public new ISugarQueryable Where(string expShortName, FormattableString expressionString) + { + var exp = DynamicCoreHelper.GetWhere(expShortName, expressionString); + _Where(exp); + return this; + } + public new ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public ISugarQueryable Where(Expression> expression) + { + _Where(expression); + return this; + } + public new ISugarQueryable Where(List conditionalModels) + { + base.Where(conditionalModels); + return this; + } + public new ISugarQueryable Where(List conditionalModels, bool isWrap) + { + base.Where(conditionalModels, isWrap); + return this; + } + public new ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public ISugarQueryable WhereIF(bool isWhere, Expression> expression) + { + if (isWhere) + _Where(expression); + return this; + } + public new ISugarQueryable Where(string whereString, object whereObj) + { + Where(whereString, whereObj); + return this; + } + + public new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj) + { + if (!isWhere) return this; + this.Where(whereString, whereObj); + return this; + } + #endregion + + #region Select + public ISugarQueryable Select(Expression> expression, bool isAutoFill) + { + var clone = this.Select(expression).Clone(); + var sql = clone.QueryBuilder.GetSelectValue; + if (this.QueryBuilder.IsSingle() || string.IsNullOrEmpty(sql) || sql.Trim() == "*") + { + sql = " "; + } + this.QueryBuilder.Parameters = clone.QueryBuilder.Parameters; + this.QueryBuilder.SubToListParameters = clone.QueryBuilder.SubToListParameters; + this.QueryBuilder.LambdaExpressions.ParameterIndex = clone.QueryBuilder.LambdaExpressions.ParameterIndex; + var parameters = (expression as LambdaExpression).Parameters; + var columnsResult = this.Context.EntityMaintenance.GetEntityInfo().Columns; + sql = AppendSelect(sql, parameters, columnsResult, 0); + sql = AppendSelect(sql, parameters, columnsResult, 1); + sql = AppendSelect(sql, parameters, columnsResult, 2); + sql = AppendSelect(sql, parameters, columnsResult, 3); + sql = AppendSelect(sql, parameters, columnsResult, 4); + sql = AppendSelect(sql, parameters, columnsResult, 5); + sql = AppendSelect(sql, parameters, columnsResult, 6); + sql = AppendSelect(sql, parameters, columnsResult, 7); + sql = AppendSelect(sql, parameters, columnsResult, 8); + sql = AppendSelect(sql, parameters, columnsResult, 9); + sql = AppendSelect(sql, parameters, columnsResult, 10); + sql = AppendSelect(sql, parameters, columnsResult, 11); + if (sql.Trim().First() == ',') + { + sql = sql.TrimStart(' ').TrimStart(','); + } + return this.Select(sql); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public ISugarQueryable Select(Expression> expression) + { + return _Select(expression); + } + public virtual ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression) + { + if (condition) + return Select(trueSelectExpression); + else + return Select(falseSelectExpression); + } + #endregion + + #region OrderBy + public new ISugarQueryable OrderBy(List models) + { + base.OrderBy(models); + return this; + } + public new ISugarQueryable OrderBy(string orderByFields) + { + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc) + { + _OrderBy(expression, type); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields) + { + if (isOrderBy) + base.OrderBy(orderByFields); + return this; + } + public new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + public ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc) + { + if (isOrderBy) + _OrderBy(expression, type); + return this; + } + #endregion + + #region GroupBy + public new ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + public ISugarQueryable GroupBy(Expression> expression) + { + _GroupBy(expression); + return this; + } + #endregion + + #region Aggr + public TResult Max(Expression> expression) + { + return _Max(expression); + } + public TResult Min(Expression> expression) + { + return _Min(expression); + } + public TResult Sum(Expression> expression) + { + return _Sum(expression); + } + public TResult Avg(Expression> expression) + { + return _Avg(expression); + } + #endregion + + #region In + public new ISugarQueryable In(Expression> expression, params FieldType[] inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, List inValues) + { + var isSingle = QueryBuilder.IsSingle(); + var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); + var fieldName = lamResult.GetResultString(); + In(fieldName, inValues); + return this; + } + public new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression) + { + var sqlObj = childQueryExpression.ToSql(); + _InQueryable(expression, sqlObj); + return this; + } + #endregion + + #region Other + public new ISugarQueryable Distinct() + { + QueryBuilder.IsDistinct = true; + return this; + } + public new ISugarQueryable Take(int num) + { + QueryBuilder.Take = num; + return this; + } + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9, t10, t11, t12) => Array.Empty()).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(AsT).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable AS(string tableName) + { + var entityName = typeof(T).Name; + _As(tableName, entityName); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.Filter(null, true); + return this; + } + public new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false) + { + _Filter(FilterName, isDisabledGobalFilter); + return this; + } + + public new ISugarQueryable ClearFilter(params Type[] types) + { + base.ClearFilter(types); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2)); + return this; + } + public new ISugarQueryable ClearFilter() + { + this.ClearFilter(typeof(FilterType1), typeof(FilterType2), typeof(FilterType3)); + return this; + } + public new ISugarQueryable AddParameters(object parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + return this; + } + public new ISugarQueryable AddParameters(SugarParameter[] parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddParameters(List parameters) + { + if (parameters != null) + QueryBuilder.Parameters.AddRange(parameters); + return this; + } + public new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left) + { + QueryBuilder.JoinIndex = +1; + QueryBuilder.JoinQueryInfos + .Add(new JoinQueryInfo() + { + JoinIndex = QueryBuilder.JoinIndex, + TableName = tableName, + ShortName = shortName, + JoinType = type, + JoinWhere = joinWhere + }); + return this; + } + public new ISugarQueryable With(string withString) + { + base.With(withString); + return this; + } + public new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + return this; + } + public new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue) + { + cacheDurationInSeconds = SetCacheTime(cacheDurationInSeconds); + if (IsCache) + { + this.IsCache = true; + this.CacheTime = cacheDurationInSeconds; + } + return this; + } + #endregion + } + #endregion +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/Reportable/ReportableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/Reportable/ReportableProvider.cs new file mode 100644 index 000000000..a9db418e5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/Reportable/ReportableProvider.cs @@ -0,0 +1,285 @@ +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class ReportableProvider : IReportable + { + public SqlSugarProvider Context { get; set; } + private List datas = new List(); + private List dates = new List(); + private bool isDates = false; + internal QueryBuilder queryBuilder; + internal InsertBuilder formatBuilder { get; set; } + + public ReportableProvider(T data) + { + datas.Add(data); + Init(); + } + + public ReportableProvider(List list) + { + datas = list; + Init(); + } + + //public IReportable MakeUp(Func auto) + //{ + // throw new NotImplementedException(); + //} + + public ISugarQueryable ToQueryable() + { + StringBuilder sb = new StringBuilder(); + if (datas.Count != 0) + { + if (isDates) + { + var da = this.dates; + Each(sb, da); + } + else + { + var da = this.datas; + Each(sb, da); + } + } + else + { + if (typeof(T).IsClass()) + { + + var result = (T)Activator.CreateInstance(typeof(T), true); + datas.Add(result); + ClassMethod(result, sb, true); + } + else + { + sb.Append("SELECT NULL as ColumnName "); + sb.Append(GetNextSql); + } + } + return this.Context.SqlQueryable(sb.ToString()).Select(); + } + public ISugarQueryable> ToQueryable() + { + return ToQueryable().Select>(); + } + + private bool _isOnlySelectEntity = false; + public ISugarQueryable> ToQueryable(bool isOnlySelectEntity) + { + _isOnlySelectEntity = isOnlySelectEntity; + return ToQueryable(); + } + + private void Each(StringBuilder sb, List list) + { + int i = 0; + foreach (var item in list) + { + ++i; + var isLast = i == list.Count; + var isClass = typeof(T).IsClass(); + if (isClass) + { + ClassMethod(item, sb, isLast); + } + else + { + NoClassMethod(item, sb, isLast); + } + } + } + + private void ClassMethod(Y data, StringBuilder sb, bool isLast) + { + var columns = new StringBuilder(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + columns.Append(string.Join(",", entity.Columns.Where(it => it.IsIgnore == false).Select(it => GetSelect(it, data)))); + if (_isOnlySelectEntity == false) + { + columns.Append(",null as NoCacheColumn"); + } + sb.AppendLine(" SELECT " + columns.ToString()); + sb.Append(GetNextSql); + if (!isLast) + { + sb.AppendLine(" UNION ALL "); + } + } + + private string GetSelect(EntityColumnInfo it, Y data) + { + + return string.Format(" {0} AS {1} ", FormatValue(it.PropertyInfo.GetValue(data, null), it), queryBuilder.Builder.GetTranslationColumnName(it.PropertyName)); + } + + private void NoClassMethod(Y data, StringBuilder sb, bool isLast) + { + sb.AppendLine(" SELECT " + FormatValue(data)); + sb.Append(" AS " + this.queryBuilder.Builder.GetTranslationColumnName("ColumnName") + " "); + sb.Append(GetNextSql); + if (!isLast) + { + sb.AppendLine(" UNION ALL "); + } + } + public string GetNextSql + { + get + { + var isDual = queryBuilder.Builder.FullSqlDateNow?.ToLower()?.Contains(" dual") == true; + if (isDual) + { + return " from dual "; + } + else + { + return null; + } + } + } + private void Init() + { + if (datas.Count == 1) + { + var data = datas.First(); + isDates = data is ReportableDateType; + if (data is ReportableDateType) + { + var type = UtilMethods.ChangeType2(data, typeof(ReportableDateType)); + switch (type) + { + case ReportableDateType.MonthsInLast1years: + dates.AddRange(GetMonths(1)); + break; + case ReportableDateType.MonthsInLast3years: + dates.AddRange(GetMonths(3)); + break; + case ReportableDateType.MonthsInLast10years: + dates.AddRange(GetMonths(10)); + break; + case ReportableDateType.years1: + dates.AddRange(GetYears(1)); + break; + case ReportableDateType.years3: + dates.AddRange(GetYears(3)); + break; + case ReportableDateType.years10: + dates.AddRange(GetYears(10)); + break; + default: + break; + } + } + } + } + + private List GetYears(int v) + { + List result = new List(); + for (int i = 0; i < v; i++) + { + var year = (DateTime.Now.AddYears(i * -1).Year + "-01" + "-01").ObjToDate(); + result.Add(year); + } + return result; + } + private List GetMonths(int v) + { + List result = new List(); + var years = GetYears(v); + foreach (var item in years) + { + for (int i = 0; i < 12; i++) + { + result.Add(item.AddMonths(i)); + } + } + return result; + } + private object FormatValue(object value, EntityColumnInfo entityColumnInfo = null) + { + if (entityColumnInfo != null && entityColumnInfo.UnderType == UtilConstants.DateType && value == null && this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + return $" CAST( NULL AS DATETIME) "; + } + else if (entityColumnInfo != null && entityColumnInfo.UnderType == UtilConstants.DateType && value == null && this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + return $" CAST( NULL AS timestamp) "; + } + if (value == null) + return "null"; + var type = UtilMethods.GetUnderType(value.GetType()); + if (type.IsIn(typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(short), typeof(ushort))) + { + return value; + } + else if (type.IsIn(typeof(decimal), typeof(double))) + { + Expression, object>> exp = it => Convert.ToDecimal(it.ColumnName); + var result = queryBuilder.LambdaExpressions.DbMehtods.ToDecimal(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= formatBuilder.FormatValue(value) + } + } + }); + return result; + } + else if (type.IsIn(typeof(Guid))) + { + Expression, object>> exp = it => Convert.ToDecimal(it.ColumnName); + var result = queryBuilder.LambdaExpressions.DbMehtods.ToGuid(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= formatBuilder.FormatValue(value) + } + } + }); + return result; + } + else if (type.IsIn(typeof(DateTime)) || type.Name == "DateOnly") + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + return queryBuilder.LambdaExpressions.DbMehtods.Oracle_ToDate(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss").ToSqlValue() + }, + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= "yyyy-mm-dd hh24:mi:ss".ToSqlValue() + } + } + }); ; + } + //Expression, object>> exp = it => Convert.ToDecimal(it.ColumnName); + var result = queryBuilder.LambdaExpressions.DbMehtods.ToDate(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= formatBuilder.FormatValue(value) + } + } + }); + return result; + } + else + { + return formatBuilder.FormatValue(value); + } + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/SaveableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/SaveableProvider.cs new file mode 100644 index 000000000..4152ac440 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/SaveableProvider.cs @@ -0,0 +1,198 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class SaveableProvider : ISaveable where T : class, new() + { + internal SaveableProvider(SqlSugarProvider context, List saveObjects) + { + this.saveObjects = saveObjects; + this.Context = context; + this.Context.InitMappingInfo(); + } + internal SaveableProvider(SqlSugarProvider context, T saveObject) + { + this.saveObjects = new List() { saveObject }; + this.Context = context; + this.Context.InitMappingInfo(); + } + public SqlSugarProvider Context { get; set; } + public List saveObjects = new List(); + public List existsObjects = null; + public List insertObjects + { + get + { + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + List result = new List(); + var pks = GetPrimaryKeys(); + Check.Exception(pks.IsNullOrEmpty(), "Need primary key"); + Check.Exception(pks.Count > 1, "Multiple primary keys are not supported"); + var pkInfo = this.EntityInfo.Columns.Where(it => it.IsIgnore == false).Where(it => it.DbColumnName.Equals(pks.First(), StringComparison.CurrentCultureIgnoreCase)).First(); + var pkValues = saveObjects.Select(it => it.GetType().GetProperty(pkInfo.PropertyName).GetValue(it, null)); + if (existsObjects == null) + existsObjects = this.Context.Queryable().In(pkValues).ToList(); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + return saveObjects.Where(it => ! + existsObjects.Any(e => + e.GetType().GetProperty(pkInfo.PropertyName).GetValue(e, null).ObjToString() + == + it.GetType().GetProperty(pkInfo.PropertyName).GetValue(it, null).ObjToString())).ToList(); + } + } + public List updatObjects + { + get + { + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + List result = new List(); + var pks = GetPrimaryKeys(); + Check.Exception(pks.IsNullOrEmpty(), "Need primary key"); + Check.Exception(pks.Count > 1, "Multiple primary keys are not supported"); + var pkInfo = this.EntityInfo.Columns.Where(it => it.IsIgnore == false).Where(it => it.DbColumnName.Equals(pks.First(), StringComparison.CurrentCultureIgnoreCase)).First(); + var pkValues = saveObjects.Select(it => it.GetType().GetProperty(pkInfo.PropertyName).GetValue(it, null)); + if (existsObjects == null) + existsObjects = this.Context.Queryable().In(pkValues).ToList(); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + return saveObjects.Where(it => + existsObjects.Any(e => + e.GetType().GetProperty(pkInfo.PropertyName).GetValue(e, null).ObjToString() + == + it.GetType().GetProperty(pkInfo.PropertyName).GetValue(it, null).ObjToString())).ToList(); + } + } + + public IInsertable insertable { get; set; } + public IUpdateable updateable { get; set; } + + public EntityInfo EntityInfo + { + get + { + return this.Context.EntityMaintenance.GetEntityInfo(); + } + } + + #region Core + public int ExecuteCommand() + { + LoadInsertable(); + LoadUpdateable(); + var insertCount = 0; + var updateCount = 0; + if (insertable != null) + { + insertCount = insertable.ExecuteCommand(); + } + if (updateable != null) + { + updateCount = updateable.ExecuteCommand(); + } + return updateCount + insertCount; + } + + public T ExecuteReturnEntity() + { + LoadInsertable(); + LoadUpdateable(); + insertable?.ExecuteCommandIdentityIntoEntity(); + updateable?.ExecuteCommand(); + return saveObjects.First(); + } + + public List ExecuteReturnList() + { + LoadInsertable(); + LoadUpdateable(); + insertable?.ExecuteCommand(); + updateable?.ExecuteCommand(); + return saveObjects; + } + #endregion + #region Core Async + public Task ExecuteCommandAsync() + { + return Task.FromResult(ExecuteCommand()); + } + + public Task ExecuteReturnEntityAsync() + { + return Task.FromResult(ExecuteReturnEntity()); + } + + public Task> ExecuteReturnListAsync() + { + return Task.FromResult(ExecuteReturnList()); + } + #endregion + public ISaveable InsertColumns(Expression> columns) + { + LoadInsertable(); + this.insertable?.InsertColumns(columns); + return this; + } + + public ISaveable EnableDiffLogEvent(object businessData = null) + { + LoadInsertable(); + LoadUpdateable(); + this.insertable?.EnableDiffLogEvent(businessData); + this.updateable?.EnableDiffLogEvent(businessData); + return this; + } + + public ISaveable RemoveDataCache() + { + this.insertable?.RemoveDataCache(); + this.updateable?.RemoveDataCache(); + return this; + } + public ISaveable InsertIgnoreColumns(Expression> columns) + { + LoadInsertable(); + this.insertable?.IgnoreColumns(columns); + return this; + } + + public ISaveable UpdateColumns(Expression> columns) + { + LoadUpdateable(); + this.updateable?.UpdateColumns(columns); + return this; + } + + public ISaveable UpdateIgnoreColumns(Expression> columns) + { + LoadUpdateable(); + this.updateable?.IgnoreColumns(columns); + return this; + } + + public ISaveable UpdateWhereColumns(Expression> columns) + { + LoadUpdateable(); + this.updateable?.WhereColumns(columns); + return this; + } + protected virtual List GetPrimaryKeys() + { + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + private void LoadInsertable() + { + var temp = insertObjects; + if (insertable == null && temp.HasValue()) + insertable = this.Context.Insertable(temp); + } + private void LoadUpdateable() + { + var temp = updatObjects; + if (updateable == null && temp.HasValue()) + updateable = this.Context.Updateable(temp); + } + + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/Storageable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/Storageable.cs new file mode 100644 index 000000000..e4cfbb0d6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/Storageable.cs @@ -0,0 +1,628 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public class Storageable : IStorageable where T : class, new() + { + SqlSugarProvider Context { get; set; } + internal ISqlBuilder Builder; + List Parameters; + List> allDatas = new List>(); + List dbDataList = new List(); + List, bool>, string>> whereFuncs = new List, bool>, string>>(); + Expression> whereExpression; + Func formatTime; + DbLockType? lockType; + private string asname { get; set; } + private bool isDisableFilters = false; + public Storageable(List datas, SqlSugarProvider context) + { + this.Context = context; + if (datas == null) + datas = new List(); + this.allDatas = datas.Select(it => new StorageableInfo() + { + Item = it + }).ToList(); + } + + Expression> queryableWhereExp; + public IStorageable TableDataRange(Expression> exp) + { + this.queryableWhereExp = exp; + return this; + } + + public IStorageable SplitInsert(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Insert, conditions, message)); + return this; + } + public IStorageable SplitDelete(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Delete, conditions, message)); + return this; + } + public IStorageable SplitUpdate(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Update, conditions, message)); + return this; + } + + public IStorageable Saveable(string inserMessage = null, string updateMessage = null) + { + return this + .SplitUpdate(it => it.Any(), updateMessage) + .SplitInsert(it => true, inserMessage); + } + public IStorageable SplitError(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Error, conditions, message)); + return this; + } + + public IStorageable SplitIgnore(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Ignore, conditions, message)); + return this; + } + + public IStorageable DisableFilters() + { + this.isDisableFilters = true; + return this; + } + + public IStorageable TranLock(DbLockType dbLockType = DbLockType.Wait) + { + this.lockType = dbLockType; + return this; + } + public IStorageable TranLock(DbLockType? LockType) + { + if (LockType != null) + { + this.lockType = LockType; + return this; + } + else + { + return this; + } + } + public IStorageable SplitOther(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Other, conditions, message)); + return this; + } + public StorageablePage PageSize(int PageSize, Action ActionCallBack = null) + { + if (PageSize > 10000) + { + Check.ExceptionEasy("Advanced save page Settings should not exceed 10,000, and the reasonable number of pages is about 2000", "高级保存分页设置不要超过1万,合理分页数在2000左右"); + } + StorageablePage page = new StorageablePage(); + page.Context = this.Context; + page.PageSize = PageSize; + page.Data = this.allDatas.Select(it => it.Item).ToList(); + page.ActionCallBack = ActionCallBack; + page.TableName = this.asname; + page.whereExpression = this.whereExpression; + page.lockType = this.lockType; + return page; + } + public StorageableSplitProvider SplitTable() + { + StorageableSplitProvider result = new StorageableSplitProvider(); + result.Context = this.Context; + result.SaveInfo = this; + result.List = allDatas.Select(it => it.Item).ToList(); + result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(typeof(T)); + result.whereExpression = this.whereExpression; + return result; + } + public IStorageable DefaultAddElseUpdate() + { + var column = this.Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(it => it.IsPrimarykey); + if (column == null) Check.ExceptionEasy("DefaultAddElseUpdate() need primary key", "DefaultAddElseUpdate()这个方法只能用于主键"); + return this.SplitUpdate(it => + { + var itemPkValue = column.PropertyInfo.GetValue(it.Item); + var defaultValue = UtilMethods.GetDefaultValue(column.PropertyInfo.PropertyType); + var result = itemPkValue != null && itemPkValue.ObjToString() != defaultValue.ObjToString(); + return result; + + }).SplitInsert(it => true); + } + + public int ExecuteCommand() + { + var result = 0; + var x = this.ToStorage(); + result += x.AsInsertable.ExecuteCommand(); + var updateRow = x.AsUpdateable.ExecuteCommand(); + if (updateRow < 0) updateRow = 0; + result += updateRow; + return result; + } + public T ExecuteReturnEntity() + { + var x = this.ToStorage(); + if (x.InsertList?.Count > 0) + { + var data = x.AsInsertable.ExecuteReturnEntity(); + x.AsUpdateable.ExecuteCommand(); + return data; + } + else + { + x.AsInsertable.ExecuteCommand(); + x.AsUpdateable.ExecuteCommand(); + return x.UpdateList.FirstOrDefault()?.Item; + } + } + public async Task ExecuteReturnEntityAsync() + { + var x = this.ToStorage(); + if (x.InsertList.Count != 0) + { + var data = await x.AsInsertable.ExecuteReturnEntityAsync().ConfigureAwait(false); + await x.AsUpdateable.ExecuteCommandAsync().ConfigureAwait(false); + return data; + } + else + { + await x.AsInsertable.ExecuteCommandAsync().ConfigureAwait(false); + await x.AsUpdateable.ExecuteCommandAsync().ConfigureAwait(false); + return x.UpdateList.FirstOrDefault()?.Item; + } + } + public Task ExecuteCommandAsync(CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return ExecuteCommandAsync(); + } + public async Task ExecuteCommandAsync() + { + var result = 0; + var x = await ToStorageAsync().ConfigureAwait(false); + result += await x.AsInsertable.ExecuteCommandAsync().ConfigureAwait(false); + var updateCount = await x.AsUpdateable.ExecuteCommandAsync().ConfigureAwait(false); + if (updateCount < 0) + updateCount = 0; + result += updateCount; + return result; + } + public int ExecuteSqlBulkCopy() + { + var storage = this.ToStorage(); + return storage.BulkCopy() + storage.BulkUpdate(); + } + public async Task ExecuteSqlBulkCopyAsync() + { + var storage = await ToStorageAsync().ConfigureAwait(false); + return await storage.BulkCopyAsync().ConfigureAwait(false) + await storage.BulkUpdateAsync().ConfigureAwait(false); + } + public StorageableResult ToStorage() + { + if (whereFuncs == null || whereFuncs.Count == 0) + { + return this.Saveable().ToStorage(); + } + if (this.allDatas.Count == 0) + return new StorageableResult() + { + AsDeleteable = this.Context.Deleteable().AS(asname).Where(it => false), + AsInsertable = this.Context.Insertable(new List()).AS(asname), + AsUpdateable = this.Context.Updateable(new List()).AS(asname), + InsertList = new List>(), + UpdateList = new List>(), + DeleteList = new List>(), + ErrorList = new List>(), + IgnoreList = new List>(), + OtherList = new List>(), + TotalList = new List>() + }; + var pkInfos = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey); + if (whereExpression == null && !pkInfos.Any()) + { + Check.ExceptionEasy(true, "Need primary key or WhereColumn", "使用Storageable实体需要主键或者使用WhereColumn指定条件列"); + } + if (whereExpression == null && pkInfos.Any()) + { + this.Context.Utilities.PageEach(allDatas, 300, item => + { + var addItems = this.Context.Queryable().Filter(null, this.isDisableFilters).TranLock(this.lockType).AS(asname).WhereClassByPrimaryKey(item.Select(it => it.Item).ToList()).ToList(); + dbDataList.AddRange(addItems); + }); + } + var pkProperties = GetPkProperties(pkInfos); + var messageList = allDatas.Select(it => new StorageableMessage() + { + Item = it.Item, + Database = dbDataList, + PkFields = pkProperties + }).ToList(); + foreach (var item in whereFuncs.OrderByDescending(it => (int)it.key)) + { + List> whereList = messageList.Where(it => it.StorageType == null).ToList(); + Func, bool> exp = item.value1; + var list = whereList.Where(exp).ToList(); + foreach (var it in list) + { + it.StorageType = item.key; + it.StorageMessage = item.value2; + } + } + var delete = messageList.Where(it => it.StorageType == StorageType.Delete).ToList(); + var update = messageList.Where(it => it.StorageType == StorageType.Update).ToList(); + var inset = messageList.Where(it => it.StorageType == StorageType.Insert).ToList(); + var error = messageList.Where(it => it.StorageType == StorageType.Error).ToList(); + var ignore = messageList.Where(it => it.StorageType == StorageType.Ignore || it.StorageType == null).ToList(); + var other = messageList.Where(it => it.StorageType == StorageType.Other).ToList(); + StorageableResult result = new StorageableResult() + { + _WhereColumnList = wherecolumnList, + _AsName = asname, + _Context = this.Context, + AsDeleteable = this.Context.Deleteable().AS(asname), + AsUpdateable = this.Context.Updateable(update.Select(it => it.Item).ToList()).AS(asname), + AsInsertable = this.Context.Insertable(inset.Select(it => it.Item).ToList()).AS(asname), + OtherList = other, + InsertList = inset, + DeleteList = delete, + UpdateList = update, + ErrorList = error, + IgnoreList = ignore, + TotalList = messageList + }; + if (this.whereExpression != null) + { + result.AsUpdateable.WhereColumns(whereExpression); + result.AsDeleteable.WhereColumns(update.Select(it => it.Item).ToList(), whereExpression); + } + if (this.whereExpression != null) + { + result.AsDeleteable.WhereColumns(delete.Select(it => it.Item).ToList(), whereExpression); + } + else + { + result.AsDeleteable.Where(delete.Select(it => it.Item).ToList()); + } + return result; + } + + public StorageableResult GetStorageableResult() + { + if (whereFuncs == null || whereFuncs.Count == 0) + { + return this.Saveable().GetStorageableResult(); + } + if (this.allDatas.Count == 0) + return new StorageableResult() + { + //AsDeleteable = this.Context.Deleteable().AS(asname).Where(it => false), + //AsInsertable = this.Context.Insertable(new List()).AS(asname), + //AsUpdateable = this.Context.Updateable(new List()).AS(asname), + InsertList = new List>(), + UpdateList = new List>(), + DeleteList = new List>(), + ErrorList = new List>(), + IgnoreList = new List>(), + OtherList = new List>(), + TotalList = new List>() + }; + var pkInfos = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey); + if (whereExpression == null && !pkInfos.Any()) + { + Check.ExceptionEasy(true, "Need primary key or WhereColumn", "使用Storageable实体需要主键或者使用WhereColumn指定条件列"); + } + if (whereExpression == null && pkInfos.Any()) + { + this.Context.Utilities.PageEach(allDatas, 300, item => + { + var addItems = this.Context.Queryable().Filter(null, this.isDisableFilters).TranLock(this.lockType).AS(asname).WhereClassByPrimaryKey(item.Select(it => it.Item).ToList()).ToList(); + dbDataList.AddRange(addItems); + }); + } + var pkProperties = GetPkProperties(pkInfos); + var messageList = allDatas.Select(it => new StorageableMessage() + { + Item = it.Item, + Database = dbDataList, + PkFields = pkProperties + }).ToList(); + foreach (var item in whereFuncs.OrderByDescending(it => (int)it.key)) + { + List> whereList = messageList.Where(it => it.StorageType == null).ToList(); + Func, bool> exp = item.value1; + var list = whereList.Where(exp).ToList(); + foreach (var it in list) + { + it.StorageType = item.key; + it.StorageMessage = item.value2; + } + } + var delete = messageList.Where(it => it.StorageType == StorageType.Delete).ToList(); + var update = messageList.Where(it => it.StorageType == StorageType.Update).ToList(); + var inset = messageList.Where(it => it.StorageType == StorageType.Insert).ToList(); + var error = messageList.Where(it => it.StorageType == StorageType.Error).ToList(); + var ignore = messageList.Where(it => it.StorageType == StorageType.Ignore || it.StorageType == null).ToList(); + var other = messageList.Where(it => it.StorageType == StorageType.Other).ToList(); + StorageableResult result = new StorageableResult() + { + _WhereColumnList = wherecolumnList, + _AsName = asname, + _Context = this.Context, + //AsDeleteable = this.Context.Deleteable().AS(asname), + //AsUpdateable = this.Context.Updateable(update.Select(it => it.Item).ToList()).AS(asname), + //AsInsertable = this.Context.Insertable(inset.Select(it => it.Item).ToList()).AS(asname), + OtherList = other, + InsertList = inset, + DeleteList = delete, + UpdateList = update, + ErrorList = error, + IgnoreList = ignore, + TotalList = messageList + }; + //if (this.whereExpression != null) + //{ + // result.AsUpdateable.WhereColumns(whereExpression); + // result.AsDeleteable.WhereColumns(update.Select(it => it.Item).ToList(), whereExpression); + //} + //result.AsDeleteable.Where(delete.Select(it => it.Item).ToList()); + return result; + } + + public async Task> ToStorageAsync() + { + if (whereFuncs == null || whereFuncs.Count == 0) + { + return await Saveable().ToStorageAsync().ConfigureAwait(false); + } + if (this.allDatas.Count == 0) + return new StorageableResult() + { + AsDeleteable = this.Context.Deleteable().AS(asname).Where(it => false), + AsInsertable = this.Context.Insertable(new List()).AS(asname), + AsUpdateable = this.Context.Updateable(new List()).AS(asname), + InsertList = new List>(), + UpdateList = new List>(), + DeleteList = new List>(), + ErrorList = new List>(), + IgnoreList = new List>(), + OtherList = new List>(), + TotalList = new List>() + }; + var pkInfos = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey); + if (whereExpression == null && !pkInfos.Any()) + { + Check.Exception(true, "Need primary key or WhereColumn"); + } + if (whereExpression == null && pkInfos.Any()) + { + await Context.Utilities.PageEachAsync(allDatas, 300, async item => + { + var addItems = await Context.Queryable().Filter(null, isDisableFilters).AS(asname).TranLock(lockType).WhereClassByPrimaryKey(item.Select(it => it.Item).ToList()).ToListAsync().ConfigureAwait(false); + dbDataList.AddRange(addItems); + }).ConfigureAwait(false); + } + var pkProperties = GetPkProperties(pkInfos); + var messageList = allDatas.Select(it => new StorageableMessage() + { + Item = it.Item, + Database = dbDataList, + PkFields = pkProperties + }).ToList(); + foreach (var item in whereFuncs.OrderByDescending(it => (int)it.key)) + { + List> whereList = messageList.Where(it => it.StorageType == null).ToList(); + Func, bool> exp = item.value1; + var list = whereList.Where(exp).ToList(); + foreach (var it in list) + { + it.StorageType = item.key; + it.StorageMessage = item.value2; + } + } + var delete = messageList.Where(it => it.StorageType == StorageType.Delete).ToList(); + var update = messageList.Where(it => it.StorageType == StorageType.Update).ToList(); + var inset = messageList.Where(it => it.StorageType == StorageType.Insert).ToList(); + var error = messageList.Where(it => it.StorageType == StorageType.Error).ToList(); + var ignore = messageList.Where(it => it.StorageType == StorageType.Ignore || it.StorageType == null).ToList(); + var other = messageList.Where(it => it.StorageType == StorageType.Other).ToList(); + StorageableResult result = new StorageableResult() + { + _WhereColumnList = wherecolumnList, + _AsName = asname, + _Context = this.Context, + AsDeleteable = this.Context.Deleteable().AS(asname), + AsUpdateable = this.Context.Updateable(update.Select(it => it.Item).ToList()).AS(asname), + AsInsertable = this.Context.Insertable(inset.Select(it => it.Item).ToList()).AS(asname), + OtherList = other, + InsertList = inset, + DeleteList = delete, + UpdateList = update, + ErrorList = error, + IgnoreList = ignore, + TotalList = messageList + }; + if (this.whereExpression != null) + { + result.AsUpdateable.WhereColumns(whereExpression); + result.AsDeleteable.WhereColumns(delete.Select(it => it.Item).ToList(), whereExpression); + } + result.AsDeleteable.Where(delete.Select(it => it.Item).ToList()); + return result; + } + + + private string[] GetPkProperties(IEnumerable pkInfos) + { + if (whereExpression == null) + { + return pkInfos.Select(it => it.PropertyName).ToArray(); + } + else + { + return wherecolumnList.Select(it => it.PropertyName).ToArray(); + } + } + List wherecolumnList; + public IStorageable WhereColumns(Expression> columns, Func formatTime) + { + this.formatTime = formatTime; + return WhereColumns(columns); + } + public IStorageable WhereColumns(Expression> columns) + { + + if (columns == null) + return this; + else if (asname == null && typeof(T).GetCustomAttribute() != null) + { + whereExpression = columns; + return this; + } + else + { + List list = GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => Builder.GetNoTranslationColumnName(it)).ToList(); + var dbColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsIgnore == false); + var whereColumns = dbColumns.Where(it => list.Any(y => + it.DbColumnName.Equals(y, StringComparison.CurrentCultureIgnoreCase) || + it.PropertyName.Equals(y, StringComparison.CurrentCultureIgnoreCase)) + ).ToList(); + wherecolumnList = whereColumns; + if (whereColumns.Count == 0) + { + whereColumns = dbColumns.Where(it => it.IsPrimarykey).ToList(); + } + if (whereColumns.Count > 0) + { + if (queryableWhereExp == null) + { + this.Context.Utilities.PageEach(allDatas, 200, itemList => + { + List conditList = new List(); + SetConditList(itemList, whereColumns, conditList); + var addItem = this.Context.Queryable().AS(asname) + .Filter(null, this.isDisableFilters) + .TranLock(this.lockType) + .Where(conditList, true).ToList(); + this.dbDataList.AddRange(addItem); + }); + } + else + { + this.dbDataList.AddRange(this.Context.Queryable().AS(asname).Where(queryableWhereExp).ToList()); + } + } + this.whereExpression = columns; + return this; + } + } + + + public IStorageable WhereColumns(string[] columns) + { + var list = columns.Select(it => this.Context.EntityMaintenance.GetPropertyName(it)).ToList(); + var exp = ExpressionBuilderHelper.CreateNewFields(this.Context.EntityMaintenance.GetEntityInfo(), list); + return this.WhereColumns(exp); + } + public IStorageable WhereColumns(string[] columns, Func formatTime) + { + this.formatTime = formatTime; + return WhereColumns(columns); + } + private void SetConditList(List> itemList, List whereColumns, List conditList) + { + ; + foreach (var dataItem in itemList) + { + var condition = new ConditionalCollections() + { + ConditionalList = new List>() + }; + conditList.Add(condition); + int i = 0; + foreach (var item in whereColumns) + { + var value = item.PropertyInfo.GetValue(dataItem.Item, null); + if (value is string str && str == "null") + { + value = $"[null]"; + } + if (value?.GetType().IsEnum() == true) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + value = value.ToString(); + } + else + { + value = Convert.ToInt64(value); + } + } + if (item.SqlParameterDbType != null && item.SqlParameterDbType is Type && UtilMethods.HasInterface((Type)item.SqlParameterDbType, typeof(ISugarDataConverter))) + { + var columnInfo = item; + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 }) as SugarParameter; + value = p.Value; + } + condition.ConditionalList.Add(new KeyValuePair(i == 0 ? WhereType.Or : WhereType.And, new ConditionalModel() + { + FieldName = item.DbColumnName, + ConditionalType = ConditionalType.Equal, + CSharpTypeName = UtilMethods.GetTypeName(value), + FieldValue = value == null ? "null" : value.ObjToString(formatTime), + FieldValueConvertFunc = this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL ? + UtilMethods.GetTypeConvert(value) : null + })); + ++i; + } + } + } + + public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType) + { + ILambdaExpressions resolveExpress = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig); ; + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + resolveExpress.TableEnumIsString = this.Context.CurrentConnectionConfig.MoreSettings.TableEnumIsString; + resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + else + { + resolveExpress.PgSqlIsAutoToLower = true; + } + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + resolveExpress.InitMappingInfo = Context.InitMappingInfo; + resolveExpress.RefreshMapping = () => + { + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + }; + resolveExpress.Resolve(expression, resolveType); + if (this.Parameters == null) + this.Parameters = new List(); + this.Parameters.AddRange(resolveExpress.Parameters); + var result = resolveExpress.Result; + return result; + } + + public IStorageable As(string tableName) + { + this.asname = tableName; + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableDataTable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableDataTable.cs new file mode 100644 index 000000000..96b37de07 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableDataTable.cs @@ -0,0 +1,239 @@ +using System.Data; + +namespace SqlSugar +{ + public class StorageableDataTable + { + internal DataTable DataTable { get; set; } + internal SqlSugarProvider Context { get; set; } + internal string[] Columns { get; set; } = Array.Empty(); + internal string SugarGroupId = "SugarGroupId"; + internal string SugarUpdateRows = "SugarUpdateRows"; + internal string SugarColumns = "SugarColumns"; + internal string SugarErrorMessage = "SugarErrorMessage"; + internal List dbDataList = new List(); + internal Func formatTime; + List, string>> whereFuncs = new List, string>>(); + public StorageableDataTable WhereColumns(string name) + { + return WhereColumns(new string[] { name }); + } + public StorageableDataTable WhereColumns(string name, Func formatTime) + { + this.formatTime = formatTime; + return WhereColumns(new string[] { name }); + } + public StorageableDataTable WhereColumns(string[] names, Func formatTime) + { + this.formatTime = formatTime; + return WhereColumns(names); + } + public StorageableDataTable WhereColumns(string[] names) + { + this.Columns = names; + var queryable = this.Context.Queryable(); + Check.Exception(Columns == null || Columns.Length == 0, "need WhereColums"); + var tableName = queryable.SqlBuilder.GetTranslationTableName(DataTable.TableName); + this.Context.Utilities.PageEach(DataTable.Rows.Cast(), 200, itemList => + { + List conditList = new List(); + SetConditList(itemList, Columns, conditList); + string selector = null; + if (queryable.SqlBuilder.SqlParameterKeyWord == ":") + { + //Oracle driver bug: Error when querying DataTable after dynamically adding columns using '*'. + selector = " * /*" + Guid.NewGuid() + "*/"; + } + var addItem = this.Context.Queryable().AS(tableName).Where(conditList).Select(selector).ToDataTable().Rows.Cast().ToList(); + this.dbDataList.AddRange(addItem); + }); + return this; + } + public StorageableDataTable WhereColumns(List names) + { + return WhereColumns(names.ToArray()); + } + public StorageableDataTable SplitInsert(Func conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, string>(StorageType.Insert, conditions, message)); + return this; + } + public StorageableDataTable SplitDelete(Func conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, string>(StorageType.Delete, conditions, message)); + return this; + } + public StorageableDataTable SplitUpdate(Func conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, string>(StorageType.Update, conditions, message)); + return this; + } + + public StorageableDataTable Saveable(string inserMessage = null, string updateMessage = null) + { + SplitUpdate(it => it.Any(), updateMessage); + SplitInsert(it => true, inserMessage); + return this; + } + public StorageableDataTable SplitError(Func conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, string>(StorageType.Error, conditions, message)); + return this; + } + public StorageableDataTable SplitIgnore(Func conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, string>(StorageType.Ignore, conditions, message)); + return this; + } + + public DataTableResult ToStorage() + { + if (whereFuncs == null || whereFuncs.Count == 0) + { + Saveable(); + } + foreach (DataRow row in DataTable.Rows) + { + foreach (var item in whereFuncs.OrderByDescending(it => (int)it.key)) + { + SplitMethod(item.value1, item.key, row, item.value2); + } + if (row[SugarGroupId] == null || row[SugarGroupId] == DBNull.Value) + { + row[SugarGroupId] = StorageType.Ignore; + } + } + DataTable.Columns.Remove(SugarUpdateRows); + DataTable.Columns.Remove(SugarColumns); + var Groups = DataTable.Rows.Cast() + .Where(it => it[SugarGroupId] != null && it[SugarGroupId] != DBNull.Value) + .GroupBy(it => ((StorageType)it[SugarGroupId]).ToString()).Select(it => new DataTableGroups { Type = it.Key, DataTable = it.CopyToDataTable() }) + .ToList(); + DataTable.Columns.Remove(SugarGroupId); + DataTable.Columns.Remove(SugarErrorMessage); + var inserList = new List>(); + var updateList = new List>(); + var DeleteList = Groups.FirstOrDefault(it => it.Type == StorageType.Delete.ToString()); + if (Groups.Any(it => it.Type == StorageType.Insert.ToString())) + { + foreach (var item in Groups) + { + if (item.Type == StorageType.Insert.ToString()) + { + item.DataTable.Columns.Remove(SugarGroupId); + item.DataTable.Columns.Remove(SugarErrorMessage); + inserList.AddRange(this.Context.Utilities.DataTableToDictionaryList(item.DataTable)); + } + } + } + if (Groups.Any(it => it.Type == StorageType.Update.ToString())) + { + foreach (var item in Groups) + { + if (item.Type == StorageType.Update.ToString()) + { + item.DataTable.Columns.Remove(SugarGroupId); + item.DataTable.Columns.Remove(SugarErrorMessage); + updateList.AddRange(this.Context.Utilities.DataTableToDictionaryList(item.DataTable)); + } + } + } + List conditionalModels = new List(); + if (DeleteList != null) + { + SetConditList(DeleteList.DataTable.Rows.Cast().ToList(), Columns, conditionalModels); + } + var tableName = this.Context.Queryable().SqlBuilder.GetTranslationTableName(DataTable.TableName); + DataTableResult result = new DataTableResult() + { + DataTableGroups = Groups, + AsDeleteable = this.Context.Deleteable().AS(tableName).Where(conditionalModels), + AsUpdateable = this.Context.Updateable(updateList).AS(tableName).WhereColumns(Columns), + AsInsertable = this.Context.Insertable(inserList).AS(tableName) + }; + return result; + } + + private void SplitMethod(Func conditions, StorageType type, DataRow item, string message) + { + item[SugarColumns] = Columns; + item[SugarUpdateRows] = dbDataList; + if ((item[SugarGroupId] == null || item[SugarGroupId] == DBNull.Value) && conditions(item)) + { + item[SugarGroupId] = type; + item[SugarErrorMessage] = message; + } + } + private void SetConditList(List itemList, string[] whereColumns, List conditList) + { + ; + foreach (var dataItem in itemList) + { + var condition = new ConditionalCollections() + { + ConditionalList = new List>() + }; + conditList.Add(condition); + int i = 0; + foreach (var name in whereColumns) + { + var value = dataItem[name]; + if (value?.GetType().IsEnum() == true) + { + value = Convert.ToInt64(value); + } + condition.ConditionalList.Add(new KeyValuePair(i == 0 ? WhereType.Or : WhereType.And, new ConditionalModel() + { + FieldName = name, + ConditionalType = ConditionalType.Equal, + FieldValue = value.ObjToString(this.formatTime), + CSharpTypeName = value?.GetType()?.Name + })); + ++i; + } + } + } + } + + public class DataTableResult + { + public List DataTableGroups { get; set; } + public IUpdateable> AsUpdateable { get; set; } + public IDeleteable AsDeleteable { get; set; } + public IInsertable> AsInsertable { get; set; } + } + public class DataTableGroups + { + public string Type { get; set; } + public DataTable DataTable { get; set; } + } + public static class StorageableDataTableExtensions + { + public static bool Any(this DataRow row) + { + var list = row["SugarUpdateRows"] as List; + var columns = row["SugarColumns"] as string[]; + return list.Any(it => + { + var result = true; + foreach (var name in columns) + { + + if (result) + { + result = row[name].ObjToString() == it[name].ObjToString(); + if (result == false && it[name] != null && it[name].GetType() == UtilConstants.DecType) + { + result = row[name].ObjToDecimal() == it[name].ObjToDecimal(); + } + if (result == false) + { + break; + } + } + } + return result; + }); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableMethodInfo.cs new file mode 100644 index 000000000..90fe35f6a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableMethodInfo.cs @@ -0,0 +1,157 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class StorageableMethodInfo + { + internal SqlSugarProvider Context { get; set; } + internal MethodInfo MethodInfo { get; set; } + internal object objectValue { get; set; } + public int ExecuteCommand() + { + if (Context == null) return 0; + object objectValue = null; + MethodInfo method = GetSaveMethod(ref objectValue); + if (method == null) return 0; + return (int)method.Invoke(objectValue, Array.Empty()); + } + + public StorageableAsMethodInfo AsInsertable + { + get + { + var type = "AsInsertable"; + return GetAs(type); + } + } + public StorageableAsMethodInfo AsUpdateable + { + get + { + var type = "AsUpdateable"; + return GetAs(type); + } + } + + private StorageableAsMethodInfo GetAs(string type) + { + object objectValue = null; + MethodInfo method = GetSaveMethod(ref objectValue); + if (method == null) return new StorageableAsMethodInfo(null); + method = objectValue.GetType().GetMethod("ToStorage"); + objectValue = method.Invoke(objectValue, Array.Empty()); + StorageableAsMethodInfo result = new StorageableAsMethodInfo(type); + result.ObjectValue = objectValue; + result.Method = method; + return result; + } + + private MethodInfo GetSaveMethod(ref object callValue) + { + if (objectValue == null) + return null; + callValue = MethodInfo.Invoke(Context, new object[] { objectValue }); + return callValue.GetType().GetMyMethod("ExecuteCommand", 0); + } + + public StorageableMethodInfo ToStorage() + { + return this; + } + + public StorageableSplitTableMethodInfo SplitTable() + { + object objectValue = null; + MethodInfo method = GetSaveMethod(ref objectValue); + if (method == null) return new StorageableSplitTableMethodInfo(null); + method = objectValue.GetType().GetMethod("SplitTable"); + objectValue = method.Invoke(objectValue, Array.Empty()); + StorageableSplitTableMethodInfo result = new StorageableSplitTableMethodInfo(null); + result.ObjectValue = objectValue; + result.Method = method; + return result; + } + + public StorageableSplitTableMethodInfo AS(string tableName) + { + object objectValue = null; + MethodInfo method = GetSaveMethod(ref objectValue); + if (method == null) return new StorageableSplitTableMethodInfo(null); + method = objectValue.GetType().GetMyMethod("As", 1); + objectValue = method.Invoke(objectValue, new object[] { tableName }); + StorageableSplitTableMethodInfo result = new StorageableSplitTableMethodInfo(null); + result.ObjectValue = objectValue; + result.Method = method; + return result; + } + + public StorageableSplitTableMethodInfo WhereColumns(string[] strings) + { + object objectValue = null; + MethodInfo method = GetSaveMethod(ref objectValue); + if (method == null) return new StorageableSplitTableMethodInfo(null); + method = objectValue.GetType().GetMyMethod("WhereColumns", 1, typeof(string[])); + objectValue = method.Invoke(objectValue, new object[] { strings }); + StorageableSplitTableMethodInfo result = new StorageableSplitTableMethodInfo(null); + result.ObjectValue = objectValue; + result.Method = method; + return result; + } + } + + public class StorageableAsMethodInfo + { + private StorageableAsMethodInfo() { } + private string type; + public StorageableAsMethodInfo(string type) + { + this.type = type; + } + internal object ObjectValue { get; set; } + internal MethodInfo Method { get; set; } + public int ExecuteCommand() + { + if (type == null) return 0; + PropertyInfo property = ObjectValue.GetType().GetProperty(type); + var value = property.GetValue(ObjectValue); + var newObj = value.GetType().GetMethod("ExecuteCommand").Invoke(value, Array.Empty()); + return (int)newObj; + } + public StorageableCommonMethodInfo IgnoreColumns(params string[] ignoreColumns) + { + PropertyInfo property = ObjectValue?.GetType().GetProperty(type); + var value = property?.GetValue(ObjectValue); + var newObj = value?.GetType().GetMyMethod("IgnoreColumns", 1, typeof(string[])).Invoke(value, new object[] { ignoreColumns }); + StorageableCommonMethodInfo result = new StorageableCommonMethodInfo(); + result.Value = newObj; + return result; + } + } + public class StorageableCommonMethodInfo + { + public object Value { get; set; } + public int ExecuteCommand() + { + if (Value == null) return 0; + var newObj = Value.GetType().GetMethod("ExecuteCommand").Invoke(Value, Array.Empty()); + return (int)newObj; + } + } + + public class StorageableSplitTableMethodInfo + { + private StorageableSplitTableMethodInfo() { } + private string type; + public StorageableSplitTableMethodInfo(string type) + { + this.type = type; + } + internal object ObjectValue { get; set; } + internal MethodInfo Method { get; set; } + public int ExecuteCommand() + { + var newObj = ObjectValue.GetType().GetMethod("ExecuteCommand").Invoke(ObjectValue, Array.Empty()); + return (int)newObj; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageablePage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageablePage.cs new file mode 100644 index 000000000..2b77de3c8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageablePage.cs @@ -0,0 +1,151 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class StorageablePage where T : class, new() + { + internal DbLockType? lockType { get; set; } + + public SqlSugarProvider Context { get; set; } + public List Data { get; set; } + public int PageSize { get; internal set; } + public Action ActionCallBack { get; internal set; } + public string TableName { get; internal set; } + public Expression> whereExpression { get; internal set; } + + public int ExecuteCommand() + { + if (Data.Count == 1 && Data.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + this.Context.Utilities.PageEach(Data, PageSize, pageItem => + { + result += this.Context.Storageable(pageItem).As(TableName).TranLock(lockType).WhereColumns(whereExpression).ExecuteCommand(); + if (ActionCallBack != null) + { + ActionCallBack(result); + } + }); + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return result; + } + public async Task ExecuteCommandAsync(CancellationToken? cancellationToken = null) + { + if (cancellationToken != null) + this.Context.Ado.CancellationToken = cancellationToken.Value; + if (Data.Count == 1 && Data.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + await Context.Utilities.PageEachAsync(Data, PageSize, async pageItem => + { + result += await Context.Storageable(pageItem).As(TableName).TranLock(lockType).WhereColumns(whereExpression).ExecuteCommandAsync().ConfigureAwait(false); + if (ActionCallBack != null) + { + ActionCallBack(result); + } + }).ConfigureAwait(false); + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return result; + } + public int ExecuteSqlBulkCopy() + { + if (Data.Count == 1 && Data.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + + this.Context.Utilities.PageEach(Data, PageSize, pageItem => + { + result += this.Context.Storageable(pageItem).As(TableName).TranLock(lockType).WhereColumns(whereExpression).ExecuteSqlBulkCopy(); + if (ActionCallBack != null) + { + ActionCallBack(result); + } + }); + } + catch (Exception) + { + throw; + } + return result; + } + public async Task ExecuteSqlBulkCopyAsync(CancellationToken? cancellationToken = null) + { + if (cancellationToken != null) + this.Context.Ado.CancellationToken = cancellationToken.Value; + if (Data.Count == 1 && Data.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + await Context.Utilities.PageEachAsync(Data, PageSize, async pageItem => + { + result += await Context.Storageable(pageItem).As(TableName).TranLock(lockType).WhereColumns(whereExpression).ExecuteSqlBulkCopyAsync().ConfigureAwait(false); + if (ActionCallBack != null) + { + ActionCallBack(result); + } + }).ConfigureAwait(false); + } + catch (Exception) + { + throw; + } + return result; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableSplitProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableSplitProvider.cs new file mode 100644 index 000000000..fecae336a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SaveableProvider/StorageableSplitProvider.cs @@ -0,0 +1,205 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public class StorageableSplitProvider where T : class, new() + { + internal Storageable SaveInfo { get; set; } + internal SqlSugarProvider Context { get; set; } + internal List List { get; set; } + internal EntityInfo EntityInfo { get; set; } + internal Expression> whereExpression { get; set; } + + internal int pageSize = 1000; + internal Action ActionCallBack = null; + public StorageableSplitProvider PageSize(int size, Action ActionCallBack = null) + { + this.pageSize = size; + return this; + } + public int ExecuteCommand() + { + if (List.Count > pageSize) + { + var result = 0; + this.Context.Utilities.PageEach(List, pageSize, pageItem => + { + result += _ExecuteCommand(pageItem); + }); + return result; + } + else + { + var list = List; + return _ExecuteCommand(list); + } + + } + public int ExecuteSqlBulkCopy() + { + if (List.Count > pageSize) + { + var result = 0; + this.Context.Utilities.PageEach(List, pageSize, pageItem => + { + result += _ExecuteSqlBulkCopy(pageItem); + }); + return result; + } + else + { + var list = List; + return _ExecuteSqlBulkCopy(list); + } + + } + + + public async Task ExecuteCommandAsync() + { + if (List.Count > pageSize) + { + var result = 0; + await Context.Utilities.PageEachAsync(List, pageSize, async pageItem => + { + result += await _ExecuteCommandAsync(pageItem).ConfigureAwait(false); + if (ActionCallBack != null) + { + ActionCallBack(result); + } + }).ConfigureAwait(false); + return result; + } + else + { + var list = List; + return await _ExecuteCommandAsync(list).ConfigureAwait(false); + } + } + public async Task ExecuteSqlBulkCopyAsync() + { + if (List.Count > pageSize) + { + var result = 0; + await Context.Utilities.PageEachAsync(List, pageSize, async pageItem => + { + result += await _ExecuteSqlBulkCopyAsync(pageItem).ConfigureAwait(false); + if (ActionCallBack != null) + { + ActionCallBack(result); + } + }).ConfigureAwait(false); + return result; + } + else + { + var list = List; + return await _ExecuteSqlBulkCopyAsync(list).ConfigureAwait(false); + } + } + + + private async Task _ExecuteCommandAsync(List list) + { + int resultValue = 0; + List groupModels; + int result; + GroupDataList(list, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + resultValue += await Context.Storageable(addList).As(item.Key).WhereColumns(whereExpression).ExecuteCommandAsync().ConfigureAwait(false); + if (ActionCallBack != null) + { + ActionCallBack(resultValue); + } + } + return resultValue; + } + private int _ExecuteCommand(List list) + { + int resultValue = 0; + List groupModels; + int result; + GroupDataList(list, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + resultValue += this.Context.Storageable(addList).As(item.Key).WhereColumns(whereExpression).ExecuteCommand(); + } + return resultValue; + } + + private async Task _ExecuteSqlBulkCopyAsync(List list) + { + int resultValue = 0; + List groupModels; + int result; + GroupDataList(list, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + resultValue += await Context.Storageable(addList).As(item.Key).WhereColumns(whereExpression).ExecuteSqlBulkCopyAsync().ConfigureAwait(false); + if (ActionCallBack != null) + { + ActionCallBack(resultValue); + } + } + return resultValue; + } + private int _ExecuteSqlBulkCopy(List list) + { + int resultValue = 0; + List groupModels; + int result; + GroupDataList(list, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + resultValue += this.Context.Storageable(addList).As(item.Key).WhereColumns(whereExpression).ExecuteSqlBulkCopy(); + } + return resultValue; + } + + private void GroupDataList(List datas, out List groupModels, out int result) + { + var attribute = typeof(T).GetCustomAttribute() as SplitTableAttribute; + Check.Exception(attribute == null, $"{typeof(T).Name} need SplitTableAttribute"); + groupModels = new List(); + var db = this.Context; + foreach (var item in datas) + { + var value = db.SplitHelper().GetValue(attribute.SplitType, item); + var tableName = db.SplitHelper().GetTableName(attribute.SplitType, value); + groupModels.Add(new GroupModel() { GroupName = tableName, Item = item }); + } + var tablenames = groupModels.Select(it => it.GroupName).Distinct().ToList(); + CreateTable(tablenames); + result = 0; + } + private void CreateTable(List tableNames) + { + var isLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + foreach (var item in tableNames) + { + if (!this.Context.DbMaintenance.IsAnyTable(item, false)) + { + if (item != null) + { + this.Context.MappingTables.Add(EntityInfo.EntityName, item); + this.Context.CodeFirst.InitTables(); + } + } + } + this.Context.Ado.IsEnableLogEvent = isLog; + this.Context.MappingTables.Add(EntityInfo.EntityName, EntityInfo.DbTableName); + } + internal class GroupModel + { + public string GroupName { get; set; } + public T Item { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/DeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/DeleteBuilder.cs new file mode 100644 index 000000000..201d7980f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/DeleteBuilder.cs @@ -0,0 +1,181 @@ +using System.Linq.Expressions; +using System.Text; +namespace SqlSugar +{ + public class DeleteBuilder : IDMLBuilder + { + #region Fields + private List _WhereInfos; + #endregion + + #region Common Properties + public EntityInfo EntityInfo { get; set; } + public SqlSugarProvider Context { get; set; } + public ILambdaExpressions LambdaExpressions { get; set; } + public List Parameters { get; set; } + public StringBuilder sql { get; set; } + public ISqlBuilder Builder { get; set; } + public string TableWithString { get; set; } + public string AsName { get; set; } + public virtual List WhereInfos + { + get + { + _WhereInfos = UtilMethods.IsNullReturnNew(_WhereInfos); + return _WhereInfos; + } + set { _WhereInfos = value; } + } + public virtual List BigDataInValues { get; set; } + public virtual string BigDataFiled { get; set; } + #endregion + + #region Sql Template + public virtual string SqlTemplate + { + get + { + return "DELETE FROM {0}{1}"; + } + } + public string WhereInTemplate + { + get + { + return "{0} IN ({1})"; + } + } + public string WhereInOrTemplate + { + get + { + return "OR"; + } + } + public string WhereInAndTemplate + { + get + { + return "AND"; + } + } + public string WhereInEqualTemplate + { + get + { + return Builder.SqlTranslationLeft + "{0}" + Builder.SqlTranslationRight + "=N'{1}'"; + } + } + public string WhereInAreaTemplate + { + get + { + return "({0})"; + } + } + #endregion + + #region Get Sql + public virtual string GetTableNameString + { + get + { + var result = Builder.GetTranslationTableName(EntityInfo.EntityName); + if (AsName.HasValue()) + { + result = Builder.GetTranslationColumnName(AsName); + } + result += UtilConstants.Space; + if (this.TableWithString.HasValue()) + { + result += TableWithString + UtilConstants.Space; + } + return result; + } + } + public virtual string GetWhereString + { + get + { + if (_WhereInfos == null || _WhereInfos.Count == 0) return null; + string whereString = null; + int i = 0; + foreach (var item in _WhereInfos) + { + var isFirst = i == 0; + whereString += isFirst ? "WHERE " : "AND "; + whereString += (item + UtilConstants.Space); + ++i; + } + return whereString; + } + } + + #endregion + + #region Public methods + public virtual void Clear() + { + } + public virtual string ToSqlString() + { + if (this.BigDataInValues.IsNullOrEmpty()) + { + return string.Format(SqlTemplate, GetTableNameString, GetWhereString); + } + else//big data + { + var whereString = GetWhereString; + var sql = string.Format(SqlTemplate, GetTableNameString, whereString); + sql += whereString.IsNullOrEmpty() ? " WHERE " : " AND "; + StringBuilder batchDeleteSql = new StringBuilder(); + int pageSize = 1000; + int pageIndex = 1; + int totalRecord = this.BigDataInValues.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + var inValues = this.BigDataInValues.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); + batchDeleteSql.Append(sql + string.Format(WhereInTemplate, BigDataFiled, inValues.ToArray().ToJoinSqlInVals())); + batchDeleteSql.Append(';'); + pageIndex++; + } + return batchDeleteSql.ToString(); + } + } + public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType) + { + ILambdaExpressions resolveExpress = this.LambdaExpressions; + this.LambdaExpressions.Clear(); + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + resolveExpress.TableEnumIsString = this.Context.CurrentConnectionConfig.MoreSettings.TableEnumIsString; + resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + else + { + resolveExpress.PgSqlIsAutoToLower = true; + } + resolveExpress.SugarContext = new ExpressionOutParameter() { Context = this.Context }; + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + resolveExpress.InitMappingInfo = Context.InitMappingInfo; + resolveExpress.RefreshMapping = () => + { + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + }; + resolveExpress.Resolve(expression, resolveType); + if (this.Parameters == null) + this.Parameters = new List(); + this.Parameters.AddRange(resolveExpress.Parameters); + var result = resolveExpress.Result; + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/Entities.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/Entities.cs new file mode 100644 index 000000000..36345a0ba --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/Entities.cs @@ -0,0 +1,14 @@ +namespace SqlSugar +{ + public class ReSetValueBySqlExpListModel + { + public string DbColumnName { get; set; } + public string Sql { get; set; } + public ReSetValueBySqlExpListModelType? Type { get; set; } + } + public enum ReSetValueBySqlExpListModelType + { + Default, + List + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/InsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/InsertBuilder.cs new file mode 100644 index 000000000..6ef9e0449 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/InsertBuilder.cs @@ -0,0 +1,396 @@ +using System.Globalization; +using System.Linq.Expressions; +using System.Text; +namespace SqlSugar +{ + public partial class InsertBuilder : IDMLBuilder + { + #region Init + public InsertBuilder() + { + this.sql = new StringBuilder(); + this.Parameters = new List(); + this.DbColumnInfoList = new List(); + } + + #endregion + + #region Common Properties + public SqlSugarProvider Context { get; set; } + public ILambdaExpressions LambdaExpressions { get; set; } + public ISqlBuilder Builder { get; set; } + public StringBuilder sql { get; set; } + public List Parameters { get; set; } + public string TableWithString { get; set; } + public List DbColumnInfoList { get; set; } + public bool IsNoInsertNull { get; set; } + public bool IsReturnIdentity { get; set; } + public EntityInfo EntityInfo { get; set; } + public Dictionary OracleSeqInfoList { get; set; } + public bool IsBlukCopy { get; set; } + public virtual bool IsOleDb { get; set; } + public virtual Func ConvertInsertReturnIdFunc { get; set; } + public virtual bool IsNoPage { get; set; } + + public virtual bool IsReturnPkList { get; set; } + public string AsName { get; set; } + public bool IsOffIdentity { get; set; } + #endregion + + #region SqlTemplate + public virtual string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;SELECT SCOPE_IDENTITY();"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public virtual string SqlTemplateBatch + { + get + { + return "INSERT {0} ({1})"; + } + } + public virtual string SqlTemplateBatchSelect + { + get + { + return "{0} AS {1}"; + } + } + public virtual string SqlTemplateBatchUnion + { + get + { + return "\t\r\nUNION ALL "; + } + } + + #endregion + + #region Methods + + public virtual void ActionMinDate() + { + if (this.Parameters != null) + { + foreach (var item in this.Parameters) + { + if (item.DbType == System.Data.DbType.Date || item.DbType == System.Data.DbType.DateTime) + { + if (item.Value != null && item.Value != DBNull.Value) + { + if (item.Value is DateTime) + { + if (Convert.ToDateTime(item.Value) == DateTime.MinValue) + { + item.Value = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + } + } + } + } + } + } + } + public virtual void Clear() + { + + } + public virtual string GetTableNameString + { + get + { + if (AsName.HasValue()) + { + return Builder.GetTranslationTableName(AsName); + } + var result = Builder.GetTranslationTableName(EntityInfo.EntityName); + result += UtilConstants.Space; + if (this.TableWithString.HasValue()) + { + result += TableWithString + UtilConstants.Space; + } + return result; + } + } + + public bool MySqlIgnore { get; internal set; } + public bool IsWithAttr { get; internal set; } + public string[] ConflictNothing { get; set; } + + public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType) + { + ILambdaExpressions resolveExpress = this.LambdaExpressions; + this.LambdaExpressions.Clear(); + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + resolveExpress.TableEnumIsString = this.Context.CurrentConnectionConfig.MoreSettings.TableEnumIsString; + resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + else + { + resolveExpress.PgSqlIsAutoToLower = true; + } + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + resolveExpress.Resolve(expression, resolveType); + this.Parameters.AddRange(resolveExpress.Parameters); + var result = resolveExpress.Result; + return result; + } + public virtual 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 => this.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName))); + return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 200; + if (this.EntityInfo.Columns.Count > 30) + { + pageSize = 50; + } + else if (this.EntityInfo.Columns.Count > 20) + { + pageSize = 100; + } + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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, this.GetDbColumn(it, FormatValue(it.Value)), Builder.GetTranslationColumnName(it.DbColumnName))))); + ++i; + } + pageIndex++; + batchInsetrSql.Append("\r\n;\r\n"); + } + var result = batchInsetrSql.ToString(); + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + result += "select @@identity;"; + } + return result; + } + } + public virtual object FormatValue(object value) + { + var N = "N"; + if (this.Context.CurrentConnectionConfig.DbType == DbType.Sqlite) + { + N = ""; + } + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + 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") + "'"; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + Convert.ToHexString((byte[])value); + 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 if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return N + "'" + value.ToString().ToSqlFilter() + "'"; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.FloatType) + { + return N + "'" + Convert.ToDouble(value).ToString() + "'"; + } + else if (value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + else + { + return N + "'" + value.ToString() + "'"; + } + } + } + + public virtual string FormatDateTimeOffset(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + + private int GetDbColumnIndex = 0; + public virtual string GetDbColumn(DbColumnInfo columnInfo, object name) + { + if (columnInfo.InsertServerTime) + { + return LambdaExpressions.DbMehtods.GetDate(); + } + else if (UtilMethods.IsErrorDecimalString() == true) + { + var pname = Builder.SqlParameterKeyWord + "Decimal" + GetDbColumnIndex; + var p = new SugarParameter(pname, columnInfo.Value); + this.Parameters.Add(p); + GetDbColumnIndex++; + return pname; + } + else if (columnInfo.InsertSql.HasValue()) + { + if (columnInfo.InsertSql.Contains("{0}")) + { + if (columnInfo.Value == null) + { + return string.Format(columnInfo.InsertSql, "null").Replace("'null'", "null"); + } + else + { + return string.Format(columnInfo.InsertSql, columnInfo.Value?.ObjToString().ToSqlFilter()); + } + } + return columnInfo.InsertSql; + } + else if (columnInfo.SqlParameterDbType is Type && IsNoParameterConvert(columnInfo)) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(typeof(string)); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { columnInfo.Value, GetDbColumnIndex }) as SugarParameter; + return p.ParameterName; + } + else if (columnInfo.SqlParameterDbType is Type) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { columnInfo.Value, GetDbColumnIndex }) as SugarParameter; + GetDbColumnIndex++; + //this.Parameters.RemoveAll(it => it.ParameterName == it.ParameterName); + UtilMethods.ConvertParameter(p, this.Builder); + this.Parameters.Add(p); + return p.ParameterName; + } + else if (columnInfo.DataType?.Equals("nvarchar2") == true) + { + var pname = Builder.SqlParameterKeyWord + columnInfo.DbColumnName + "_ts" + GetDbColumnIndex; + var p = new SugarParameter(pname, columnInfo.Value); + p.IsNvarchar2 = true; + this.Parameters.Add(p); + GetDbColumnIndex++; + return pname; + } + else if (columnInfo.PropertyType?.Name == "TimeOnly") + { + var timeSpan = UtilMethods.TimeOnlyToTimeSpan(columnInfo.Value); + var pname = Builder.SqlParameterKeyWord + columnInfo.DbColumnName + "_ts" + GetDbColumnIndex; + this.Parameters.Add(new SugarParameter(pname, timeSpan)); + GetDbColumnIndex++; + return pname; + } + else if (columnInfo.PropertyType?.Name == "DateOnly") + { + var timeSpan = UtilMethods.DateOnlyToDateTime(columnInfo.Value); + var pname = Builder.SqlParameterKeyWord + columnInfo.DbColumnName + "_ts" + GetDbColumnIndex; + if (timeSpan == null) + { + this.Parameters.Add(new SugarParameter(pname, null) { DbType = System.Data.DbType.Date }); + } + else + { + this.Parameters.Add(new SugarParameter(pname, Convert.ToDateTime(timeSpan))); + } + GetDbColumnIndex++; + return pname; + } + else if (UtilMethods.IsErrorParameterName(this.Context.CurrentConnectionConfig, columnInfo)) + { + var pname = Builder.SqlParameterKeyWord + "CrorrPara" + GetDbColumnIndex; + var p = new SugarParameter(pname, columnInfo.Value); + this.Parameters.Add(p); + GetDbColumnIndex++; + return pname; + + } + else + { + return name + ""; + } + } + + private static bool IsNoParameterConvert(DbColumnInfo columnInfo) + { + if (columnInfo.SqlParameterDbType is Type t) + { + var isAssignableFrom = typeof(DbConvert.NoParameterCommonPropertyConvert).IsAssignableFrom(t); + if (isAssignableFrom) + { + return isAssignableFrom; + } + } + return (Type)columnInfo.SqlParameterDbType == UtilConstants.SqlConvertType; + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/QueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/QueryBuilder.cs new file mode 100644 index 000000000..a7ae7307b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/QueryBuilder.cs @@ -0,0 +1,1183 @@ +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public abstract class QueryBuilder : IDMLBuilder + { + + public QueryBuilder() + { + this.Parameters = new List(); + } + + #region Private Fileds + protected List _JoinQueryInfos; + protected Dictionary _EasyJoinInfos; + private List _WhereInfos; + private string _HavingInfos; + protected string _TableNameString; + #endregion + + #region Service object + public StringBuilder sql { get; set; } + public SqlSugarProvider Context { get; set; } + public ILambdaExpressions LambdaExpressions { get; set; } + public ISqlBuilder Builder { get; set; } + #endregion + + #region Splicing basic + public List GroupParameters { get; set; } + public string GroupBySql { get; set; } + public string GroupBySqlOld { get; set; } + public Type AsType { get; set; } + public bool IsParameterizedConstructor { get; set; } + public string Hints { get; set; } + internal AppendNavInfo AppendNavInfo { get; set; } + public Type[] RemoveFilters { get; set; } + public Dictionary SubToListParameters { get; set; } + internal List AppendColumns { get; set; } + internal List> AppendValues { get; set; } + public bool IsCrossQueryWithAttr { get; set; } + public Dictionary CrossQueryItems { get; set; } + public bool IsSelectSingleFiledJson { get; set; } + public bool IsSelectSingleFiledArray { get; set; } + public string TranLock { get; set; } + public bool IsDisableMasterSlaveSeparation { get; set; } + public bool IsEnableMasterSlaveSeparation { get; set; } + public bool IsQueryInQuery { get; set; } + public List Includes { get; set; } + public List IgnoreColumns { get; set; } + public bool IsCount { get; set; } + public bool IsSqlQuery { get; set; } + public bool IsSqlQuerySelect { get; set; } + public int? Skip { get; set; } + public int ExternalPageIndex { get; set; } + public int ExternalPageSize { get; set; } + public int? Take { get; set; } + public bool DisableTop { get; set; } + public string SampleBy { get; set; } + public string OrderByValue { get; set; } + public object SelectValue { get; set; } + public string SelectCacheKey { get; set; } + public string EntityName { get; set; } + public string OldSql { get; set; } + + public Type EntityType { get; set; } + public Type ResultType { get; set; } + public string TableWithString { get; set; } + public string GroupByValue { get; set; } + public string PartitionByValue { get; set; } + public int WhereIndex { get; set; } + public bool IsDistinct { get; set; } + public int JoinIndex { get; set; } + public bool IsDisabledGobalFilter { get; set; } + public virtual List Parameters { get; set; } + public Expression JoinExpression { get; set; } + public Dictionary EasyJoinInfos + { + get + { + _EasyJoinInfos = UtilMethods.IsNullReturnNew(_EasyJoinInfos); + return _EasyJoinInfos; + } + set { _EasyJoinInfos = value; } + } + public virtual List JoinQueryInfos + { + get + { + _JoinQueryInfos = UtilMethods.IsNullReturnNew(_JoinQueryInfos); + return _JoinQueryInfos; + } + set { _JoinQueryInfos = value; } + } + public virtual string TableShortName { get; set; } + public virtual List WhereInfos + { + get + { + _WhereInfos = UtilMethods.IsNullReturnNew(_WhereInfos); + return _WhereInfos; + } + set { _WhereInfos = value; } + } + public virtual string HavingInfos + { + get + { + return _HavingInfos; + } + set + { + _HavingInfos = value; + } + } + #endregion + + #region Lambada Type + public ResolveExpressType SelectType + { + get + { + return this.IsSingle() ? ResolveExpressType.SelectSingle : ResolveExpressType.SelectMultiple; + } + } + public ResolveExpressType WheretType + { + get + { + return this.IsSingle() ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple; + } + } + #endregion + + #region Sql Template + public Dictionary AsTables = new Dictionary(); + public virtual string SqlTemplate + { + get + { + if (this.SampleBy.HasValue()) + { + return "SELECT {0} FROM {1}{2} " + this.SampleBy + " {3}{4}"; + } + return "SELECT {0} FROM {1}{2}{3}{4} "; + } + } + public virtual string JoinTemplate + { + get + { + return "{0}JOIN {1}{2}ON {3} "; + } + } + public virtual string PageTempalte + { + get + { + return @"SELECT * FROM ({0}) T WHERE RowIndex BETWEEN {1} AND {2}"; + } + } + public virtual string ExternalPageTempalte + { + get + { + return @"SELECT * FROM ({0}) T WHERE RowIndex2 BETWEEN {1} AND {2}"; + } + } + public virtual string DefaultOrderByTemplate + { + get + { + return "ORDER BY " + this.Builder.SqlDateNow + " "; + } + } + public virtual string OrderByTemplate + { + get + { + return "ORDER BY "; + } + } + public virtual string GroupByTemplate + { + get + { + return "GROUP BY "; + } + } + public virtual string PartitionByTemplate + { + get + { + return "PARTITION BY "; + } + } + public virtual string MaxTemplate + { + get + { + return "MAX({0})"; + } + } + public virtual string MinTemplate + { + get + { + return "MIN({0})"; + } + } + public virtual string SumTemplate + { + get + { + return "SUM({0})"; + } + } + public virtual string AvgTemplate + { + get + { + return "AVG({0})"; + } + } + public virtual string InTemplate + { + get + { + return "{0} IN ({1}) "; + } + } + public virtual string EqualTemplate + { + get + { + return "{0} = {1} "; + } + } + #endregion + + #region Common Methods + public virtual bool IsSingle() + { + var isSingle = Builder.QueryBuilder.JoinQueryInfos.IsNullOrEmpty() && EasyJoinInfos.Count == 0; + return isSingle; + } + public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType) + { + ILambdaExpressions resolveExpress = this.LambdaExpressions; + if (resolveType.IsIn(ResolveExpressType.FieldSingle, ResolveExpressType.FieldMultiple, ResolveExpressType.SelectSingle, ResolveExpressType.SelectMultiple) && (expression is LambdaExpression) && (expression as LambdaExpression).Body is BinaryExpression) + { + resolveType = resolveType.IsIn(ResolveExpressType.SelectSingle, ResolveExpressType.FieldSingle) ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple; + } + this.LambdaExpressions.Clear(); + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + resolveExpress.TableEnumIsString = this.Context.CurrentConnectionConfig.MoreSettings.TableEnumIsString; + resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + else + { + resolveExpress.PgSqlIsAutoToLower = true; + } + resolveExpress.SugarContext = new ExpressionOutParameter() { Context = this.Context, QueryBuilder = this }; + resolveExpress.RootExpression = expression; + resolveExpress.JoinQueryInfos = Builder.QueryBuilder.JoinQueryInfos; + resolveExpress.IsSingle = IsSingle() && resolveType != ResolveExpressType.WhereMultiple; + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + resolveExpress.InitMappingInfo = this.Context.InitMappingInfo; + resolveExpress.RefreshMapping = () => + { + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + }; + resolveExpress.Resolve(expression, resolveType); + this.Parameters.AddRange(resolveExpress.Parameters.Select(it => new SugarParameter(it.ParameterName, it.Value, it.DbType) { Size = it.Size, TypeName = it.TypeName, IsNvarchar2 = it.IsNvarchar2 })); + var result = resolveExpress.Result; + var isSingleTableHasSubquery = IsSingle() && resolveExpress.SingleTableNameSubqueryShortName.HasValue(); + if (isSingleTableHasSubquery) + { + if (this.TableShortName?.StartsWith('\"') == true) + { + Check.Exception(!string.IsNullOrEmpty(this.TableShortName) && resolveExpress.SingleTableNameSubqueryShortName != this.TableShortName.TrimEnd('\"').TrimStart('\"'), "{0} and {1} need same name", resolveExpress.SingleTableNameSubqueryShortName, this.TableShortName); + this.TableShortName = resolveExpress.SingleTableNameSubqueryShortName; + } + else + { + Check.Exception(!string.IsNullOrEmpty(this.TableShortName) && resolveExpress.SingleTableNameSubqueryShortName != this.TableShortName, "{0} and {1} need same name", resolveExpress.SingleTableNameSubqueryShortName, this.TableShortName); + this.TableShortName = resolveExpress.SingleTableNameSubqueryShortName; + } + } + return result; + } + + internal string GetFilters(Type type) + { + var result = ""; + if (this.Context != null) + { + var db = Context; + BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; + var index = 0; + if (db.QueryFilter.GetFilterList != null) + { + foreach (var item in db.QueryFilter.GetFilterList) + { + if (this.RemoveFilters?.Length > 0) + { + if (this.RemoveFilters.Contains(item.type)) + { + continue; + } + } + + PropertyInfo field = item.GetType().GetProperty("exp", flag); + if (field != null) + { + Type ChildType = item.type; + var isInterface = ChildType.IsInterface && type.GetInterfaces().Any(it => it == ChildType); + if (ChildType == type || isInterface) + { + var entityInfo = db.EntityMaintenance.GetEntityInfo(ChildType); + var exp = field.GetValue(item, null) as Expression; + var whereStr = index == 0 ? " " : " AND "; + index++; + result += (whereStr + GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()); + if (isInterface) + { + result = ReplaceFilterColumnName(result, type); + } + } + } + } + } + } + return result; + } + + public virtual string ToSqlString() + { + string oldOrderBy = this.OrderByValue; + string externalOrderBy = oldOrderBy; + var isIgnoreOrderBy = this.IsCount && this.PartitionByValue.IsNullOrEmpty(); + AppendFilter(); + sql = new StringBuilder(); + if (this.OrderByValue == null && (Skip != null || Take != null)) this.OrderByValue = " ORDER BY GetDate() "; + if (this.PartitionByValue.HasValue()) + { + this.OrderByValue = this.PartitionByValue + this.OrderByValue; + } + var isRowNumber = Skip != null || Take != null; + var rowNumberString = string.Format(",ROW_NUMBER() OVER({0}) AS RowIndex ", GetOrderByString); + string groupByValue = GetGroupByString + HavingInfos; + string orderByValue = (!isRowNumber && this.OrderByValue.HasValue()) ? GetOrderByString : null; + if (isIgnoreOrderBy) { orderByValue = null; } + sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, groupByValue, orderByValue); + sql.Replace(UtilConstants.ReplaceKey, isRowNumber ? (isIgnoreOrderBy ? null : rowNumberString) : null); + if (isIgnoreOrderBy) { this.OrderByValue = oldOrderBy; return sql.ToString(); } + var result = ToPageSql(sql.ToString(), this.Take, this.Skip); + if (ExternalPageIndex > 0) + { + if (externalOrderBy.IsNullOrEmpty()) + { + externalOrderBy = " ORDER BY GetDate() "; + } + result = string.Format("SELECT *,ROW_NUMBER() OVER({0}) AS RowIndex2 FROM ({1}) ExternalTable ", GetExternalOrderBy(externalOrderBy), result); + result = ToPageSql2(result, ExternalPageIndex, ExternalPageSize, true); + } + this.OrderByValue = oldOrderBy; + return result; + } + + public virtual void AppendFilter() + { + if (!IsDisabledGobalFilter && this.Context.QueryFilter.GetFilterList.HasValue()) + { + var gobalFilterList = this.Context.QueryFilter.GetFilterList.Where(it => it.FilterName.IsNullOrEmpty()).ToList(); + if (this.RemoveFilters?.Length > 0) + { + gobalFilterList = gobalFilterList.Where(it => !this.RemoveFilters.Contains(it.type)).ToList(); + } + foreach (var item in gobalFilterList) + { + if (item.GetType().Name.StartsWith("TableFilterItem")) + { + AppendTableFilter(item); + } + } + foreach (var item in gobalFilterList.Where(it => it.GetType().Name == "SqlFilterItem").Where(it => it.IsJoinQuery == !IsSingle())) + { + var filterResult = item.FilterValue(this.Context); + WhereInfos.Add(this.Builder.AppendWhereOrAnd(this.WhereInfos.IsNullOrEmpty(), filterResult.Sql + UtilConstants.Space)); + var filterParamters = this.Context.Ado.GetParameters(filterResult.Parameters); + if (filterParamters.HasValue()) + { + this.Parameters.AddRange(filterParamters); + } + } + } + } + + private void AppendTableFilter(SqlFilterItem item) + { + BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; + Type type = item.GetType(); + PropertyInfo field = type.GetProperty("exp", flag); + Type ChildType = item.type; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(ChildType); + var exp = field.GetValue(item, null) as Expression; + var isMain = ChildType == this.EntityType || (ChildType.IsInterface && this.EntityType.GetInterfaces().Any(it => it == ChildType)); + var isSingle = IsSingle(); + var itName = (exp as LambdaExpression).Parameters[0].Name; + itName = this.Builder.GetTranslationColumnName(itName) + "."; + var isEasyJoin = this.EasyJoinInfos.Count > 0; + + string sql = ""; + if (isSingle) + { + if (ChildType.IsInterface && this.EntityType.GetInterfaces().Any(it => it == ChildType)) + { + //future + } + else if (ChildType != this.EntityType && isSingle) + { + return; + } + sql = GetSql(exp, isSingle); + if (ChildType.IsInterface) + { + var filterType = this.EntityType; + sql = ReplaceFilterColumnName(sql, filterType); + } + } + else if (isEasyJoin && ChildType.IsInterface && this.JoinExpression != null && (this.JoinExpression as LambdaExpression)?.Parameters?.Any(it => it.Type.GetInterfaces().Any(z => z == ChildType)) == true) + { + var parameters = (this.JoinExpression as LambdaExpression).Parameters.Where(it => it.Type.GetInterfaces().Any(z => z == ChildType)).ToList(); + foreach (var parameter in parameters) + { + var shortName = this.Builder.GetTranslationColumnName(parameter.Name) + "."; + var mysql = GetSql(exp, isSingle); + sql += mysql.Replace(itName, shortName); + var filterType = parameter.Type; + sql = ReplaceFilterColumnName(sql, filterType); + } + } + else if (isMain) + { + if (TableShortName == null) + return; + + var isSameName = !isSingle && JoinQueryInfos.Any(it => it.TableName == entityInfo.DbTableName); + if (isSameName || ChildType.IsInterface) + { + var mysql = GetSql(exp, isSingle); + if (ChildType.IsInterface && item.IsJoinQuery == true) + { + foreach (var joinInfoItem in this.JoinQueryInfos.Where(it => it.EntityType.GetInterfaces().Any(z => z == ChildType))) + { + var addSql = mysql.Replace(itName, this.Builder.GetTranslationColumnName(joinInfoItem.ShortName) + "."); + addSql = ReplaceFilterColumnName(addSql, joinInfoItem.EntityType, joinInfoItem.ShortName); + joinInfoItem.JoinWhere += (" AND " + Regex.Replace(addSql, "^ (WHERE|AND) ", "")); + } + } + else if (ChildType.IsInterface && item.IsJoinQuery == false) + { + { + var addSql = mysql.Replace(itName, this.Builder.GetTranslationColumnName(TableShortName) + "."); + addSql = ReplaceFilterColumnName(addSql, EntityType, TableShortName); + var andOrWhere = this.WhereInfos.Count != 0 ? " AND " : "WHERE"; + this.WhereInfos.Add(andOrWhere + Regex.Replace(addSql, "^ (WHERE|AND) ", "")); + } + foreach (var joinInfoItem in this.JoinQueryInfos.Where(it => it.EntityType.GetInterfaces().Any(z => z == ChildType))) + { + var addSql = mysql.Replace(itName, this.Builder.GetTranslationColumnName(joinInfoItem.ShortName) + "."); + addSql = ReplaceFilterColumnName(addSql, joinInfoItem.EntityType, joinInfoItem.ShortName); + this.WhereInfos.Add(" AND " + Regex.Replace(addSql, "^ (WHERE|AND) ", "")); + } + return; + } + else + { + foreach (var joinInfoItem in this.JoinQueryInfos.Where(it => it.TableName == entityInfo.DbTableName)) + { + var addSql = mysql.Replace(itName, this.Builder.GetTranslationColumnName(joinInfoItem.ShortName) + "."); + addSql = ReplaceFilterColumnName(addSql, joinInfoItem.EntityType, joinInfoItem.ShortName); + joinInfoItem.JoinWhere += (" AND " + Regex.Replace(addSql, "^ (WHERE|AND) ", "")); + } + } + sql = mysql.Replace(itName, this.Builder.GetTranslationColumnName(TableShortName) + "."); + } + else + { + var shortName = this.Builder.GetTranslationColumnName(TableShortName) + "."; + sql = GetSql(exp, isSingle); + sql = sql.Replace(itName, shortName); + } + + if (ChildType.IsInterface) + { + sql = ReplaceFilterColumnName(sql, this.EntityType); + } + } + else if (isEasyJoin) + { + var easyInfo = EasyJoinInfos.FirstOrDefault(it => + it.Value.Equals(entityInfo.DbTableName, StringComparison.CurrentCultureIgnoreCase) || + it.Value.Equals(entityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)); + if (easyInfo.Key == null) + { + return; + } + var shortName = this.Builder.GetTranslationColumnName(easyInfo.Key.Trim()) + "."; + sql = GetSql(exp, isSingle); + sql = sql.Replace(itName, shortName); + } + else + { + var easyInfo = JoinQueryInfos.FirstOrDefault(it => + it.TableName.Equals(entityInfo.DbTableName, StringComparison.CurrentCultureIgnoreCase) || + it.TableName.Equals(entityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase) || + it.EntityType == ChildType); + if (easyInfo == null) + { + if (ChildType.IsInterface && JoinQueryInfos.Any(it => it.EntityType?.GetInterfaces().Any(z => z == ChildType) == true)) + { + easyInfo = JoinQueryInfos.FirstOrDefault(it => it.EntityType.GetInterfaces().Any(z => z == ChildType)); + } + else + { + return; + } + } + var shortName = this.Builder.GetTranslationColumnName(easyInfo.ShortName.Trim()) + "."; + sql = GetSql(exp, isSingle); + sql = sql.Replace(itName, shortName); + } + if (item.IsJoinQuery == false || isMain || isSingle || isEasyJoin) + { + if (item.IsJoinQuery == false && ChildType.IsInterface) + { + foreach (var joinInfo in this.JoinQueryInfos) + { + sql = ReplaceFilterColumnName(sql, joinInfo.EntityType, Builder.GetTranslationColumnName(joinInfo.ShortName)); + } + } + WhereInfos.Add(sql); + } + else + { + var isSameName = !isSingle && this.JoinQueryInfos.Count(it => it.TableName == entityInfo.DbTableName) > 1; + foreach (var joinInfo in this.JoinQueryInfos) + { + var isInterface = ChildType.IsInterface && joinInfo.EntityType?.GetInterfaces().Any(it => it == ChildType) == true; + if (isInterface + && isSameName == false + && this.JoinQueryInfos.Where(it => it.EntityType != null).Count(it => it.EntityType.GetInterfaces().Any(z => z == ChildType)) > 1) + { + sql = GetSql(exp, false); + var shortName = this.Builder.GetTranslationColumnName(joinInfo.ShortName.Trim()) + "."; + sql = sql.Replace(itName, shortName); + } + if (isInterface || joinInfo.TableName.EqualCase(entityInfo.EntityName) || joinInfo.TableName.EqualCase(entityInfo.DbTableName) || joinInfo.EntityType == ChildType) + { + var mysql = sql; + if (isSameName) + { + var firstShortName = this.JoinQueryInfos.First(it => it.TableName == entityInfo.DbTableName).ShortName; + mysql = mysql.Replace(Builder.GetTranslationColumnName(firstShortName), Builder.GetTranslationColumnName(joinInfo.ShortName)); + } + if (mysql.StartsWith(" WHERE ")) + { + mysql = Regex.Replace(mysql, $"^ WHERE ", " AND "); + } + if (isInterface) + { + mysql = ReplaceFilterColumnName(mysql, joinInfo.EntityType, Builder.GetTranslationColumnName(joinInfo.ShortName)); + } + joinInfo.JoinWhere = joinInfo.JoinWhere + mysql; + } + } + } + } + + private string ReplaceFilterColumnName(string sql, Type filterType, string shortName = null) + { + foreach (var column in this.Context.EntityMaintenance.GetEntityInfoWithAttr(filterType).Columns.Where(it => it.IsIgnore == false)) + { + if (shortName == null) + { + sql = sql.Replace(Builder.GetTranslationColumnName(column.PropertyName), Builder.GetTranslationColumnName(column.DbColumnName)); + } + else + { + sql = sql.Replace(Builder.GetTranslationColumnName(shortName) + "." + Builder.GetTranslationColumnName(column.PropertyName), Builder.GetTranslationColumnName(shortName) + "." + Builder.GetTranslationColumnName(column.DbColumnName)); + sql = sql.Replace(shortName + "." + Builder.GetTranslationColumnName(column.PropertyName), shortName + "." + Builder.GetTranslationColumnName(column.DbColumnName)); + } + } + return sql; + } + + private string GetSql(Expression exp, bool isSingle) + { + var expValue = GetExpressionValue(exp, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); + var sql = expValue.GetResultString(); + if (WhereInfos.Count == 0) + { + sql = (" WHERE " + sql); + } + else + { + sql = (" AND " + sql); + } + + return sql; + } + + public virtual string GetExternalOrderBy(string externalOrderBy) + { + return Regex.Replace(externalOrderBy, @"\[\w+\]\.", ""); + } + + public virtual string ToCountSql(string sql) + { + if (sql?.Contains("-- No table") == true) + { + return "-- No table"; + } + return string.Format(" SELECT COUNT(1) FROM ({0}) CountTable ", sql); + } + + public virtual string ToPageSql(string sql, int? take, int? skip, bool isExternal = false) + { + string temp = isExternal ? ExternalPageTempalte : PageTempalte; + if (skip != null && take == null) + { + return string.Format(temp, sql.ToString(), skip.ObjToInt() + 1, long.MaxValue); + } + else if (skip == null && take != null) + { + return string.Format(temp, sql.ToString(), 1, take.ObjToInt()); + } + else if (skip != null && take != null) + { + return string.Format(temp, sql.ToString(), skip.ObjToInt() + 1, skip.ObjToInt() + take.ObjToInt()); + } + else + { + return sql.ToString(); + } + } + + public virtual string ToPageSql2(string sql, int? pageIndex, int? pageSize, bool isExternal = false) + { + string temp = isExternal ? ExternalPageTempalte : PageTempalte; + return string.Format(temp, sql.ToString(), (pageIndex - 1) * pageSize + 1, pageIndex * pageSize); + } + + public virtual string GetSelectByItems(List> items) + { + var array = items.Select(it => + { + JoinMapper dynamicObj = it.Value; + var dbName = Builder.GetTranslationColumnName(dynamicObj.DbName); + var asName = Builder.GetTranslationColumnName(dynamicObj.AsName); + return string.Format("{0}.{1} AS {2}", it.Key, dbName, asName); + }); + return string.Join(",", array); + } + + public virtual string ToJoinString(JoinQueryInfo joinInfo) + { + var name = joinInfo.TableName; + if (this.AsTables.Count != 0) + { + if (this.Context.MappingTables?.Any(it => it.DbTableName == name) == true) + { + name = this.Context.MappingTables.First(it => it.DbTableName == name).EntityName; + } + if (this.AsTables.Any(it => it.Key == name)) + { + name = this.AsTables.First(it => it.Key == name).Value; + } + } + var isSubQuery = name?.StartsWith('(') == true && name.EndsWith(')'); + var shortName = joinInfo.ShortName; + if (shortName.HasValue()) + { + shortName = this.Builder.GetTranslationColumnName(shortName); + } + var result = string.Format( + this.JoinTemplate, + joinInfo.JoinType.ToString() + UtilConstants.Space, + Builder.GetTranslationTableName(name) + UtilConstants.Space, + shortName + UtilConstants.Space + (TableWithString == SqlWith.Null || isSubQuery ? " " : TableWithString), + joinInfo.JoinWhere); + if (joinInfo.EntityType != null && this.Context.EntityMaintenance.GetEntityInfoWithAttr(joinInfo.EntityType).Discrimator.HasValue()) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(joinInfo.EntityType); + result = $" {result} AND {shortName}.{UtilMethods.GetDiscrimator(entityInfo, this.Builder)}"; + } + if (joinInfo.JoinType == JoinType.Cross) + { + + var onIndex = result.IndexOf(" ON "); + result = result.Substring(0, onIndex); + } + return result; + } + public virtual void Clear() + { + this.Skip = 0; + this.Take = 0; + this.sql = null; + this.WhereIndex = 0; + this.Parameters = null; + this.GroupByValue = null; + this._TableNameString = null; + this.WhereInfos = null; + this.JoinQueryInfos = null; + this.IsDistinct = false; + } + public virtual bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS \[\w+\.\w+\]") || Regex.IsMatch(sql, @"AS \[\w+\.\w+\.\w+\]"); + } + public string GetSqlQuerySql(string result) + { + if (this.Hints.HasValue()) + { + result = ReplaceHints(result); + } + if (GetTableNameString == " (-- No table ) t ") + { + result = "-- No table "; + return result; + } + if (this.IsSqlQuerySelect == true) + { + return result; + } + if (this.JoinQueryInfos.Count == 0 && string.IsNullOrEmpty(OrderByValue) && this.IsSqlQuery && this.OldSql.HasValue() && (Skip == null && Take == null) && (this.WhereInfos == null || this.WhereInfos.Count == 0)) + { + return this.OldSql; + } + else + { + return result; + } + } + + protected virtual string ReplaceHints(string result) + { + result = Regex.Replace(result, "^SELECT ", it => + { + return $"{it} {Hints} "; + }); + return result; + } + + protected string SubToListMethod(string result) + { + string oldResult = result; + List names = new List(); + var allShortName = new List(); + if (IsSingleSubToList()) + { + this.TableShortName = (SelectValue as LambdaExpression).Parameters[0].Name; + } + allShortName.Add(this.Builder.SqlTranslationLeft + Builder.GetNoTranslationColumnName(this.TableShortName.ObjToString().ToLower()) + this.Builder.SqlTranslationRight + "."); + if (this.JoinQueryInfos.HasValue()) + { + foreach (var item in this.JoinQueryInfos) + { + allShortName.Add(this.Builder.SqlTranslationLeft + Builder.GetNoTranslationColumnName(item.ShortName.ObjToString().ToLower()) + this.Builder.SqlTranslationRight + "."); + } + } + else if (this.EasyJoinInfos != null && this.EasyJoinInfos.Count != 0) + { + Check.ExceptionEasy("No Supprt Subquery.ToList(), Inner Join Or Left Join", "Subquery.ToList请使用Inner方式联表"); + } + if (this.TableShortName == null) + { + //Empty + } + else + { + var name = Builder.GetTranslationColumnName(this.TableShortName) + @"\."; + foreach (var paramter in this.SubToListParameters) + { + var regex = $@"\{Builder.SqlTranslationLeft}[\w]{{1,20}}?\{Builder.SqlTranslationRight}\.\{Builder.SqlTranslationLeft}.{{1,50}}?\{Builder.SqlTranslationRight}"; + var matches = Regex + .Matches(paramter.Value.ObjToString(), regex, RegexOptions.IgnoreCase).Cast() + .Where(it => allShortName.Any(z => it.Value.ObjToString().Contains(z, StringComparison.CurrentCultureIgnoreCase))) + .Select(it => it.Value).ToList(); + names.AddRange(matches); + } + int i = 0; + names = names.Distinct().ToList(); + if (names.Count != 0) + { + List colums = new List(); + foreach (var item in names) + { + result = (result + $",{item} as app_ext_col_{i}"); + colums.Add(new QueryableAppendColumn() { AsName = $"app_ext_col_{i}", Name = item, Index = i }); + i++; + } + this.AppendColumns = colums; + } + } + if (HasAppText(oldResult)) + { + return oldResult; + } + return result; + } + + #endregion + + #region Get SQL Partial + public string Offset { get; set; } + public virtual 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?.StartsWith("DISTINCT ") != true) + { + result = " DISTINCT " + result; + } + if (this.SubToListParameters != null && this.SubToListParameters.Count != 0) + { + result = SubToListMethod(result); + } + return result; + } + } + + public virtual string GetSelectValueByExpression() + { + var expression = this.SelectValue as Expression; + string result = string.Empty; + if (this.IgnoreColumns != null && this.IgnoreColumns.Count != 0) + { + var expArray = GetExpressionValue(expression, this.SelectType).GetResultArray() + .Where(it => + !this.IgnoreColumns.Any(z => it.Contains(Builder.GetTranslationColumnName(z))) + ).ToArray(); + result = string.Join(",", expArray); + } + else + { + result = GetExpressionValue(expression, this.SelectType).GetResultString(); + if (result == null && ExpressionTool.GetMethodName(ExpressionTool.GetLambdaExpressionBody(expression)) == "End") + { + result = GetExpressionValue(expression, ResolveExpressType.FieldSingle).GetResultString(); + } + } + if (result == null && this.AppendNavInfo?.AppendProperties == null) + { + return "*"; + } + if (this.AppendNavInfo?.AppendProperties?.Count > 0) + { + if (result == null) + { + result = "*"; + } + result += ","; + var shortName = ""; + if (this.TableShortName.HasValue()) + { + shortName = $"{Builder.GetTranslationColumnName(this.TableShortName)}."; + } + if (this.GroupByValue.HasValue()) + { + result += string.Join(",", this.AppendNavInfo.AppendProperties.Select(it => "max(" + shortName + Builder.GetTranslationColumnName(it.Value) + ") AS SugarNav_" + it.Key)); + } + else + { + result += string.Join(",", this.AppendNavInfo.AppendProperties.Select(it => shortName + Builder.GetTranslationColumnName(it.Value) + " AS SugarNav_" + it.Key)); + } + } + if (result.Contains("/**/*")) + { + return result.Replace("/**/*", ""); + } + if (this.IsSingle() && this.SubToListParameters != null && expression is LambdaExpression && this.SubToListParameters.Count > 0 && this.TableShortName == null) + { + this.TableShortName = this.Builder.GetTranslationColumnName((expression as LambdaExpression).Parameters[0].Name); + } + if (result.Contains(".*") && this.IsSingle()) + { + return "*"; + } + else + { + if (expression is LambdaExpression && (expression as LambdaExpression).Body is MethodCallExpression && this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer && this.OrderByValue.HasValue()) + { + result = result + " AS columnName"; + } + if (this.GroupParameters?.Count > 0 && this.GroupBySql.HasValue()) + { + var selectSql = UtilMethods.GetSqlString(DbType.SqlServer, result, UtilMethods.CopySugarParameters(this.Parameters).ToArray()); + if (selectSql.Contains(this.GroupBySql)) + { + result = selectSql; + this.GroupByIsReplace = true; + } + } + this.SelectCacheKey = result; + return result; + } + } + public virtual string GetSelectValueByString() + { + string result; + if (this.SelectValue.IsNullOrEmpty()) + { + string pre = null; + if (this.JoinQueryInfos.HasValue() && this.JoinQueryInfos.Any(it => TableShortName.HasValue())) + { + pre = Builder.GetTranslationColumnName(TableShortName) + "."; + } + else if (this.EasyJoinInfos?.Count > 0 && this.EasyJoinInfos.Any(it => TableShortName.HasValue())) + { + pre = Builder.GetTranslationColumnName(TableShortName) + "."; + } + var columns = this.Context.EntityMaintenance.GetEntityInfo(this.EntityType).Columns.Where(it => !it.IsIgnore); + if (this.IgnoreColumns.HasValue()) + { + columns = columns.Where(c => !this.IgnoreColumns.Any(i => c.PropertyName.Equals(i, StringComparison.CurrentCultureIgnoreCase) || c.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase))).ToList(); + } + result = string.Join(",", columns.Select(it => GetSelectStringByColumnInfo(it, pre))); + } + else + { + result = this.SelectValue.ObjToString(); + this.SelectCacheKey = result; + } + if (result.IsNullOrEmpty()) + { + result = "*"; + } + if (result.StartsWith(UtilConstants.GroupReplaceKey)) + { + this.GroupByIsReplace = true; + result = result.Replace(UtilConstants.GroupReplaceKey, string.Empty); + } + return result; + } + + private string GetSelectStringByColumnInfo(EntityColumnInfo it, string pre) + { + if (it.QuerySql.HasValue()) + { + return it.QuerySql + " AS " + Builder.GetTranslationColumnName(it.EntityName, it.PropertyName); + } + return pre + Builder.GetTranslationColumnName(it.EntityName, it.PropertyName); + } + + public virtual string GetWhereValueString + { + get + { + if (this.WhereInfos == null) return null; + else + { + return string.Join(UtilConstants.Space, this.WhereInfos); + } + } + } + public virtual string GetJoinValueString + { + get + { + if (this.JoinQueryInfos.IsNullOrEmpty()) return null; + else + { + return string.Join(UtilConstants.Space, this.JoinQueryInfos.Select(it => this.ToJoinString(it))); + } + } + } + public virtual string MasterDbTableName { get; set; } + public virtual string GetTableNameString + { + get + { + var name = EntityName; + if (this.AsTables.Any(it => it.Key == EntityName)) + { + name = this.AsTables.FirstOrDefault(it => it.Key == EntityName).Value; + if (this.IsQueryInQuery && this.SelectValue != null && this.SelectValue is Expression) + { + if (this.SelectValue.ToString().Contains("Subqueryable()") && name.TrimStart().StartsWith('(')) + { + var oldName = name; + name = Regex.Match(name, @"\(.+\)").Value; + if (name.IsNullOrEmpty()) + { + name = oldName; + } + } + } + } + var result = Builder.GetTranslationTableName(name); + result += UtilConstants.Space; + if (MasterDbTableName.HasValue()) + { + result = MasterDbTableName; + } + if (IsSingle() && result.Contains("MergeTable") && result.Trim().EndsWith(" MergeTable") && TableShortName != null) + { + result = result.Replace(") MergeTable ", ") " + this.Builder.GetTranslationColumnName(TableShortName) + UtilConstants.Space); + TableShortName = null; + } + if (IsSingle() && result.Contains("unionTable") && result.Trim().EndsWith(" unionTable") && TableShortName != null) + { + result = result.Replace(" ) unionTable ", ") " + TableShortName + UtilConstants.Space); + TableShortName = null; + } + if (this.TableShortName.HasValue() && !IsSqlQuery) + { + result += (Builder.GetTranslationColumnName(TableShortName) + UtilConstants.Space); + } + if (this.TableWithString.HasValue() && this.TableWithString != SqlWith.Null) + { + if (!result.TrimStart().StartsWith('(')) + { + result += TableWithString + UtilConstants.Space; + } + } + if (!this.IsSingle()) + { + result += GetJoinValueString + UtilConstants.Space; + } + if (this.EasyJoinInfos.IsValuable()) + { + + if (this.TableWithString.HasValue() && this.TableWithString != SqlWith.Null) + { + result += "," + string.Join(",", this.EasyJoinInfos.Select(it => string.Format("{0} {1} {2} ", GetTableName(it.Value), " " + Builder.GetTranslationColumnName(it.Key.ObjToString().Trim()), TableWithString))); + } + else + { + result += "," + string.Join(",", this.EasyJoinInfos.Select(it => string.Format("{0} {1} ", GetTableName(it.Value), " " + Builder.GetTranslationColumnName(it.Key.ObjToString().Trim())))); + } + } + return result; + } + } + public virtual string GetOrderByString + { + get + { + if (this.OrderByValue == null) return null; + if (IsCount && this.PartitionByValue.IsNullOrEmpty()) return null; + else + { + return this.OrderByValue; + } + } + } + public virtual string GetGroupByString + { + get + { + if (this.GroupByValue == null) return null; + if (this.GroupByValue.Last() != ' ') + { + return this.GroupByValue + UtilConstants.Space; + } + return this.GroupByValue; + } + } + + + #endregion + + #region NoCopy + + internal bool GroupByIsReplace { get; set; } + internal List QueryableFormats { get; set; } + internal bool IsClone { get; set; } + public bool NoCheckInclude { get; set; } + public virtual bool IsSelectNoAll { get; set; } = false; + public List AutoAppendedColumns { get; set; } + public Dictionary MappingKeys { get; set; } + public List> SelectNewIgnoreColumns { get; set; } + #endregion + + private string GetTableName(string entityName) + { + if (this.AsTables?.Any(it => it.Key == entityName) == true) + { + entityName = this.AsTables.First(it => it.Key == entityName).Value; + } + var result = this.Context.EntityMaintenance.GetTableName(entityName); + return this.Builder.GetTranslationTableName(result); + } + + public void CheckExpression(Expression expression, string methodName) + { + if (IsSingle() == false && this.JoinExpression != null) + { + var jsoinParameters = (this.JoinExpression as LambdaExpression).Parameters; + var currentParametres = (expression as LambdaExpression).Parameters; + if ((expression as LambdaExpression).Body.ToString() == "True") + { + return; + } + if (currentParametres?.Count > 0) + { + foreach (var item in currentParametres) + { + var index = currentParametres.IndexOf(item); + var name = item.Name; + var joinName = jsoinParameters[index].Name; + Check.Exception(!name.Equals(joinName, StringComparison.CurrentCultureIgnoreCase), ErrorMessage.ExpressionCheck, joinName, methodName, name); + } + } + } + } + public void CheckExpressionNew(Expression expression, string methodName) + { + if (IsSingle() == false && this.JoinExpression != null) + { + var jsoinParameters = (this.JoinExpression as LambdaExpression).Parameters; + var currentParametres = (expression as LambdaExpression).Parameters; + if ((expression as LambdaExpression).Body.ToString() == "True") + { + return; + } + if (currentParametres?.Count > 0) + { + if (jsoinParameters.Count + 1 != currentParametres.Count) + { + var str1 = "(" + string.Join(",", currentParametres.Select(it => it.Name)) + ")=>"; + var str2 = "(" + string.Join(",", jsoinParameters.Select(it => it.Name)) + "," + currentParametres.Last().Type.Name + " )=>"; + throw new Exception(ErrorMessage.GetThrowMessage($"Join {currentParametres.Last().Type.Name} error , Please change {str1} to {str2}.", $"Join {currentParametres.Last().Type.Name} 错误, 请把 {str1} 改成 {str2} ")); + } + foreach (var item in currentParametres.Take(jsoinParameters.Count)) + { + var index = currentParametres.IndexOf(item); + var name = item.Name; + var joinName = jsoinParameters[index].Name; + Check.Exception(!name.Equals(joinName, StringComparison.CurrentCultureIgnoreCase), ErrorMessage.ExpressionCheck, joinName, methodName, name); + } + } + } + } + private bool IsSingleSubToList() + { + return this.SubToListParameters != null + && this.TableShortName == null + && this.SelectValue is Expression + && this.IsSingle(); + } + private static bool HasAppText(string result) + { + return result.HasValue() && result.Contains("app_ext_col_0"); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderAccessory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderAccessory.cs new file mode 100644 index 000000000..ede17666b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderAccessory.cs @@ -0,0 +1,15 @@ +namespace SqlSugar +{ + public partial class SqlBuilderAccessory + { + protected DeleteBuilder _DeleteBuilder; + + protected InsertBuilder _InsertBuilder; + + protected QueryBuilder _QueryBuilder; + + protected SqlQueryBuilder _SqlQueryBuilder; + + protected UpdateBuilder _UpdateBuilder; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs new file mode 100644 index 000000000..36decdc25 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs @@ -0,0 +1,195 @@ +using System.Data; +using System.Data.Common; +using System.Text; +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + #region Properties + public SqlSugarProvider Context { get; set; } + public CommandType CommandType { get; set; } + public DeleteBuilder DeleteBuilder { get; set; } + public InsertBuilder InsertBuilder { get; set; } + public QueryBuilder QueryBuilder { get; set; } + public UpdateBuilder UpdateBuilder { get; set; } + public SqlQueryBuilder SqlQueryBuilder + { + get + { + base._SqlQueryBuilder = UtilMethods.IsNullReturnNew(base._SqlQueryBuilder); + return base._SqlQueryBuilder; + } + set { base._SqlQueryBuilder = value; } + } + #endregion + + #region abstract Methods + + public virtual bool SupportReadToken { get; set; } = true; + + public virtual Task GetReaderByToken(IDataReader dataReader, CancellationToken cancellationToken) + { + return ((DbDataReader)dataReader).ReadAsync(cancellationToken); + } + public virtual void ChangeJsonType(SugarParameter paramter) + { + + } + public virtual string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (!name.Contains("<>f__AnonymousType") && name.IsContainsIn("(", ")", SqlTranslationLeft) && name != "Dictionary`2") + { + var tableInfo = this.Context + .MappingTables? + .FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase)); + if (tableInfo != null) + { + return GetTranslationColumnName(tableInfo.DbTableName); + } + 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; + } + } + public virtual string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName + SqlTranslationRight); + } + + public virtual string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + if (propertyName.Contains('.')) + { + return string.Join(".", propertyName.Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else + return SqlTranslationLeft + propertyName + SqlTranslationRight; + } + + public virtual string GetNoTranslationColumnName(string name) + { + if (name.Contains('=')) + { + name = name.Split('=').First(); + } + if (!name.Contains(SqlTranslationLeft)) return name; + if (!name.Contains('.') && name.StartsWith(SqlTranslationLeft) && name.EndsWith(SqlTranslationRight)) + { + var result = name.TrimStart(Convert.ToChar(SqlTranslationLeft)).TrimEnd(Convert.ToChar(SqlTranslationRight)); + return result; + } + return name == null ? string.Empty : Regex.Match(name, @".*" + "\\" + SqlTranslationLeft + "(.*?)" + "\\" + SqlTranslationRight + "").Groups[1].Value; + } + public virtual string GetPackTable(string sql, string shortName) + { + return UtilMethods.GetPackTable(sql, shortName); + } + public virtual string GetDefaultShortName() + { + return "t"; + } + + + public string GetWhere(string fieldName, string conditionalType, int? parameterIndex = null) + { + return string.Format(" {0} {1} {2}{3} ", this.GetTranslationColumnName(fieldName), conditionalType, this.SqlParameterKeyWord, fieldName.Replace(".", "_") + parameterIndex); + } + public virtual string GetUnionAllSql(List sqlList) + { + return string.Join(" UNION ALL \r\n", sqlList); + } + public virtual string GetUnionSql(List sqlList) + { + return string.Join(" UNION \r\n", sqlList); + } + public virtual void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex) + { + UtilMethods.RepairReplicationParameters(ref appendSql, parameters, addIndex); + } + public virtual string GetUnionFomatSql(string sql) + { + return sql; + } + public virtual Type GetNullType(string tableName, string columnName) + { + return null; + } + + public virtual string RemoveParentheses(string sql) + { + return sql; + } + + private static object GetFieldValue(ConditionalModel item) + { + if (item.FieldValueConvertFunc != null) + { + return item.FieldValueConvertFunc(item.FieldValue); + } + else if (item.CSharpTypeName.HasValue()) + { + return UtilMethods.ConvertDataByTypeName(item.CSharpTypeName, item.FieldValue); + } + else + { + return item.FieldValue; + } + } + public virtual void FormatSaveQueueSql(StringBuilder sqlBuilder) + { + } + public virtual string RemoveN(string sql) + { + return sql; + } + #endregion + + #region Common SqlTemplate + public string AppendWhereOrAnd(bool isWhere, string sqlString) + { + return isWhere ? (" WHERE " + sqlString) : (" AND " + sqlString); + } + public string AppendHaving(string sqlString) + { + return " HAVING " + sqlString; + } + public virtual string SqlParameterKeyWord { get { return "@"; } } + public abstract string SqlTranslationLeft { get; } + public abstract string SqlTranslationRight { get; } + public virtual string SqlFalse { get { return "1=2 "; } } + public virtual string SqlDateNow { get { return "GETDATE()"; } } + public virtual string FullSqlDateNow { get { return "SELECT GETDATE()"; } } + public virtual string SqlSelectAll { get { return "*"; } } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderProvider_Condition.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderProvider_Condition.cs new file mode 100644 index 000000000..3d441a48c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlBuilderProvider_Condition.cs @@ -0,0 +1,457 @@ +using System.Data; +using System.Text; +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + #region Core + public KeyValuePair ConditionalModelToSql(List models, int beginIndex = 0) + { + if (models.IsNullOrEmpty()) return new KeyValuePair(); + StringBuilder builder = new StringBuilder(); + List parameters = new List(); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + var mainIndex = 0; + var indexTree = 0; + foreach (var model in models) + { + if (model is ConditionalModel) + { + var item = model as ConditionalModel; + if (item.CustomConditionalFunc != null) + { + var colIndex = mainIndex + beginIndex; + var colType = colIndex == 0 ? "" : "AND"; + var custom = item.CustomConditionalFunc.GetConditionalSql(item, colIndex); + parameters.AddRange(custom.Value); + builder.AppendFormat(" " + colType + " " + custom.Key); + mainIndex++; + continue; + } + else if (item.FieldName == UtilMethods.FieldNameSql()) + { + builder.Append(item.FieldValue); + continue; + } + var index = mainIndex + beginIndex; + var type = index == 0 ? "" : "AND"; + if (beginIndex > 0) + { + type = null; + } + string temp = " {0} {1} {2} {3} "; + string parameterName = string.Format("{0}Condit{1}{2}", sqlBuilder.SqlParameterKeyWord, item.FieldName, index); + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength > 0 && parameterName.Length > this.Context?.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength) + { + parameterName = string.Format("{0}Condit{1}{2}", sqlBuilder.SqlParameterKeyWord, item.FieldName.GetHashCode().ToString().Replace("-", ""), index); + } + if (parameterName.Contains('.')) + { + parameterName = parameterName.Replace(".", "_"); + } + if (parameterName.Contains('[')) + { + parameterName = parameterName.Replace('[', '_'); + } + if (parameterName.Contains(']')) + { + parameterName = parameterName.Replace(']', '_'); + } + if (!string.IsNullOrEmpty(this.SqlTranslationLeft) && parameterName.Contains(this.SqlTranslationLeft)) + { + parameterName = parameterName.Replace(this.SqlTranslationLeft, "_"); + } + string oldName = item.FieldName; + item.FieldName = GetTranslationColumnName(item.FieldName); + item.FieldName = item.FieldName.ToCheckField(); + var isILike = this.Context.CurrentConnectionConfig?.MoreSettings?.EnableILike == true; + switch (item.ConditionalType) + { + case ConditionalType.Equal: + Equal(builder, parameters, item, type, temp, parameterName); + break; + case ConditionalType.Like: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), isILike ? "ILIKE" : "LIKE", parameterName); + parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue + "%")); + break; + case ConditionalType.GreaterThan: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), ">", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + break; + case ConditionalType.GreaterThanOrEqual: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), ">=", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + break; + case ConditionalType.LessThan: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + break; + case ConditionalType.LessThanOrEqual: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<=", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + break; + case ConditionalType.In: + In(builder, item, type, temp); + //parameters.Add(new SugarParameter(parameterName, item.FieldValue)); + break; + case ConditionalType.NotIn: + NotIn(builder, parameters, item, type, temp, parameterName); + break; + case ConditionalType.LikeLeft: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), isILike ? "ILIKE" : "LIKE", parameterName); + parameters.Add(new SugarParameter(parameterName, item.FieldValue + "%")); + break; + case ConditionalType.NoLike: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), isILike ? "NOT ILIKE" : " NOT LIKE", parameterName); + parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue + "%")); + break; + case ConditionalType.LikeRight: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), isILike ? "ILIKE" : "LIKE", parameterName); + parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue)); + break; + case ConditionalType.NoEqual: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<>", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + break; + case ConditionalType.IsNullOrEmpty: + builder.AppendFormat(" {0} (({1}) OR ({2})) ", type, item.FieldName.ToSqlFilter() + " IS NULL ", item.FieldName.ToSqlFilter() + " = '' "); + parameters.Add(new SugarParameter(parameterName, item.FieldValue)); + break; + case ConditionalType.IsNot: + IsNot(builder, parameters, item, type, temp, parameterName); + break; + case ConditionalType.EqualNull: + EqualNull(builder, parameters, item, type, temp, parameterName); + break; + case ConditionalType.InLike: + InLike(builder, parameters, item, index, type, parameterName); + break; + case ConditionalType.Range: + Range(builder, parameters, item, index, type, parameterName); + break; + default: + break; + } + item.FieldName = oldName; + } + else if (model is ConditionalCollections) + { + var item = model as ConditionalCollections; + if (item?.ConditionalList.HasValue() == true) + { + foreach (var con in item.ConditionalList) + { + var index = item.ConditionalList.IndexOf(con); + var isFirst = index == 0; + var isLast = index == (item.ConditionalList.Count - 1); + if (models.IndexOf(item) == 0 && index == 0 && beginIndex == 0) + { + builder.AppendFormat(" ( "); + + } + else if (isFirst) + { + builder.AppendFormat(" {0} ( ", con.Key.ToString().ToUpper()); + } + List conModels = new List(); + conModels.Add(con.Value); + var childSqlInfo = ConditionalModelToSql(conModels, 1000 * (1 + index) + models.IndexOf(item)); + if (!isFirst && con.Value.FieldName != $"[value=sql{UtilConstants.ReplaceKey}]") + { + + builder.AppendFormat(" {0} ", con.Key.ToString().ToUpper()); + } + builder.Append(childSqlInfo.Key); + if (conModels?.FirstOrDefault() is ConditionalModel conModel) + { + if (conModel.CustomConditionalFunc != null) + { + builder.Replace(" AND ( AND", " AND ( "); + builder.Replace(" OR ( AND", " OR ( "); + builder.Replace(" ( AND ", " ( "); + builder.Replace(" ( OR ", " ( "); + builder.Replace(" OR AND ", " OR "); + builder.Replace(" AND AND ", " AND "); + } + } + parameters.AddRange(childSqlInfo.Value); + if (isLast) + { + builder.Append(" ) "); + } + else + { + + } + } + } + } + else + { + var item = model as ConditionalTree; + BuilderTree(builder, item, ref indexTree, parameters, ref mainIndex); + } + mainIndex++; + } + return new KeyValuePair(builder.ToString(), parameters.ToArray()); + } + + #endregion + + #region Case Method + private static void Range(StringBuilder builder, List parameters, ConditionalModel item, int index, string type, string parameterName) + { + var value = item.FieldValue; + var valueArray = (value + "").Split(','); + if (valueArray.Length != 2) + { + Check.ExceptionEasy($"The {item.FieldName} value is not a valid format, but is properly separated by a comma (1,2)", $"{item.FieldName} 值不是有效格式,正确是 1,2 这种中间逗号隔开"); + } + var firstValue = GetFieldValue(new ConditionalModel() { CSharpTypeName = item.CSharpTypeName, FieldValue = valueArray.FirstOrDefault() }); + var lastValue = GetFieldValue(new ConditionalModel() { CSharpTypeName = item.CSharpTypeName, FieldValue = valueArray.LastOrDefault() }); + var parameterNameFirst = parameterName + "_01"; + var parameterNameLast = parameterName + "_02"; + builder.AppendFormat("( {0}>={1} AND {0}<={2} )", item.FieldName.ToSqlFilter(), parameterNameFirst, parameterNameLast); + parameters.Add(new SugarParameter(parameterNameFirst, firstValue)); + parameters.Add(new SugarParameter(parameterNameLast, lastValue)); + } + private static void InLike(StringBuilder builder, List parameters, ConditionalModel item, int index, string type, string parameterName) + { + var array = (item.FieldValue + "").Split(',').ToList(); + List sqls = new List(); + int i = 0; + foreach (var val in array) + { + var itemParameterName = $"{parameterName}{index}{i}"; + sqls.Add(item.FieldName.ToSqlFilter() + " LIKE " + itemParameterName); + parameters.Add(new SugarParameter(itemParameterName, "%" + val + "%")); + i++; + } + builder.Append($" {type} ({string.Join(" OR ", sqls)}) "); + } + + private static void EqualNull(StringBuilder builder, List parameters, ConditionalModel item, string type, string temp, string parameterName) + { + if (GetFieldValue(item) == null || (item.FieldValue == null)) + { + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), " IS ", " NULL "); + } + else + { + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "=", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + } + } + + private static void IsNot(StringBuilder builder, List parameters, ConditionalModel item, string type, string temp, string parameterName) + { + if (item.FieldValue == null) + { + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), " IS NOT ", "NULL"); + } + else + { + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<>", parameterName); + parameters.Add(new SugarParameter(parameterName, item.FieldValue)); + } + } + + private static void NotIn(StringBuilder builder, List parameters, ConditionalModel item, string type, string temp, string parameterName) + { + if (item.FieldValue == null) item.FieldValue = string.Empty; + var inValue2 = ("(" + item.FieldValue.Split(',').ToJoinSqlInVals() + ")"); + if (item.CSharpTypeName.HasValue() && UtilMethods.IsNumber(item.CSharpTypeName)) + { + inValue2 = inValue2.Replace("'", ""); + } + else if (inValue2.Contains("'null'")) + { + inValue2 = inValue2.Replace("'null'", "null"); + } + if (inValue2.Contains("[null]")) + { + inValue2 = inValue2.Replace("[null]", "'null'"); + } + if (inValue2.Contains("[comma]")) + { + inValue2 = inValue2.Replace("[comma]", ","); + } + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "NOT IN", inValue2); + parameters.Add(new SugarParameter(parameterName, item.FieldValue)); + } + + private void In(StringBuilder builder, ConditionalModel item, string type, string temp) + { + if (item.FieldValue == null) item.FieldValue = string.Empty; + var inValue1 = string.Empty; + var inArray = item.FieldValue.Split(','); + var pageSize = 1000; + if (inArray.Length > pageSize && this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + { + InBig(builder, item, type, temp, inArray, pageSize); + return; + } + inValue1 = In_GetInValue(item, inArray); + if (item.CSharpTypeName.HasValue() && UtilMethods.IsNumber(item.CSharpTypeName)) + { + inValue1 = inValue1.Replace("'", ""); + } + else if (inValue1.Contains("'null'")) + { + inValue1 = inValue1.Replace("'null'", "null"); + } + if (inValue1.Contains("[comma]")) + { + inValue1 = inValue1.Replace("[comma]", ","); + } + if (inValue1.Contains("[null]")) + { + inValue1 = inValue1.Replace("[null]", "'null'"); + } + if (item.CSharpTypeName.EqualCase("guid") && inValue1 == "('')") + { + inValue1 = $"('{Guid.Empty.ToString()}')"; + } + else if (inValue1 == "()") + { + inValue1 = $"(NULL)"; + } + if (inArray.Length == 1 && inValue1 != "(null)") + { + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "=", inValue1.TrimStart('(').TrimEnd(')')); + } + else + { + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "IN", inValue1); + } + } + + private void InBig(StringBuilder builder, ConditionalModel item, string type, string temp, string[] inArray, int pageSize) + { + var sqlList = new List(); + this.Context.Utilities.PageEach(inArray, pageSize, items => + { + if (item.CSharpTypeName.EqualCase("string") || item.CSharpTypeName == null) + { + sqlList.Add("(" + item.FieldName.ToSqlFilter() + " IN (" + items.Distinct().ToArray().ToJoinSqlInVals() + "))"); + } + else + { + sqlList.Add("(" + item.FieldName.ToSqlFilter() + " IN (" + items.Select(it => string.IsNullOrEmpty(it) ? "null" : it).Distinct().ToArray().ToJoinSqlInVals() + "))"); + } + }); + var inValue1 = $" {string.Join(" OR ", sqlList)} "; + if (item.CSharpTypeName.HasValue() && UtilMethods.IsNumber(item.CSharpTypeName)) + { + inValue1 = inValue1.Replace("'", ""); + } + builder.AppendFormat(temp, type, "", " ", inValue1); + } + + private string In_GetInValue(ConditionalModel item, string[] inArray) + { + string inValue1; + if (item.CSharpTypeName.EqualCase("string") || item.CSharpTypeName == null) + { + inValue1 = ("(" + inArray.Distinct().ToArray().ToJoinSqlInVals() + ")"); + } + if (item.CSharpTypeName.EqualCase("bool") || item.CSharpTypeName.EqualCase("Boolean")) + { + var lam = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig); + lam.Context = this.Context; + var value = lam.DbMehtods.TrueValue(); + inValue1 = ("(" + string.Join(",", inArray.Distinct().ToArray()) + ")"); + if (value.EqualCase("true")) + { + inValue1 = inValue1.Replace("1", "true").Replace("0", "false"); + } + } + else + { + if (item.CSharpTypeName.EqualCase("nstring")) + { + inValue1 = ("(" + inArray.Select(it => string.IsNullOrEmpty(it) ? "null" : it).Distinct().ToArray().ToJoinSqlInValsByVarchar() + ")"); + } + else + { + inValue1 = ("(" + inArray.Select(it => string.IsNullOrEmpty(it) ? "null" : it).Distinct().ToArray().ToJoinSqlInVals() + ")"); + } + } + + return inValue1; + } + + private static void Equal(StringBuilder builder, List parameters, ConditionalModel item, string type, string temp, string parameterName) + { + if (item.FieldValue != null && item.FieldValue == "null" && item.FieldValue != "[null]") + { + builder.AppendFormat($" {item.FieldName.ToSqlFilter()} is null "); + } + else + { + if (item.FieldValue == "[null]") + { + item.FieldValue = "null"; + } + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "=", parameterName); + parameters.Add(new SugarParameter(parameterName, GetFieldValue(item))); + } + } + #endregion + + #region ConditionalCollections + private void BuilderTree(StringBuilder builder, ConditionalTree item, ref int indexTree, List parameters, ref int mainIndex) + { + var conditionals = ToConditionalCollections(item, ref indexTree, parameters); + var sqlobj = ConditionalModelToSql(new List { conditionals }, mainIndex); + var sql = sqlobj.Key; + RepairReplicationParameters(ref sql, sqlobj.Value, indexTree); + parameters.AddRange(sqlobj.Value); + var buiderSql = sql; + builder.Append(buiderSql); + indexTree++; + } + private ConditionalCollections ToConditionalCollections(ConditionalTree item, ref int indexTree, List parameters) + { + List> list = new List>(); + var index = 0; + foreach (var it in item.ConditionalList) + { + ConditionalModel model = new ConditionalModel(); + if (it.Value is ConditionalModel) + { + model = (ConditionalModel)it.Value; + } + else + { + var tree = it.Value as ConditionalTree; + var con = ToConditionalCollections(tree, ref indexTree, parameters); + var sqlobj = ConditionalModelToSql(new List { con }, index); + var sql = sqlobj.Key; + if (sql.StartsWith(" NULL ")) + { + sql = Regex.Replace(sql, "^ NULL ", it.Key.ToString().ToUpper()); + } + RepairReplicationParameters(ref sql, sqlobj.Value, indexTree); + model = new ConditionalModel() + { + FieldName = $"[value=sql{UtilConstants.ReplaceKey}]", + FieldValue = sql + }; + parameters.AddRange(sqlobj.Value); + indexTree++; + } + list.Add(new KeyValuePair(it.Key, model)); + index++; + } + var result = new ConditionalCollections() + { + ConditionalList = list + }; + return result; + } + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlQueryBuilder.cs new file mode 100644 index 000000000..ec9c63343 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/SqlQueryBuilder.cs @@ -0,0 +1,80 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SqlQueryBuilder : IDMLBuilder + { + + #region Fields + private string _Fields; + private StringBuilder _Sql; + private List _Parameters; + #endregion + + #region Properties + public SqlSugarProvider Context { get; set; } + public string Fields + { + get + { + if (this._Fields.IsNullOrEmpty()) + { + this._Fields = Regex.Match(this.sql.ObjToString().Replace("\n", string.Empty).Replace("\r", string.Empty).Trim(), @"select(.*?)from", RegexOptions.IgnoreCase).Groups[1].Value; + if (this._Fields.IsNullOrEmpty()) + { + this._Fields = "*"; + } + } + return this._Fields; + } + set + { + _Fields = value; + } + } + public StringBuilder sql + { + get + { + _Sql = UtilMethods.IsNullReturnNew(_Sql); + return _Sql; + } + set + { + _Sql = value; + } + } + public string SqlTemplate + { + get + { + return null; + } + } + public List Parameters + { + get + { + _Parameters = UtilMethods.IsNullReturnNew(_Parameters); + return _Parameters; + } + set + { + _Parameters = value; + } + } + #endregion + + #region Methods + public string ToSqlString() + { + return sql.ToString(); + } + public void Clear() + { + this.sql = null; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/UpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/UpdateBuilder.cs new file mode 100644 index 000000000..6012e2d91 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SqlBuilderProvider/UpdateBuilder.cs @@ -0,0 +1,614 @@ +using System.Globalization; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class UpdateBuilder : IDMLBuilder + { + public UpdateBuilder() + { + this.sql = new StringBuilder(); + this.DbColumnInfoList = new List(); + this.SetValues = new List>(); + this.WhereValues = new List(); + this.Parameters = new List(); + } + public SqlSugarProvider Context { get; set; } + public ILambdaExpressions LambdaExpressions { get; set; } + public ISqlBuilder Builder { get; set; } + public StringBuilder sql { get; set; } + public List Parameters { get; set; } + public string TableName { get; set; } + public string TableWithString { get; set; } + public List DbColumnInfoList { get; set; } + public List WhereValues { get; set; } + public string AppendWhere { get; set; } + public List> SetValues { get; set; } + public bool IsNoUpdateNull { get; set; } + public bool IsNoUpdateDefaultValue { get; set; } + public List PrimaryKeys { get; set; } + public List OldPrimaryKeys { get; set; } + public bool IsOffIdentity { get; set; } + public bool IsWhereColumns { get; set; } + public bool? IsListUpdate { get; set; } + public List UpdateColumns { get; set; } + public List IgnoreColumns { get; set; } + public List JoinInfos { get; set; } + public string ShortName { get; set; } + public Dictionary ReSetValueBySqlExpList { get; set; } + public virtual string ReSetValueBySqlExpListType { get; set; } + public EntityInfo EntityInfo { get; set; } + public virtual string SqlTemplate + { + get + { + return @"UPDATE {0} SET + {1} {2}"; + + } + } + + public virtual string SqlTemplateBatch + { + get + { + return @"UPDATE S SET {0} FROM {1} S {2} INNER JOIN "; + } + } + + public virtual string SqlTemplateJoin + { + get + { + return @" ( + {0} + + ) T ON {1} + ; "; + } + } + + public virtual string SqlTemplateBatchSet + { + get + { + return "{0} AS {1}"; + } + } + public virtual string SqlTemplateBatchSelect + { + get + { + return "{0} AS {1}"; + } + } + + public virtual string SqlTemplateBatchUnion + { + get + { + return "\t\t\r\nUNION ALL "; + } + } + + public virtual void Clear() + { + + } + public virtual string GetTableNameString + { + get + { + var result = Builder.GetTranslationTableName(TableName); + result += UtilConstants.Space; + if (this.TableWithString.HasValue()) + { + result += TableWithString + UtilConstants.Space; + } + return result; + } + } + public virtual string GetTableNameStringNoWith + { + get + { + var result = Builder.GetTranslationTableName(TableName); + return result; + } + } + + + public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType, bool isMapping = true) + { + ILambdaExpressions resolveExpress = this.LambdaExpressions; + this.LambdaExpressions.Clear(); + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + resolveExpress.TableEnumIsString = this.Context.CurrentConnectionConfig.MoreSettings.TableEnumIsString; + } + else + { + resolveExpress.PgSqlIsAutoToLower = true; + } + if (isMapping) + { + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + } + resolveExpress.InitMappingInfo = Context.InitMappingInfo; + resolveExpress.RefreshMapping = () => + { + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + }; + resolveExpress.SugarContext = new ExpressionOutParameter() { Context = this.Context }; + resolveExpress.Resolve(expression, resolveType); + this.Parameters.AddRange(resolveExpress.Parameters); + var result = resolveExpress.Result; + return result; + } + public virtual string ToSqlString() + { + if (IsNoUpdateNull) + { + DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null || (it.UpdateServerTime == true || !string.IsNullOrEmpty(it.UpdateSql))).ToList(); + } + if (IsNoUpdateDefaultValue) + { + DbColumnInfoList = DbColumnInfoList.Where(it => + { + if (it.Value.ObjToString() == "0" && it.PropertyType.IsEnum) + { + return it.Value.ObjToLong() != UtilMethods.DefaultForType(it.PropertyType).ObjToLong(); + } + else if (it.UpdateServerTime == true || !string.IsNullOrEmpty(it.UpdateSql)) + { + return true; + } + else + { + return it.Value.ObjToString() != UtilMethods.DefaultForType(it.PropertyType).ObjToString(); + } + + }).ToList(); + } + var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList(); + var isSingle = groupList.Count == 1; + if (isSingle && this.IsListUpdate == null) + { + ActionMinDate(); + return ToSingleSqlString(groupList); + } + else + { + return TomultipleSqlString(groupList); + } + } + + protected virtual string TomultipleSqlString(List> groupList) + { + Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List need Primary key"); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + StringBuilder batchUpdateSql = new StringBuilder(); + while (pageCount >= pageIndex) + { + StringBuilder updateTable = new StringBuilder(); + string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName)); + return result; + })); + batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString); + int i = 0; + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) + { + updateTable.Append(SqlTemplateBatchUnion); + } + updateTable.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, FormatValue(it.Value), Builder.GetTranslationColumnName(it.DbColumnName))))); + ++i; + } + pageIndex++; + updateTable.Append("\r\n"); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += Regex.Replace(item, "\\" + this.Builder.SqlTranslationLeft, "S." + this.Builder.SqlTranslationLeft); + } + } + if (PrimaryKeys.HasValue()) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(item)); + } + } + batchUpdateSql.AppendFormat(SqlTemplateJoin, updateTable, whereString); + } + return batchUpdateSql.ToString(); + } + + protected virtual string ToSingleSqlString(List> groupList) + { + string columnsString = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName) || sv.Key == Builder.GetTranslationColumnName(it.PropertyName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + else if (JoinInfos != null && JoinInfos.Count != 0) + { + setValue = SetValues.Where(sv => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Where(sv => sv.Key == Builder.GetNoTranslationColumnName(it.DbColumnName) || sv.Key == Builder.GetNoTranslationColumnName(it.PropertyName)); + return Builder.GetTranslationColumnName(this.ShortName) + "." + Builder.GetTranslationColumnName(setValue.First().Key) + "=" + setValue.First().Value; + } + } + var result = Builder.GetTranslationColumnName(it.DbColumnName) + "=" + GetDbColumn(it, this.Context.Ado.SqlParameterKeyWord + it.DbColumnName); + return result; + })); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? " WHERE " : " AND "); + whereString += item; + } + } + else if (PrimaryKeys.HasValue()) + { + if (IsWhereColumns == false) + { + int i = 100000; + foreach (var item in PrimaryKeys) + { + i++; + var isFirst = whereString == null; + whereString += (isFirst ? " WHERE " : " AND "); + var pkIsSugarDataConverter = GetPkIsSugarDataConverter(); + if (pkIsSugarDataConverter && GetColumnInfo(item) != null) + { + var columnInfo = GetColumnInfo(item); + var value = this.DbColumnInfoList.FirstOrDefault(it => it.DbColumnName.EqualCase(item) || it.PropertyName.EqualCase(item))?.Value; + var p = UtilMethods.GetParameterConverter(i, this.Context, value, this.EntityInfo, this.EntityInfo?.Columns.First(it => it.DbColumnName.Equals(item) || it.PropertyName.Equals(item))); + whereString += Builder.GetTranslationColumnName(item) + "=" + p.ParameterName; + this.Parameters.Add(p); + } + else + { + whereString += Builder.GetTranslationColumnName(item) + "=" + this.Context.Ado.SqlParameterKeyWord + item; + var columnInfo = GetColumnInfo(item); + if (columnInfo?.SqlParameterDbType is System.Data.DbType valueDbType) + { + var p = this.Parameters?.FirstOrDefault(it => it.ParameterName == this.Context.Ado.SqlParameterKeyWord + item); + if (p != null) + { + p.DbType = valueDbType; + } + } + } + } + } + } + if (PrimaryKeys.HasValue() && IsWhereColumns) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? " WHERE " : " AND "); + whereString += Builder.GetTranslationColumnName(item) + "=" + this.Context.Ado.SqlParameterKeyWord + item; + } + } + if (this.JoinInfos != null && this.JoinInfos.Count != 0) + { + return GetJoinUpdate(columnsString, ref whereString); + } + return string.Format(SqlTemplate, GetTableNameString, columnsString, whereString); + } + + private EntityColumnInfo GetColumnInfo(string item) + { + var columnInfo = this.EntityInfo?.Columns?.FirstOrDefault(it => it.DbColumnName.EqualCase(item) || it.PropertyName.EqualCase(item)); + return columnInfo; + } + + private bool GetPkIsSugarDataConverter() + { + return this.EntityInfo?.Columns.Any(it => it.IsPrimarykey && it.SqlParameterDbType is Type && typeof(ISugarDataConverter).IsAssignableFrom((it.SqlParameterDbType as Type))) == true; + } + + protected virtual string GetJoinUpdate(string columnsString, ref string whereString) + { + var tableName = Builder.GetTranslationColumnName(this.TableName); + this.TableName = Builder.GetTranslationColumnName(this.ShortName); + var joinString = $" FROM {tableName} {Builder.GetTranslationColumnName(this.ShortName)} "; + foreach (var item in this.JoinInfos) + { + joinString += $"\r\n JOIN {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} ON {item.JoinWhere} "; + } + whereString = joinString + "\r\n" + whereString; + return string.Format(SqlTemplate, GetTableNameString, columnsString, whereString); + } + + public virtual void ActionMinDate() + { + if (this.Parameters != null) + { + foreach (var item in this.Parameters) + { + if (item.DbType == System.Data.DbType.Date || item.DbType == System.Data.DbType.DateTime) + { + if (item.Value != null && item.Value != DBNull.Value) + { + if (item.Value is DateTime) + { + if (Convert.ToDateTime(item.Value) == DateTime.MinValue) + { + item.Value = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + } + } + } + } + } + } + } + public virtual object FormatValue(object value) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + 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") + "'"; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + Convert.ToHexString((byte[])value); + 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 if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "N'" + value.ToString().ToSqlFilter() + "'"; + } + else if (type == UtilConstants.IntType || type == UtilConstants.LongType) + { + return value; + } + else if (UtilMethods.IsNumber(type.Name)) + { + if (value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + if (value.ObjToString().Contains(',')) + { + return $"'{value}'"; + } + else + { + return value; + } + } + else + { + return "N'" + value.ToString() + "'"; + } + } + } + + public virtual string FormatDateTimeOffset(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + private int GetDbColumnIndex = 0; + public virtual string GetDbColumn(DbColumnInfo columnInfo, object name) + { + if (columnInfo.UpdateServerTime) + { + return LambdaExpressions.DbMehtods.GetDate(); + } + else if (columnInfo.PropertyType.FullName == "NetTopologySuite.Geometries.Geometry") + { + var pname = Builder.SqlParameterKeyWord + "Geometry" + GetDbColumnIndex; + var p = new SugarParameter(pname, columnInfo.Value); + p.DbType = System.Data.DbType.Object; + this.Parameters.Add(p); + GetDbColumnIndex++; + return pname; + } + else if (UtilMethods.IsErrorDecimalString() == true) + { + var pname = Builder.SqlParameterKeyWord + "Decimal" + GetDbColumnIndex; + var p = new SugarParameter(pname, columnInfo.Value); + this.Parameters.Add(p); + GetDbColumnIndex++; + return pname; + } + else if (IsListSetExp(columnInfo) || IsSingleSetExp(columnInfo)) + { + if (this.ReSetValueBySqlExpList[columnInfo.PropertyName].Type == ReSetValueBySqlExpListModelType.List) + { + return Builder.GetTranslationColumnName(columnInfo.DbColumnName) + this.ReSetValueBySqlExpList[columnInfo.PropertyName].Sql + name; + } + else + { + return this.ReSetValueBySqlExpList[columnInfo.PropertyName].Sql; + } + } + else if (columnInfo.UpdateSql.HasValue()) + { + if (columnInfo.UpdateSql.Contains("{0}")) + { + if (columnInfo.Value == null) + { + return string.Format(columnInfo.UpdateSql, "null").Replace("'null'", "null"); + } + else + { + return string.Format(columnInfo.UpdateSql, columnInfo.Value?.ObjToString().ToSqlFilter()); + } + } + return columnInfo.UpdateSql; + } + else if (columnInfo.SqlParameterDbType is Type && IsNoParameterConvert(columnInfo)) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(typeof(string)); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { columnInfo.Value, GetDbColumnIndex }) as SugarParameter; + return p.ParameterName; + } + else if (columnInfo.SqlParameterDbType is Type) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { columnInfo.Value, GetDbColumnIndex }) as SugarParameter; + GetDbColumnIndex++; + //this.Parameters.RemoveAll(it => it.ParameterName == it.ParameterName); + this.Parameters.Add(p); + return p.ParameterName; + } + else if (columnInfo.PropertyType?.Name == "TimeOnly" && name?.ObjToString().StartsWith(Builder.SqlParameterKeyWord) == false) + { + var timeSpan = UtilMethods.TimeOnlyToTimeSpan(columnInfo.Value); + var pname = Builder.SqlParameterKeyWord + columnInfo.DbColumnName + "_ts" + GetDbColumnIndex; + if (timeSpan == null) + { + this.Parameters.Add(new SugarParameter(pname, null) { DbType = System.Data.DbType.Date }); + } + else + { + this.Parameters.Add(new SugarParameter(pname, timeSpan)); + } + GetDbColumnIndex++; + return pname; + } + else if (columnInfo.PropertyType?.Name == "DateOnly") + { + var timeSpan = UtilMethods.DateOnlyToDateTime(columnInfo.Value); + var pname = Builder.SqlParameterKeyWord + columnInfo.DbColumnName + "_ts" + GetDbColumnIndex; + if (timeSpan == null) + { + this.Parameters.Add(new SugarParameter(pname, null) { DbType = System.Data.DbType.Date }); + } + else + { + this.Parameters.Add(new SugarParameter(pname, Convert.ToDateTime(timeSpan))); + } + GetDbColumnIndex++; + return pname; + } + else if (UtilMethods.IsErrorParameterName(this.Context.CurrentConnectionConfig, columnInfo)) + { + var pname = Builder.SqlParameterKeyWord + "CrorrPara" + GetDbColumnIndex; + var p = new SugarParameter(pname, columnInfo.Value); + this.Parameters.Add(p); + GetDbColumnIndex++; + return pname; + + } + else + { + return name + ""; + } + } + + private static bool IsNoParameterConvert(DbColumnInfo columnInfo) + { + if (columnInfo.SqlParameterDbType is Type t) + { + var isAssignableFrom = typeof(DbConvert.NoParameterCommonPropertyConvert).IsAssignableFrom(t); + if (isAssignableFrom) + { + return isAssignableFrom; + } + } + return (Type)columnInfo.SqlParameterDbType == UtilConstants.SqlConvertType; + } + + private bool IsSingleSetExp(DbColumnInfo columnInfo) + { + return this.ReSetValueBySqlExpList?.ContainsKey(columnInfo.PropertyName) == true && + this.IsListUpdate == null && + DbColumnInfoList.GroupBy(it => it.TableId).Count() == 1; + } + private bool IsListSetExp(DbColumnInfo columnInfo) + { + return this.ReSetValueBySqlExpListType != null && this.ReSetValueBySqlExpList?.ContainsKey(columnInfo.PropertyName) == true; + } + //public virtual string GetDbColumn(DbColumnInfo columnInfo, string name) + //{ + // if (columnInfo.UpdateServerTime) + // { + // return LambdaExpressions.DbMehtods.GetDate(); + // } + // else if (columnInfo.UpdateSql.HasValue()) + // { + // return columnInfo.UpdateSql; + // } + // else + // { + // return name + ""; + // } + //} + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarAccessory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarAccessory.cs new file mode 100644 index 000000000..e24c6a642 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarAccessory.cs @@ -0,0 +1,683 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public partial class SqlSugarProvider + { + #region Properties + public SqlSugarProvider Context + { + get + { + _Context = this; + return _Context; + } + set + { + _Context = value; + } + } + public SqlSugarClient Root { get; set; } + public ConnectionConfig CurrentConnectionConfig { get; set; } + public Dictionary TempItems { get { if (_TempItems == null) { _TempItems = new Dictionary(); } return _TempItems; } set { _TempItems = value; } } + public Guid ContextID { get; set; } + public MappingTableList MappingTables { get; set; } + public MappingColumnList MappingColumns { get; set; } + public IgnoreColumnList IgnoreColumns { get; set; } + public IgnoreColumnList IgnoreInsertColumns { get; set; } + public SugarActionType SugarActionType { get; set; } = SugarActionType.UnKnown; + public ConfigQuery ConfigQuery + { + get + { + if (_SqlConfigTable == null) + { + _SqlConfigTable = new ConfigQuery() { Context = this.Context }; + } + return _SqlConfigTable; + } + set + { + _SqlConfigTable = value; + } + } + + + #endregion + + #region Fields + public Dictionary _TempItems; + public QueueList _Queues; + protected ISqlBuilder _SqlBuilder; + protected SqlSugarProvider _Context { get; set; } + protected EntityMaintenance _EntityProvider; + protected IAdo _Ado; + protected ILambdaExpressions _LambdaExpressions; + protected IContextMethods _RewritableMethods; + protected IDbMaintenance _DbMaintenance; + protected QueryFilterProvider _QueryFilterProvider; + protected ConfigQuery _SqlConfigTable; + //protected SimpleClient _SimpleClient; + protected IAdo ContextAdo + { + get + { + return this._Ado; + } + set + { + this._Ado = value; + } + } + protected IContextMethods ContextRewritableMethods + { + get + { + return this._RewritableMethods; + } + set + { + this._RewritableMethods = value; + } + } + #endregion + + #region Init mappingInfo + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + + #region 9-12 + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + protected void InitMappingInfo() + { + InitMappingInfo(); + InitMappingInfo(); + } + #endregion + + public void InitMappingInfo() + { + InitMappingInfo(typeof(T)); + } + public void InitMappingInfo(Type type) + { + string cacheKey = "Context.InitAttributeMappingTables" + type.FullName + this.Context?.CurrentConnectionConfig?.ConfigId; + var entityInfo = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + var result = this.Context.EntityMaintenance.GetEntityInfoWithAttr(type); + return result; + }); + //var copyObj = CopyEntityInfo(entityInfo); + InitMappingInfo(entityInfo); + } + public void InitMappingInfoNoCache(Type type) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfoNoCache(type); + InitMappingInfo(entityInfo); + } + public EntityInfo GetEntityNoCacheInitMappingInfo(Type type) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfoNoCache(type); + InitMappingInfo(entityInfo); + return entityInfo; + } + //private EntityInfo CopyEntityInfo(EntityInfo entityInfo) + //{ + // EntityInfo result = new EntityInfo() + // { + // DbTableName = entityInfo.DbTableName, + // EntityName = entityInfo.EntityName, + // Type = entityInfo.Type + // }; + // List columns = new List(); + // if (entityInfo.Columns.HasValue()) + // { + // foreach (var item in entityInfo.Columns) + // { + // EntityColumnInfo column = new EntityColumnInfo() + // { + // ColumnDescription = item.ColumnDescription, + // DataType = item.DataType, + // DbColumnName = item.DbColumnName, + // DbTableName = item.DbTableName, + // DecimalDigits = item.DecimalDigits, + // DefaultValue = item.DefaultValue, + // EntityName = item.EntityName, + // IsIdentity = item.IsIdentity, + // IsIgnore = item.IsIgnore, + // IsNullable = item.IsNullable, + // IsOnlyIgnoreInsert = item.IsOnlyIgnoreInsert, + // IsPrimarykey = item.IsPrimarykey, + // Length = item.Length, + // OldDbColumnName = item.OldDbColumnName, + // OracleSequenceName = item.OracleSequenceName, + // PropertyInfo = item.PropertyInfo, + // PropertyName = item.PropertyName, + // IsArray=item.IsArray, + // IsJson=item.IsJson + // }; + // columns.Add(item); + // } + // } + // result.Columns = columns; + // return result; + //} + + private void InitMappingInfo(EntityInfo entityInfo) + { + if (this.MappingTables == null) + this.MappingTables = new MappingTableList(); + if (this.MappingColumns == null) + this.MappingColumns = new MappingColumnList(); + if (this.IgnoreColumns == null) + this.IgnoreColumns = new IgnoreColumnList(); + if (this.IgnoreInsertColumns == null) + this.IgnoreInsertColumns = new IgnoreColumnList(); + if (!this.MappingTables.Any(it => it.EntityName == entityInfo.EntityName)) + { + if (entityInfo.DbTableName != entityInfo.EntityName && entityInfo.DbTableName.HasValue()) + { + this.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName); + } + } + if (entityInfo.Columns.Any(it => it.EntityName == entityInfo.EntityName)) + { + var mappingColumnInfos = this.MappingColumns.Where(it => it.EntityName == entityInfo.EntityName); + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) + { + if (!mappingColumnInfos.Any(it => it.PropertyName == item.PropertyName)) + if (item.PropertyName != item.DbColumnName && item.DbColumnName.HasValue()) + this.MappingColumns.Add(item.PropertyName, item.DbColumnName, item.EntityName); + } + var ignoreInfos = this.IgnoreColumns.Where(it => it.EntityName == entityInfo.EntityName); + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore)) + { + if (!ignoreInfos.Any(it => it.PropertyName == item.PropertyName)) + this.IgnoreColumns.Add(item.PropertyName, item.EntityName); + } + + var ignoreInsertInfos = this.IgnoreInsertColumns.Where(it => it.EntityName == entityInfo.EntityName); + foreach (var item in entityInfo.Columns.Where(it => it.IsOnlyIgnoreInsert)) + { + if (!ignoreInsertInfos.Any(it => it.PropertyName == item.PropertyName)) + this.IgnoreInsertColumns.Add(item.PropertyName, item.EntityName); + } + } + } + #endregion + + #region Create Instance + protected ISugarQueryable CreateQueryable() + { + ISugarQueryable result = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + return CreateQueryable(result); + } + protected ISugarQueryable CreateQueryable(ISugarQueryable result) + { + this.SugarActionType = SugarActionType.Query; + Check.Exception(typeof(T).IsClass() == false || typeof(T).GetConstructors().Length == 0, "Queryable<{0}> Error ,{0} is invalid , need is a class,and can new().", typeof(T).Name); + var sqlBuilder = InstanceFactory.GetSqlbuilder(CurrentConnectionConfig); + result.Context = this.Context; + result.SqlBuilder = sqlBuilder; + result.SqlBuilder.QueryBuilder = InstanceFactory.GetQueryBuilder(CurrentConnectionConfig); + result.SqlBuilder.QueryBuilder.Builder = sqlBuilder; + result.SqlBuilder.Context = result.SqlBuilder.QueryBuilder.Context = this; + result.SqlBuilder.QueryBuilder.EntityType = typeof(T); + result.SqlBuilder.QueryBuilder.EntityName = typeof(T).Name; + result.SqlBuilder.QueryBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(CurrentConnectionConfig); + if (StaticConfig.CompleteQueryableFunc != null) + { + StaticConfig.CompleteQueryableFunc(result); + } + return result; + } + protected InsertableProvider CreateInsertable(T[] insertObjs) where T : class, new() + { + this.SugarActionType = SugarActionType.Insert; + var result = InstanceFactory.GetInsertableProvider(this.CurrentConnectionConfig); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.CurrentConnectionConfig); ; + result.Context = this; + result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + result.SqlBuilder = sqlBuilder; + result.InsertObjs = insertObjs; + sqlBuilder.InsertBuilder = result.InsertBuilder = InstanceFactory.GetInsertBuilder(this.CurrentConnectionConfig); + sqlBuilder.InsertBuilder.Builder = sqlBuilder; + sqlBuilder.InsertBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig); + sqlBuilder.Context = result.SqlBuilder.InsertBuilder.Context = this; + result.Init(); + if (StaticConfig.CompleteInsertableFunc != null) + { + StaticConfig.CompleteInsertableFunc(result); + } + return result; + } + protected DeleteableProvider CreateDeleteable() where T : class, new() + { + this.SugarActionType = SugarActionType.Delete; + var result = InstanceFactory.GetDeleteableProvider(this.CurrentConnectionConfig); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.CurrentConnectionConfig); ; + result.Context = this; + result.SqlBuilder = sqlBuilder; + sqlBuilder.DeleteBuilder = result.DeleteBuilder = InstanceFactory.GetDeleteBuilder(this.CurrentConnectionConfig); + sqlBuilder.DeleteBuilder.Builder = sqlBuilder; + sqlBuilder.DeleteBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig); + sqlBuilder.Context = result.SqlBuilder.DeleteBuilder.Context = this; + if (StaticConfig.CompleteDeleteableFunc != null) + { + StaticConfig.CompleteDeleteableFunc(result); + } + return result; + } + protected UpdateableProvider CreateUpdateable(T[] UpdateObjs) where T : class, new() + { + this.SugarActionType = SugarActionType.Update; + var result = InstanceFactory.GetUpdateableProvider(this.CurrentConnectionConfig); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.CurrentConnectionConfig); ; + result.Context = this; + result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + result.SqlBuilder = sqlBuilder; + result.UpdateObjs = UpdateObjs; + sqlBuilder.UpdateBuilder = result.UpdateBuilder = InstanceFactory.GetUpdateBuilder(this.CurrentConnectionConfig); + sqlBuilder.UpdateBuilder.Builder = sqlBuilder; + sqlBuilder.UpdateBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig); + sqlBuilder.Context = result.SqlBuilder.UpdateBuilder.Context = this; + result.Init(); + if (StaticConfig.CompleteUpdateableFunc != null) + { + StaticConfig.CompleteUpdateableFunc(result); + } + return result; + } + + protected void CreateQueryJoin(Expression joinExpression, Type[] types, ISugarQueryable queryable) + { + this.SugarActionType = SugarActionType.Query; + this.CreateQueryable(queryable); + string shortName = string.Empty; + List paramters = new List(); + queryable.SqlBuilder.QueryBuilder.JoinQueryInfos = this.GetJoinInfos(queryable.SqlBuilder, joinExpression, ref paramters, ref shortName, types); + if (queryable.SqlBuilder.QueryBuilder.JoinQueryInfos.Count != 0) + { + queryable.SqlBuilder.QueryBuilder.JoinQueryInfos.Last().EntityType = types.Last(); + } + queryable.SqlBuilder.QueryBuilder.TableShortName = shortName; + queryable.SqlBuilder.QueryBuilder.JoinExpression = joinExpression; + if (paramters != null) + { + queryable.SqlBuilder.QueryBuilder.Parameters.AddRange(paramters); + } + UtilMethods.AddDiscrimator(typeof(T), queryable, queryable.QueryBuilder.TableShortName + "."); + } + protected void CreateEasyQueryJoin(Expression joinExpression, Type[] types, ISugarQueryable queryable) + { + this.SugarActionType = SugarActionType.Query; + this.CreateQueryable(queryable); + string shortName = string.Empty; + queryable.SqlBuilder.QueryBuilder.EasyJoinInfos = this.GetEasyJoinInfo(joinExpression, ref shortName, queryable.SqlBuilder, types); + queryable.SqlBuilder.QueryBuilder.TableShortName = shortName; + queryable.SqlBuilder.QueryBuilder.JoinExpression = joinExpression; + var isNoPgAuto = this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLower == false; + if (isNoPgAuto) + queryable.SqlBuilder.QueryBuilder.TableShortName = queryable.SqlBuilder.GetTranslationColumnName(shortName); + } + #endregion + + #region Private methods + private void _ThenMapper(IEnumerable list, Action action) + { + MapperContext result = new MapperContext(); + result.context = this.Context; + if (result.context.TempItems == null) + { + result.context.TempItems = new Dictionary(); + } + var key = "Queryable_To_Context"; + result.context.TempItems.Add(key, result); + result.list = list.ToList(); + foreach (var item in list) + { + action.Invoke(item); + } + result.context.TempItems.Remove(key); + } + private async Task _ThenMapperAsync(IEnumerable list, Func action) + { + MapperContext result = new MapperContext(); + result.context = this.Context; + if (result.context.TempItems == null) + { + result.context.TempItems = new Dictionary(); + } + var key = "Queryable_To_Context"; + result.context.TempItems.Add(key, result); + result.list = list.ToList(); + foreach (var item in list) + { + await action.Invoke(item).ConfigureAwait(false); + } + result.context.TempItems.Remove(key); + } + internal string GetN() + { + var N = "N"; + if (_Context.CurrentConnectionConfig.MoreSettings?.DisableNvarchar == true) + { + N = ""; + } + return N; + } + public bool IsVarchar() + { + if (_Context.CurrentConnectionConfig.MoreSettings?.DisableNvarchar == true) + { + return true; + } + return false; + } + private void CheckDbDependency(ConnectionConfig config) + { + switch (config.DbType) + { + case DbType.MySql: + DependencyManagement.TryMySqlData(); + break; + case DbType.SqlServer: + break; + case DbType.Sqlite: + DependencyManagement.TrySqlite(); + break; + case DbType.Oracle: + DependencyManagement.TryOracle(); + break; + case DbType.PostgreSQL: + DependencyManagement.TryPostgreSQL(); + break; + case DbType.OpenGauss: + config.DbType = DbType.PostgreSQL; + if (this.CurrentConnectionConfig.MoreSettings == null) + this.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings(); + this.CurrentConnectionConfig.MoreSettings.DatabaseModel = DbType.OpenGauss; + break; + case DbType.HG: + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? throw new Exception("Only.NET CORE is supported") : "SqlSugar.HGCore"; + break; + case DbType.Kdbndp: + DependencyManagement.TryKdbndb(); + break; + case DbType.Dm: + DependencyManagement.TryDm(); + break; + case DbType.Oscar: + DependencyManagement.TryOscar(); + break; + case DbType.MySqlConnector: + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.MySqlConnector" : "SqlSugar.MySqlConnectorCore"; + if (SugarCompatible.IsFramework.ObjToBool() == false) + { + config.DbType = DbType.MySql; + InstanceFactory.CustomDllName = null; + } + break; + case DbType.Access: + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.Access" : "SqlSugar.AccessCore"; + break; + case DbType.Custom: + Check.Exception(InstanceFactory.CustomDbName.IsNullOrEmpty(), "DbType.Custom: InstanceFactory.CustomDbName is not null "); + Check.Exception(InstanceFactory.CustomNamespace.IsNullOrEmpty(), "DbType.Custom: InstanceFactory.CustomNamespace is not null "); + Check.Exception(InstanceFactory.CustomDllName.IsNullOrEmpty(), "DbType.Custom: InstanceFactory.CustomDllName is not null "); + break; + case DbType.QuestDB: + DependencyManagement.TryPostgreSQL(); + break; + case DbType.ClickHouse: + Check.Exception(SugarCompatible.IsFramework, "ClickHouse only support .net core"); + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.ClickHouse" : "SqlSugar.ClickHouseCore"; + break; + case DbType.GBase: + Check.Exception(SugarCompatible.IsFramework, "GBase only support .net core"); + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.GBase" : "SqlSugar.GBaseCore"; + break; + case DbType.Odbc: + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.Odbc" : "SqlSugar.OdbcCore"; + break; + case DbType.OceanBaseForOracle: + Check.Exception(SugarCompatible.IsFramework, "OceanBaseForOracle only support .net core"); + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.OceanBaseForOracle" : "SqlSugar.OceanBaseForOracleCore"; + break; + case DbType.TDSQLForPGODBC: + Check.Exception(SugarCompatible.IsFramework, "TDSQLForPGODBC only support .net core"); + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.TDSQLForPGODBC" : "SqlSugar.TDSQLForPGODBC"; + break; + case DbType.GaussDB: + config.DbType = DbType.PostgreSQL; + if (this.CurrentConnectionConfig.MoreSettings == null) + this.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings(); + this.CurrentConnectionConfig.MoreSettings.DatabaseModel = DbType.GaussDB; + break; + case DbType.Vastbase: + config.DbType = DbType.PostgreSQL; + if (this.CurrentConnectionConfig.MoreSettings == null) + this.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings(); + this.CurrentConnectionConfig.MoreSettings.DatabaseModel = DbType.Vastbase; + break; + case DbType.OceanBase: + config.DbType = DbType.MySql; + if (this.CurrentConnectionConfig.MoreSettings == null) + this.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings(); + this.CurrentConnectionConfig.MoreSettings.DatabaseModel = DbType.OceanBase; + break; + case DbType.Tidb: + config.DbType = DbType.MySql; + break; + case DbType.PolarDB: + config.DbType = DbType.MySql; + break; + case DbType.TDSQL: + config.DbType = DbType.MySql; + break; + case DbType.Doris: + config.DbType = DbType.MySql; + if (this.CurrentConnectionConfig.MoreSettings == null) + this.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings(); + this.CurrentConnectionConfig.MoreSettings.DatabaseModel = DbType.Doris; + this.CurrentConnectionConfig.MoreSettings.DisableNvarchar = true; + break; + case DbType.TDengine: + Check.Exception(SugarCompatible.IsFramework, "TDengine only support .net core"); + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.TDengine" : "SqlSugar.TDengineCore"; + break; + case DbType.HANA: + Check.Exception(SugarCompatible.IsFramework, "NANA only support .net core"); + InstanceFactory.CustomDllName = "SqlSugar.HANAConnector"; + break; + case DbType.Xugu: + Check.Exception(SugarCompatible.IsFramework, "Xugu only support .net core"); + //InstanceFactory.CustomDbName = "Xugu"; + InstanceFactory.CustomDllName = "SqlSugar.XuguCore"; + //InstanceFactory.CustomNamespace = "SqlSugar.Xugu"; + break; + case DbType.GoldenDB: + config.DbType = DbType.MySql; + break; + case DbType.DB2: + Check.Exception(SugarCompatible.IsFramework, "Db2 only support .net core"); + InstanceFactory.CustomDllName = "SqlSugar.Db2Core"; + break; + case DbType.GaussDBNative: + Check.Exception(SugarCompatible.IsFramework, "GaussDBNative only support .net core"); + InstanceFactory.CustomDllName = "SqlSugar.GaussDBCore"; + break; + case DbType.DuckDB: + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? throw new Exception("Only.NET CORE is supported") : "SqlSugar.DuckDBCore"; + break; + case DbType.MongoDb: + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? throw new Exception("Only.NET CORE is supported") : "SqlSugar.MongoDbCore"; + break; + default: + throw new Exception("ConnectionConfig.DbType is null"); + } + } + protected List GetJoinInfos(ISqlBuilder sqlBuilder, Expression joinExpression, ref List parameters, ref string shortName, params Type[] entityTypeArray) + { + List result = new List(); + var lambdaParameters = ((LambdaExpression)joinExpression).Parameters.ToList(); + ILambdaExpressions expressionContext = sqlBuilder.QueryBuilder.LambdaExpressions; + expressionContext.MappingColumns = this.MappingColumns; + expressionContext.MappingTables = this.MappingTables; + expressionContext.IsSingle = false; + expressionContext.SugarContext = new ExpressionOutParameter() { Context = this.Context }; + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + expressionContext.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + else + { + expressionContext.PgSqlIsAutoToLower = true; + } + if (this.Context.CurrentConnectionConfig.ConfigureExternalServices != null) + expressionContext.SqlFuncServices = this.Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + expressionContext.Resolve(joinExpression, ResolveExpressType.Join); + int i = 0; + var joinArray = MergeJoinArray(expressionContext.Result.GetResultArray()); + if (joinArray == null) return null; + parameters = expressionContext.Parameters; + foreach (var entityType in entityTypeArray) + { + var isFirst = i == 0; ++i; + JoinQueryInfo joinInfo = new JoinQueryInfo(); + var hasMappingTable = expressionContext.MappingTables.HasValue(); + MappingTable mappingInfo = null; + if (hasMappingTable) + { + mappingInfo = expressionContext.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityType.Name, StringComparison.CurrentCultureIgnoreCase)); + joinInfo.TableName = mappingInfo != null ? mappingInfo.DbTableName : entityType.Name; + } + else + { + joinInfo.TableName = entityType.Name; + } + var isNoPgAuto = this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLower == false; + if (isFirst) + { + var firstItem = lambdaParameters.First(); + lambdaParameters.Remove(firstItem); + shortName = firstItem.Name; + if (isNoPgAuto) + shortName = sqlBuilder.GetTranslationColumnName(shortName); + } + var joinString = joinArray[i * 2 - 2]; + joinInfo.ShortName = lambdaParameters[i - 1].Name; + joinInfo.JoinType = (JoinType)Enum.Parse(typeof(JoinType), joinString); + joinInfo.JoinWhere = joinArray[i * 2 - 1]; + joinInfo.JoinIndex = i; + joinInfo.EntityType = entityType; + if (isNoPgAuto) + joinInfo.ShortName = sqlBuilder.GetTranslationColumnName(joinInfo.ShortName); + result.Add((joinInfo)); + } + expressionContext.Clear(); + return result; + } + + private string[] MergeJoinArray(string[] joinArray) + { + List result = new List(); + string joinValue = null; + int i = 0; + if (joinArray == null) return null; + foreach (var item in joinArray) + { + ++i; + var isLast = joinArray.Length == i; + var isJoinType = item.IsIn(JoinType.Full.ToString(), JoinType.Inner.ToString(), JoinType.Left.ToString(), JoinType.Right.ToString(), JoinType.Cross.ToString()); + if (isJoinType) + { + if (joinValue != null) + result.Add(joinValue); + joinValue = null; + result.Add(item); + } + else + { + isJoinType = false; + joinValue += joinValue == null ? item : ("," + item); + } + if (isLast) + { + result.Add(joinValue); + } + } + return result.ToArray(); ; + } + + protected Dictionary GetEasyJoinInfo(Expression joinExpression, ref string shortName, ISqlBuilder builder, params Type[] entityTypeArray) + { + Dictionary result = new Dictionary(); + var lambdaParameters = ((LambdaExpression)joinExpression).Parameters.ToList(); + shortName = lambdaParameters.First().Name; + var isNoPgAuto = this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLower == false; + var index = 1; + foreach (var item in entityTypeArray) + { + if (isNoPgAuto) + { + result.Add(UtilConstants.Space + builder.GetTranslationColumnName(lambdaParameters[index].Name), item.Name); + } + else + { + result.Add(UtilConstants.Space + lambdaParameters[index].Name, item.Name); + } + ++index; + } + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarCoreProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarCoreProvider.cs new file mode 100644 index 000000000..42917f97b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarCoreProvider.cs @@ -0,0 +1,84 @@ +using System.Diagnostics; + +namespace SqlSugar +{ + /// + /// Partial SqlSugarScope + /// + public partial class SqlSugarScope : ISqlSugarClient, ITenant + { + + private List _configs; + private Action _configAction; + + protected virtual SqlSugarClient GetContext() + { + SqlSugarClient result = null; + var key = _configs.GetHashCode().ToString(); + StackTrace st = new StackTrace(true); + var methods = st.GetFrames(); + var isAsync = UtilMethods.IsAnyAsyncMethod(methods); + if (methods?.Length >= 0) + { + foreach (var method in methods.Take(35)) + { + var refType = method.GetMethod()?.ReflectedType; + if (refType != null) + { + var getInterfaces = refType.Name.StartsWith('<') ? refType?.ReflectedType?.GetInterfaces() : refType?.GetInterfaces(); + if (getInterfaces?.Any(it => it.Name.IsIn("IJob")) == true) + { + key = $"{key}IJob"; + break; + } + } + } + } + if (isAsync) + { + result = GetAsyncContext(key); + } + else + { + result = GetThreadContext(key); + } + return result; + } + private SqlSugarClient GetAsyncContext(string key) + { + SqlSugarClient result = CallContextAsync.GetData(key); + if (result == null) + { + List configList = GetCopyConfigs(); + CallContextAsync.SetData(key, new SqlSugarClient(configList)); + result = CallContextAsync.GetData(key); + if (this._configAction != null) + { + this._configAction(result); + } + } + + return result; + } + private SqlSugarClient GetThreadContext(string key) + { + SqlSugarClient result = CallContextThread.GetData(key); + if (result == null) + { + List configList = GetCopyConfigs(); + CallContextThread.SetData(key, new SqlSugarClient(configList)); + result = CallContextThread.GetData(key); + if (this._configAction != null) + { + this._configAction(result); + } + } + return result; + } + private List GetCopyConfigs() + { + return _configs.Select(it => UtilMethods.CopyConfig(it)).ToList(); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarProvider.cs new file mode 100644 index 000000000..da73be30e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarProvider.cs @@ -0,0 +1,1864 @@ +using System.Collections; +using System.Data; +using System.Dynamic; +using System.Linq.Expressions; +using System.Text; +namespace SqlSugar +{ + /// + /// ** description:Create datathis.access object + /// ** author:sunkaixuan + /// ** date:2017/1/2 + /// ** email:610262374@qq.com + /// + public partial class SqlSugarProvider : ISqlSugarClient + { + + #region Constructor + public SqlSugarProvider(ConnectionConfig config) + { + this.Context = this; + this.CurrentConnectionConfig = config; + this.ContextID = Guid.NewGuid(); + Check.ArgumentNullException(config, "config is null"); + CheckDbDependency(config); + if (StaticConfig.CompleteDbFunc != null) + { + StaticConfig.CompleteDbFunc(this); + } + } + #endregion + + #region ADO Methods + /// + ///Datathis.operation + /// + public virtual IAdo Ado + { + get + { + if (this.ContextAdo == null) + { + var result = InstanceFactory.GetAdo(this.Context.CurrentConnectionConfig); + this.ContextAdo = result; + result.Context = this; + return result; + } + return this._Ado; + } + } + #endregion + + #region Aop Log Methods + public virtual AopProvider Aop { get { return new AopProvider(this); } } + #endregion + + #region Util Methods + [Obsolete("Use SqlSugarClient.Utilities")] + public virtual IContextMethods RewritableMethods + { + get { return this.Context.Utilities; } + set { this.Context.Utilities = value; } + } + public virtual IContextMethods Utilities + { + get + { + if (ContextRewritableMethods == null) + { + ContextRewritableMethods = new ContextMethods(); + ContextRewritableMethods.Context = this; + } + return ContextRewritableMethods; + } + set { ContextRewritableMethods = value; } + } + #endregion + + #region Queryable + public QueryMethodInfo QueryableByObject(Type entityType) + { + QueryMethodInfo result = new QueryMethodInfo(); + var method = this.GetType().GetMyMethod("Queryable", 0); + var methodT = method.MakeGenericMethod(entityType); + var queryableObj = methodT.Invoke(this, Array.Empty()); + result.QueryableObj = queryableObj; + result.Context = this.Context; + result.EntityType = entityType; + return result; + } + public QueryMethodInfo QueryableByObject(Type entityType, string shortName) + { + return this.QueryableByObject(entityType).AS(this.Context.EntityMaintenance.GetTableName(entityType), shortName); + } + /// + /// Get datebase time + /// + /// + public DateTime GetDate() + { + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + return this.Ado.GetDateTime(sqlBuilder.FullSqlDateNow); + } + public ISugarQueryable MasterQueryable() + { + var result = this.Queryable(); + result.QueryBuilder.IsDisableMasterSlaveSeparation = true; + return result; + } + + public ISugarQueryable SlaveQueryable() + { + var result = this.Queryable(); + result.QueryBuilder.IsEnableMasterSlaveSeparation = true; + return result; + } + /// + /// Lambda Query operation + /// + public virtual ISugarQueryable Queryable() + { + + InitMappingInfo(); + var result = this.CreateQueryable(); + UtilMethods.AddDiscrimator(typeof(T), result); + return result; + } + /// + /// Lambda Query operation + /// + public virtual ISugarQueryable Queryable(string shortName) + { + Check.Exception(shortName.HasValue() && shortName.Length > 40, ErrorMessage.GetThrowMessage("shortName参数长度不能超过40,你可能是想用这个方法 db.SqlQueryable(sql)而不是db.Queryable(shortName)", "Queryable.shortName max length 20")); + var queryable = Queryable(); + queryable.SqlBuilder.QueryBuilder.TableShortName = shortName; + return queryable; + } + /// + /// Lambda Query operation + /// + public virtual ISugarQueryable Queryable(string tableName, string shortName) + { + var queryable = Queryable(); + queryable.SqlBuilder.QueryBuilder.EntityName = tableName; + queryable.SqlBuilder.QueryBuilder.TableShortName = shortName; + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + #region 9-12 + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateQueryJoin(joinExpression, types, queryable); + return queryable; + } + #endregion + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + + #region 9-12 + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + InitMappingInfo(); + var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + this.CreateEasyQueryJoin(joinExpression, types, queryable); + queryable.Where(joinExpression); + return queryable; + } + public virtual ISugarQueryable Queryable(ISugarQueryable queryable) + { + var sqlobj = queryable.ToSql(); + var QueryBuilder = queryable.QueryBuilder; + var newQueryable = this.SqlQueryable(sqlobj.Key).AddParameters(sqlobj.Value); + var result = newQueryable.Select(newQueryable.QueryBuilder.SelectValue + ""); + result.QueryBuilder.IsSqlQuery = false; + result.QueryBuilder.NoCheckInclude = true; + result.QueryBuilder.WhereIndex = (QueryBuilder.WhereIndex + 1); + var appendIndex = result.QueryBuilder.Parameters == null ? 1 : result.QueryBuilder.Parameters.Count + 1; + result.QueryBuilder.LambdaExpressions.ParameterIndex = (QueryBuilder.LambdaExpressions.ParameterIndex + appendIndex); + result.QueryBuilder.Includes = queryable.QueryBuilder.Includes?.ToList(); + return result; + } + public virtual ISugarQueryable Queryable(ISugarQueryable queryable, string shortName) + { + var result = Queryable(queryable); + var key = result.QueryBuilder.AsTables.First().Key; + var value = result.QueryBuilder.AsTables.First().Value; + result.QueryBuilder.AsTables.Remove(key); + result.QueryBuilder.AsTables.Add(key, value.TrimEnd(' ').TrimEnd('t') + shortName); + return result; + } + + public virtual ISugarQueryable Queryable( + ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) where T : class, new() where T2 : class, new() + { + return Queryable(joinQueryable1, joinQueryable2, JoinType.Inner, joinExpression); + } + public virtual ISugarQueryable Queryable( + ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) where T : class, new() where T2 : class, new() + { + Check.Exception(joinQueryable1.QueryBuilder.Take != null || joinQueryable1.QueryBuilder.Skip != null || joinQueryable1.QueryBuilder.OrderByValue.HasValue(), "joinQueryable1 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable2.QueryBuilder.Take != null || joinQueryable2.QueryBuilder.Skip != null || joinQueryable2.QueryBuilder.OrderByValue.HasValue(), "joinQueryable2 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + + sqlBuilder.Context = this; + InitMappingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + queryable.Context = this.Context; + queryable.SqlBuilder = sqlBuilder; + queryable.QueryBuilder = InstanceFactory.GetQueryBuilder(this.CurrentConnectionConfig); + queryable.QueryBuilder.JoinQueryInfos = new List(); + queryable.QueryBuilder.Builder = sqlBuilder; + queryable.QueryBuilder.Context = this; + queryable.QueryBuilder.EntityType = typeof(T); + queryable.QueryBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig); + + //master + var shortName1 = joinExpression.Parameters[0].Name; + var sqlObj1 = joinQueryable1.ToSql(); + string sql1 = sqlObj1.Key; + UtilMethods.RepairReplicationParameters(ref sql1, sqlObj1.Value.ToArray(), 0, "Join"); + queryable.QueryBuilder.EntityName = sqlBuilder.GetPackTable(sql1, sqlBuilder.GetTranslationColumnName(shortName1)); ; + queryable.QueryBuilder.Parameters.AddRange(sqlObj1.Value); + + //join table 1 + var shortName2 = joinExpression.Parameters[1].Name; + var sqlObj2 = joinQueryable2.ToSql(); + string sql2 = sqlObj2.Key; + UtilMethods.RepairReplicationParameters(ref sql2, sqlObj2.Value.ToArray(), 1, "Join"); + queryable.QueryBuilder.Parameters.AddRange(sqlObj2.Value); + var exp = queryable.QueryBuilder.GetExpressionValue(joinExpression, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 0, JoinType = joinType, JoinWhere = exp.GetResultString(), TableName = sqlBuilder.GetPackTable(sql2, sqlBuilder.GetTranslationColumnName(shortName2)) }); + + return queryable; + } + + + public virtual ISugarQueryable Queryable( + ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, + JoinType joinType1, Expression> joinExpression1, + JoinType joinType2, Expression> joinExpression2 + ) where T : class, new() where T2 : class, new() where T3 : class, new() + { + Check.Exception(joinQueryable1.QueryBuilder.Take != null || joinQueryable1.QueryBuilder.Skip != null || joinQueryable1.QueryBuilder.OrderByValue.HasValue(), "joinQueryable1 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable2.QueryBuilder.Take != null || joinQueryable2.QueryBuilder.Skip != null || joinQueryable2.QueryBuilder.OrderByValue.HasValue(), "joinQueryable2 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable3.QueryBuilder.Take != null || joinQueryable3.QueryBuilder.Skip != null || joinQueryable3.QueryBuilder.OrderByValue.HasValue(), "joinQueryable3 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + + sqlBuilder.Context = this; + InitMappingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + queryable.Context = this.Context; + queryable.SqlBuilder = sqlBuilder; + queryable.QueryBuilder = InstanceFactory.GetQueryBuilder(this.CurrentConnectionConfig); + queryable.QueryBuilder.JoinQueryInfos = new List(); + queryable.QueryBuilder.Builder = sqlBuilder; + queryable.QueryBuilder.Context = this; + queryable.QueryBuilder.EntityType = typeof(T); + queryable.QueryBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig); + + //master + var shortName1 = joinExpression1.Parameters[0].Name; + var sqlObj1 = joinQueryable1.ToSql(); + string sql1 = sqlObj1.Key; + UtilMethods.RepairReplicationParameters(ref sql1, sqlObj1.Value.ToArray(), 0, "Join"); + queryable.QueryBuilder.EntityName = sqlBuilder.GetPackTable(sql1, shortName1); ; + queryable.QueryBuilder.Parameters.AddRange(sqlObj1.Value); + + //join table 1 + var shortName2 = joinExpression1.Parameters[1].Name; + var sqlObj2 = joinQueryable2.ToSql(); + string sql2 = sqlObj2.Key; + UtilMethods.RepairReplicationParameters(ref sql2, sqlObj2.Value.ToArray(), 1, "Join"); + queryable.QueryBuilder.Parameters.AddRange(sqlObj2.Value); + var exp = queryable.QueryBuilder.GetExpressionValue(joinExpression1, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 0, JoinType = joinType1, JoinWhere = exp.GetResultString(), TableName = sqlBuilder.GetPackTable(sql2, shortName2) }); + + + //join table 2 + var shortName3 = joinExpression1.Parameters[2].Name; + var sqlObj3 = joinQueryable3.ToSql(); + string sql3 = sqlObj3.Key; + UtilMethods.RepairReplicationParameters(ref sql3, sqlObj3.Value.ToArray(), 2, "Join"); + queryable.QueryBuilder.Parameters.AddRange(sqlObj3.Value); + var exp2 = queryable.QueryBuilder.GetExpressionValue(joinExpression2, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 1, JoinType = joinType2, JoinWhere = exp2.GetResultString(), TableName = sqlBuilder.GetPackTable(sql3, shortName3) }); + return queryable; + } + + public virtual ISugarQueryable Queryable( + ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, ISugarQueryable joinQueryable4, + JoinType joinType1, Expression> joinExpression1, + JoinType joinType2, Expression> joinExpression2, + JoinType joinType3, Expression> joinExpression3 + ) where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class, new() + { + Check.Exception(joinQueryable1.QueryBuilder.Take != null || joinQueryable1.QueryBuilder.Skip != null || joinQueryable1.QueryBuilder.OrderByValue.HasValue(), "joinQueryable1 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable2.QueryBuilder.Take != null || joinQueryable2.QueryBuilder.Skip != null || joinQueryable2.QueryBuilder.OrderByValue.HasValue(), "joinQueryable2 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable3.QueryBuilder.Take != null || joinQueryable3.QueryBuilder.Skip != null || joinQueryable3.QueryBuilder.OrderByValue.HasValue(), "joinQueryable3 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable4.QueryBuilder.Take != null || joinQueryable4.QueryBuilder.Skip != null || joinQueryable4.QueryBuilder.OrderByValue.HasValue(), "joinQueryable4 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + + sqlBuilder.Context = this; + InitMappingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); + queryable.Context = this.Context; + queryable.SqlBuilder = sqlBuilder; + queryable.QueryBuilder = InstanceFactory.GetQueryBuilder(this.CurrentConnectionConfig); + queryable.QueryBuilder.JoinQueryInfos = new List(); + queryable.QueryBuilder.Builder = sqlBuilder; + queryable.QueryBuilder.Context = this; + queryable.QueryBuilder.EntityType = typeof(T); + queryable.QueryBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig); + + //master + var shortName1 = joinExpression1.Parameters[0].Name; + var sqlObj1 = joinQueryable1.ToSql(); + string sql1 = sqlObj1.Key; + UtilMethods.RepairReplicationParameters(ref sql1, sqlObj1.Value.ToArray(), 0, "Join"); + queryable.QueryBuilder.EntityName = sqlBuilder.GetPackTable(sql1, shortName1); ; + queryable.QueryBuilder.Parameters.AddRange(sqlObj1.Value); + + //join table 1 + var shortName2 = joinExpression1.Parameters[1].Name; + var sqlObj2 = joinQueryable2.ToSql(); + string sql2 = sqlObj2.Key; + UtilMethods.RepairReplicationParameters(ref sql2, sqlObj2.Value.ToArray(), 1, "Join"); + queryable.QueryBuilder.Parameters.AddRange(sqlObj2.Value); + var exp = queryable.QueryBuilder.GetExpressionValue(joinExpression1, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 0, JoinType = joinType1, JoinWhere = exp.GetResultString(), TableName = sqlBuilder.GetPackTable(sql2, shortName2) }); + + + //join table 2 + var shortName3 = joinExpression1.Parameters[2].Name; + var sqlObj3 = joinQueryable3.ToSql(); + string sql3 = sqlObj3.Key; + UtilMethods.RepairReplicationParameters(ref sql3, sqlObj3.Value.ToArray(), 2, "Join"); + queryable.QueryBuilder.Parameters.AddRange(sqlObj3.Value); + var exp2 = queryable.QueryBuilder.GetExpressionValue(joinExpression2, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 1, JoinType = joinType2, JoinWhere = exp2.GetResultString(), TableName = sqlBuilder.GetPackTable(sql3, shortName3) }); + + //join table 3 + var shortName4 = joinExpression1.Parameters[3].Name; + var sqlObj4 = joinQueryable4.ToSql(); + string sql4 = sqlObj4.Key; + UtilMethods.RepairReplicationParameters(ref sql4, sqlObj4.Value.ToArray(), 3, "Join"); + queryable.QueryBuilder.Parameters.AddRange(sqlObj4.Value); + var exp3 = queryable.QueryBuilder.GetExpressionValue(joinExpression3, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 1, JoinType = joinType3, JoinWhere = exp3.GetResultString(), TableName = sqlBuilder.GetPackTable(sql4, shortName4) }); + + return queryable; + } + #endregion + + public virtual ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class + { + return _UnionAll(queryables); + } + + internal ISugarQueryable _UnionAll(ISugarQueryable[] queryables) + { + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + Check.Exception(queryables.IsNullOrEmpty(), "UnionAll.queryables is null "); + int i = 1; + List>> allItems = new List>>(); + foreach (var item in queryables) + { + var sqlObj = item.ToSql(); + string sql = sqlObj.Key; + if (this.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength > 0) + { + UtilMethods.RepairReplicationParameters(this.Context, ref sql, sqlObj.Value.ToArray(), i, "UnionAll"); + } + else + { + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i, "UnionAll"); + } + if (sqlObj.Value.HasValue()) + allItems.Add(new KeyValuePair>(sqlBuilder.GetUnionFomatSql(sql), sqlObj.Value)); + else + allItems.Add(new KeyValuePair>(sqlBuilder.GetUnionFomatSql(sql), new List())); + i++; + } + var allSql = sqlBuilder.GetUnionAllSql(allItems.Select(it => it.Key).ToList()); + var allParameters = allItems.SelectMany(it => it.Value).ToArray(); + var resulut = this.Context.Queryable().AS(UtilMethods.GetPackTable(allSql, "unionTable")).With(SqlWith.Null); + resulut.AddParameters(allParameters); + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle && sqlBuilder.SqlSelectAll == "*") + { + return resulut.Select("unionTable.*"); + } + else if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsWithNoLockQuery == true) + { + return resulut.Select(sqlBuilder.SqlSelectAll).With(SqlWith.Null); + } + else + { + return resulut.Select(sqlBuilder.SqlSelectAll); + } + } + + public virtual ISugarQueryable UnionAll(List> queryables) where T : class + { + Check.Exception(queryables.IsNullOrEmpty(), "UnionAll.queryables is null "); + return UnionAll(queryables.ToArray()); + } + public virtual ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class + { + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + Check.Exception(queryables.IsNullOrEmpty(), "UnionAll.queryables is null "); + int i = 1; + List>> allItems = new List>>(); + foreach (var item in queryables) + { + item.QueryBuilder.DisableTop = true; + var sqlObj = item.ToSql(); + string sql = sqlObj.Key; + if (this.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength > 0) + { + UtilMethods.RepairReplicationParameters(this.Context, ref sql, sqlObj.Value.ToArray(), i, "Union"); + } + else + { + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i, "Union"); + } + if (sqlObj.Value.HasValue()) + allItems.Add(new KeyValuePair>(sqlBuilder.GetUnionFomatSql(sql), sqlObj.Value)); + else + allItems.Add(new KeyValuePair>(sqlBuilder.GetUnionFomatSql(sql), new List())); + i++; + } + var allSql = sqlBuilder.GetUnionSql(allItems.Select(it => it.Key).ToList()); + var allParameters = allItems.SelectMany(it => it.Value).ToArray(); + var resulut = this.Context.Queryable().AS(UtilMethods.GetPackTable(allSql, "unionTable")).With(SqlWith.Null); + resulut.AddParameters(allParameters); + if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle && sqlBuilder.SqlSelectAll == "*") + { + return resulut.Select("unionTable.*"); + } + else + { + return resulut.Select(sqlBuilder.SqlSelectAll); + } + } + public virtual ISugarQueryable Union(List> queryables) where T : class + { + Check.Exception(queryables.IsNullOrEmpty(), "Union.queryables is null "); + return Union(queryables.ToArray()); + } + #endregion + + #region SqlQueryable + public ISugarQueryable SqlQueryable(string sql) where T : class, new() + { + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + var result = this.Context.Queryable().AS(sqlBuilder.GetPackTable(sql, sqlBuilder.GetDefaultShortName())).With(SqlWith.Null).Select(sqlBuilder.GetDefaultShortName() + ".*"); + result.QueryBuilder.IsSqlQuery = true; + result.QueryBuilder.OldSql = sql; + result.QueryBuilder.NoCheckInclude = true; + return result; + } + #endregion + + #region Insertable + public IInsertable> InsertableByDynamic(object insertDynamicObject) + { + return this.Insertable>(insertDynamicObject); + } + public InsertMethodInfo InsertableByObject(object singleEntityObjectOrListObject) + { + if (singleEntityObjectOrListObject == null) + return new InsertMethodInfo(); + if (singleEntityObjectOrListObject.GetType().FullName.IsCollectionsList()) + { + var list = ((IList)singleEntityObjectOrListObject); + if (list == null || list.Count == 0) + return new InsertMethodInfo(); + var type = list[0].GetType(); + var newList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); + foreach (var item in list) + { + newList.Add(item); + } + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Insertable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("List"))) + .Where(it => it.Name == "Insertable").ToList(); + var method = methods.Single().MakeGenericMethod(newList.GetType().GetGenericArguments().First()); + InsertMethodInfo result = new InsertMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = newList + }; + return result; + } + else + { + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Insertable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T")) + .Where(it => it.Name == "Insertable").ToList(); + var method = methods.Single().MakeGenericMethod(singleEntityObjectOrListObject.GetType()); + InsertMethodInfo result = new InsertMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = singleEntityObjectOrListObject + }; + return result; + } + } + public virtual IInsertable Insertable(T[] insertObjs) where T : class, new() + { + UtilMethods.CheckArray(insertObjs); + InitMappingInfo(); + InsertableProvider result = this.CreateInsertable(insertObjs); + return result; + } + public virtual IInsertable Insertable(List insertObjs) where T : class, new() + { + if (insertObjs?.IsNullOrEmpty() != false) + { + insertObjs = new List(); + insertObjs.Add(default(T)); + } + return this.Context.Insertable(insertObjs.ToArray()); + } + public virtual IInsertable Insertable(T insertObj) where T : class, new() + { + return this.Context.Insertable(new T[] { insertObj }); + } + public virtual IInsertable Insertable(Dictionary columnDictionary) where T : class, new() + { + InitMappingInfo(); + Check.Exception(columnDictionary == null || columnDictionary.Count == 0, "Insertable.columnDictionary can't be null"); + var insertObject = this.Context.Utilities.DeserializeObject(this.Context.Utilities.SerializeObject(columnDictionary)); + var columns = columnDictionary.Select(it => it.Key).ToList(); + return this.Context.Insertable(insertObject).InsertColumns(columns.ToArray()); ; + } + public virtual IInsertable Insertable(dynamic insertDynamicObject) where T : class, new() + { + InitMappingInfo(); + if (insertDynamicObject is T) + { + return this.Context.Insertable((T)insertDynamicObject); + } + else + { + var columns = ((object)insertDynamicObject).GetType().GetProperties().Select(it => it.Name).ToList(); + Check.Exception(columns.IsNullOrEmpty(), "Insertable.updateDynamicObject can't be null"); + T insertObject = this.Context.Utilities.DeserializeObject(this.Context.Utilities.SerializeObject(insertDynamicObject)); + return this.Context.Insertable(insertObject).InsertColumns(columns.ToArray()); + } + } + #endregion + + #region Deleteable + public DeleteMethodInfo DeleteableByObject(object singleEntityObjectOrListObject) + { + if (singleEntityObjectOrListObject == null) + return new DeleteMethodInfo(); + if (singleEntityObjectOrListObject.GetType().FullName.IsCollectionsList()) + { + var list = ((IList)singleEntityObjectOrListObject); + if (list == null || list.Count == 0) + return new DeleteMethodInfo(); + var type = list[0].GetType(); + var newList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); + foreach (var item in list) + { + newList.Add(item); + } + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Deleteable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.Name != "pkValue" && z.ParameterType.Name.StartsWith("List"))) + .Where(it => it.Name == "Deleteable").ToList(); + var method = methods.FirstOrDefault().MakeGenericMethod(newList.GetType().GetGenericArguments().FirstOrDefault()); + DeleteMethodInfo result = new DeleteMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = newList + }; + return result; + } + else + { + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Deleteable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T")) + .Where(it => it.Name == "Deleteable").ToList(); + var method = methods.Single().MakeGenericMethod(singleEntityObjectOrListObject.GetType()); + DeleteMethodInfo result = new DeleteMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = singleEntityObjectOrListObject + }; + return result; + } + } + public virtual IDeleteable Deleteable() where T : class, new() + { + InitMappingInfo(); + DeleteableProvider result = this.CreateDeleteable(); + if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true) + { + return result.EnableQueryFilter(); + } + return result; + } + public virtual IDeleteable Deleteable(Expression> expression) where T : class, new() + { + InitMappingInfo(); + return this.Context.Deleteable().Where(expression); + } + public virtual IDeleteable Deleteable(dynamic primaryKeyValue) where T : class, new() + { + InitMappingInfo(); + return this.Context.Deleteable().In(primaryKeyValue); + } + public virtual IDeleteable Deleteable(dynamic[] primaryKeyValues) where T : class, new() + { + InitMappingInfo(); + return this.Context.Deleteable().In(primaryKeyValues); + } + public virtual IDeleteable Deleteable(List pkValue) where T : class, new() + { + InitMappingInfo(); + return this.Context.Deleteable().In(pkValue); + } + public virtual IDeleteable Deleteable(T deleteObj) where T : class, new() + { + InitMappingInfo(); + return this.Context.Deleteable().Where(deleteObj); + } + public virtual IDeleteable Deleteable(List deleteObjs) where T : class, new() + { + InitMappingInfo(); + return this.Context.Deleteable().Where(deleteObjs); + } + #endregion + + #region Updateable + public UpdateMethodInfo UpdateableByObject(object singleEntityObjectOrListObject) + { + if (singleEntityObjectOrListObject == null) + return new UpdateMethodInfo(); + if (singleEntityObjectOrListObject.GetType().FullName.IsCollectionsList()) + { + var list = ((IList)singleEntityObjectOrListObject); + if (list == null || list.Count == 0) + return new UpdateMethodInfo(); + var type = list[0].GetType(); + var newList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); + foreach (var item in list) + { + newList.Add(item); + } + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Updateable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("List"))) + .Where(it => it.Name == "Updateable").ToList(); + var method = methods.Single().MakeGenericMethod(newList.GetType().GetGenericArguments().First()); + UpdateMethodInfo result = new UpdateMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = newList + }; + return result; + } + else + { + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Updateable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T")) + .Where(it => it.Name == "Updateable").ToList(); + var method = methods.Single().MakeGenericMethod(singleEntityObjectOrListObject.GetType()); + UpdateMethodInfo result = new UpdateMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = singleEntityObjectOrListObject + }; + return result; + } + } + public UpdateExpressionMethodInfo UpdateableByObject(Type entityType) + { + UpdateExpressionMethodInfo reslut = new UpdateExpressionMethodInfo(); + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Updateable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Length == 0) + .Where(it => it.Name == "Updateable").ToList(); + var method = methods.Single().MakeGenericMethod(entityType); + reslut.Context = this.Context; + reslut.MethodInfo = method; + reslut.Type = entityType; + reslut.objectValue = method.Invoke(Context, Array.Empty()); + return reslut; + } + public virtual IUpdateable Updateable(T[] UpdateObjs) where T : class, new() + { + InitMappingInfo(); + Check.ExceptionEasy(UpdateObjs is IList && typeof(T).FullName.IsCollectionsList(), "The methods you encapsulate are loaded incorrectly, so List should be Updateable(List UpdateObjs)where T: class, new()", "你封装的方法进错重载,List应该进Updateable(List UpdateObjs)where T : class, new()重载"); + UpdateableProvider result = this.CreateUpdateable(UpdateObjs); + return result; + } + public virtual IUpdateable Updateable(List UpdateObjs) where T : class, new() + { + //Check.ArgumentNullException(UpdateObjs, "Updateable.UpdateObjs can't be null"); + if (UpdateObjs == null) + { + UpdateObjs = new List(); + } + var result = (UpdateableProvider)Updateable(UpdateObjs.ToArray()); + result.UpdateBuilder.IsListUpdate = true; + return result; + } + public virtual IUpdateable Updateable(T UpdateObj) where T : class, new() + { + + return this.Context.Updateable(new T[] { UpdateObj }); + } + public virtual IUpdateable Updateable() where T : class, new() + { + var result = this.Context.Updateable(new T[] { new T() }); + result.UpdateParameterIsNull = true; + if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsAutoUpdateQueryFilter == true) + { + return result.EnableQueryFilter(); + } + return result; + } + public virtual IUpdateable Updateable(Expression> columns) where T : class, new() + { + var result = this.Context.Updateable().SetColumns(columns); + result.UpdateParameterIsNull = true; + return result; + } + public virtual IUpdateable Updateable(Expression> columns) where T : class, new() + { + var result = this.Context.Updateable().SetColumns(columns); + result.UpdateParameterIsNull = true; + return result; + } + + public IUpdateable> UpdateableByDynamic(object updateDynamicObject) + { + return this.Updateable>(updateDynamicObject); + } + + public virtual IUpdateable Updateable(Dictionary columnDictionary) where T : class, new() + { + InitMappingInfo(); + Check.Exception(columnDictionary == null || columnDictionary.Count == 0, "Updateable.columnDictionary can't be null"); + var updateObject = this.Context.Utilities.DeserializeObject(this.Context.Utilities.SerializeObject(columnDictionary)); + var columns = columnDictionary.Select(it => it.Key).ToList(); + return this.Context.Updateable(updateObject).UpdateColumns(columns.ToArray()); ; + } + public virtual IUpdateable Updateable(dynamic updateDynamicObject) where T : class, new() + { + InitMappingInfo(); + if (updateDynamicObject is T) + { + return this.Context.Updateable((T)updateDynamicObject); + } + else + { + var columns = ((object)updateDynamicObject).GetType().GetProperties().Select(it => it.Name).ToList(); + Check.Exception(columns.IsNullOrEmpty(), "Updateable.updateDynamicObject can't be null"); + T updateObject = this.Context.Utilities.DeserializeObject(this.Context.Utilities.SerializeObject(updateDynamicObject)); + return this.Context.Updateable(updateObject).UpdateColumns(columns.ToArray()); ; + } + } + #endregion + + #region Saveable + public GridSaveProvider GridSave(List saveList) where T : class, new() + { + Check.ExceptionEasy(saveList == null, "saveList is null", "saveList 不能是 null"); + var isTran = this.Context.TempItems?.Any(it => it.Key == "OldData_" + saveList.GetHashCode()) == true; + Check.ExceptionEasy(isTran == false, "saveList no tracking", "saveList 没有使用跟踪"); + var oldList = (List)this.Context.TempItems.FirstOrDefault(it => it.Key == "OldData_" + saveList.GetHashCode()).Value; + return GridSave(oldList, saveList); + } + public GridSaveProvider GridSave(List oldList, List saveList) where T : class, new() + { + GridSaveProvider result = new GridSaveProvider(); + result.Context = this; + result.OldList = oldList; + result.SaveList = saveList; + return result; + } + public IStorageable Storageable(T[] dataList) where T : class, new() + { + return Storageable(dataList?.ToList()); + } + public ISaveable Saveable(List saveObjects) where T : class, new() + { + return new SaveableProvider(this, saveObjects); + } + public ISaveable Saveable(T saveObject) where T : class, new() + { + return new SaveableProvider(this, saveObject); + } + public StorageableDataTable Storageable(List> dictionaryList, string tableName) + { + DataTable dt = this.Context.Utilities.DictionaryListToDataTable(dictionaryList); + dt.TableName = tableName; + return this.Context.Storageable(dt); + } + public StorageableDataTable Storageable(Dictionary dictionary, string tableName) + { + DataTable dt = this.Context.Utilities.DictionaryListToDataTable(new List>() { dictionary }); + dt.TableName = tableName; + return this.Context.Storageable(dt); + } + public IStorageable Storageable(List dataList) where T : class, new() + { + dataList = dataList.Where(it => it != null).ToList(); + this.InitMappingInfo(); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + var result = new Storageable(dataList, this); + result.Builder = sqlBuilder; + return result; + } + public IStorageable Storageable(IList dataList) where T : class, new() + { + return Storageable(dataList?.ToList()); + } + public IStorageable Storageable(T data) where T : class, new() + { + return Storageable(new List() { data }); + } + public StorageableDataTable Storageable(DataTable data) + { + var result = new StorageableDataTable(); + Check.Exception(data.TableName.IsNullOrEmpty() || data.TableName == "Table", ErrorMessage.GetThrowMessage("DataTable data.TableName is null", "参数DataTable没有设置TableName ,参数.TableName=表名")); + result.DataTable = data; + result.Context = this; + data.Columns.Add(new DataColumn("SugarGroupId", typeof(StorageType))); + data.Columns.Add(new DataColumn("SugarUpdateRows", typeof(List))); + data.Columns.Add(new DataColumn("SugarErrorMessage", typeof(string))); + data.Columns.Add(new DataColumn("SugarColumns", typeof(string[]))); + return result; + } + public StorageableMethodInfo StorageableByObject(object singleEntityObjectOrList) + { + if (singleEntityObjectOrList == null) + return new StorageableMethodInfo(); + if (singleEntityObjectOrList.GetType().FullName.IsCollectionsList()) + { + var list = ((IList)singleEntityObjectOrList); + if (list == null || list.Count == 0) + return new StorageableMethodInfo(); + var type = list[0].GetType(); + var newList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); + foreach (var item in list) + { + newList.Add(item); + } + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Storageable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("List"))) + .Where(it => it.Name == "Storageable").ToList(); + var method = methods.Single().MakeGenericMethod(newList.GetType().GetGenericArguments().First()); + StorageableMethodInfo result = new StorageableMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = newList + }; + return result; + } + else + { + var methods = this.Context.GetType().GetMethods() + .Where(it => it.Name == "Storageable") + .Where(it => it.GetGenericArguments().Length != 0) + .Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T")) + .Where(it => it.Name == "Storageable").ToList(); + var method = methods.Single().MakeGenericMethod(singleEntityObjectOrList.GetType()); + StorageableMethodInfo result = new StorageableMethodInfo() + { + Context = this.Context, + MethodInfo = method, + objectValue = singleEntityObjectOrList + }; + return result; + } + } + #endregion + + #region Reportable + public IReportable Reportable(T data) + { + var result = new ReportableProvider(data); + result.formatBuilder = InstanceFactory.GetInsertBuilder(this.Context.CurrentConnectionConfig); + result.Context = this; + result.formatBuilder.Context = this; + result.queryBuilder = this.Queryable().QueryBuilder; + return result; + } + public IReportable Reportable(List list) + { + var result = new ReportableProvider(list); + result.formatBuilder = InstanceFactory.GetInsertBuilder(this.Context.CurrentConnectionConfig); + result.Context = this; + result.formatBuilder.Context = this; + result.queryBuilder = this.Queryable().QueryBuilder; + return result; + } + public IReportable Reportable(T[] list) + { + if (list == null) + list = Array.Empty(); + var result = new ReportableProvider(list.ToList()); + result.formatBuilder = InstanceFactory.GetInsertBuilder(this.Context.CurrentConnectionConfig); + result.Context = this; + result.formatBuilder.Context = this; + result.queryBuilder = this.Queryable().QueryBuilder; + return result; + } + #endregion + + #region Nav CUD + public InsertNavTaskInit InsertNav(T data) where T : class, new() + { + return InsertNav(new List() { data }); + } + public InsertNavTaskInit InsertNav(List datas) where T : class, new() + { + var result = new InsertNavTaskInit(); + var provider = new InsertNavProvider(); + provider._Roots = datas; + provider._Context = this; + result.insertNavProvider = provider; + result.NavContext = new NavContext() { Items = new List() }; + return result; + } + public InsertNavTaskInit InsertNav(T data, InsertNavRootOptions rootOptions) where T : class, new() + { + return InsertNav(new List() { data }, rootOptions); ; + } + public InsertNavTaskInit InsertNav(List datas, InsertNavRootOptions rootOptions) where T : class, new() + { + var result = new InsertNavTaskInit(); + var provider = new InsertNavProvider(); + provider._Roots = datas; + provider._Context = this; + provider._RootOptions = rootOptions; + result.insertNavProvider = provider; + result.NavContext = new NavContext() { Items = new List() }; + return result; + } + public DeleteNavTaskInit DeleteNav(T data) where T : class, new() + { + return DeleteNav(new List() { data }); + } + public DeleteNavTaskInit DeleteNav(List datas) where T : class, new() + { + var result = new DeleteNavTaskInit(); + result.deleteNavProvider = new DeleteNavProvider(); + result.deleteNavProvider._Roots = datas; + result.deleteNavProvider._Context = this; + return result; + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression) where T : class, new() + { + return DeleteNav(this.Queryable().Where(whereExpression).ToList()); + } + + public DeleteNavTaskInit DeleteNav(T data, DeleteNavRootOptions options) where T : class, new() + { + return DeleteNav(new List() { data }, options); + } + public DeleteNavTaskInit DeleteNav(List datas, DeleteNavRootOptions options) where T : class, new() + { + var result = new DeleteNavTaskInit(); + result.deleteNavProvider = new DeleteNavProvider(); + result.deleteNavProvider._Roots = datas; + result.deleteNavProvider._Context = this; + result.deleteNavProvider._RootOptions = options; + return result; + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression, DeleteNavRootOptions options) where T : class, new() + { + return DeleteNav(this.Queryable().Where(whereExpression).ToList(), options); + } + + public UpdateNavTaskInit UpdateNav(T data) where T : class, new() + { + return UpdateNav(new List() { data }); + } + public UpdateNavTaskInit UpdateNav(List datas) where T : class, new() + { + var result = new UpdateNavTaskInit(); + var provider = new UpdateNavProvider(); + provider._Roots = datas; + provider._Context = this; + result.UpdateNavProvider = provider; + result.NavContext = new NavContext() { Items = new List() { } }; + return result; + } + public UpdateNavTaskInit UpdateNav(T data, UpdateNavRootOptions rootOptions) where T : class, new() + { + return UpdateNav(new List() { data }, rootOptions); + } + public UpdateNavTaskInit UpdateNav(List datas, UpdateNavRootOptions rootOptions) where T : class, new() + { + var result = new UpdateNavTaskInit(); + var provider = new UpdateNavProvider(); + provider._Roots = datas; + provider._RootOptions = rootOptions; + provider._Context = this; + result.UpdateNavProvider = provider; + result.NavContext = new NavContext() { Items = new List() { } }; + return result; ; + } + #endregion + + #region DbFirst + public virtual IDbFirst DbFirst + { + get + { + IDbFirst dbFirst = InstanceFactory.GetDbFirst(this.Context.CurrentConnectionConfig); + dbFirst.Context = this.Context; + dbFirst.Init(); + return dbFirst; + } + } + #endregion + + #region CodeFirst + public virtual ICodeFirst CodeFirst + { + get + { + ICodeFirst codeFirst = InstanceFactory.GetCodeFirst(this.Context.CurrentConnectionConfig); + codeFirst.Context = this; + return codeFirst; + } + } + #endregion + + #region Db Maintenance + public virtual IDbMaintenance DbMaintenance + { + get + { + if (this._DbMaintenance == null) + { + IDbMaintenance maintenance = InstanceFactory.GetDbMaintenance(this.Context.CurrentConnectionConfig); + this._DbMaintenance = maintenance; + maintenance.Context = this; + } + return this._DbMaintenance; + } + } + #endregion + + #region Entity Maintenance + public virtual EntityMaintenance EntityMaintenance + { + get + { + if (this._EntityProvider == null) + { + this._EntityProvider = new EntityMaintenance(); + this._EntityProvider.Context = this; + } + return this._EntityProvider; + } + set { this._EntityProvider = value; } + } + #endregion + + #region Gobal Filter + public virtual QueryFilterProvider QueryFilter + { + get + { + if (this._QueryFilterProvider == null) + { + this._QueryFilterProvider = new QueryFilterProvider(); + this._QueryFilterProvider.Context = this; + } + return this._QueryFilterProvider; + } + set { this._QueryFilterProvider = value; } + } + #endregion + + #region SimpleClient + public T CreateContext(bool isTran) where T : SugarUnitOfWork, new() + { + Check.ExceptionEasy(" var childDb=Db.GetConnection(configId); use Db.CreateContext ", " 例如 var childDb=Db.GetConnection(configId);其中Db才能使用CreateContext,childDb不能使用"); + return null; + } + public SugarUnitOfWork CreateContext(bool isTran = true) + { + Check.ExceptionEasy(" var childDb=Db.GetConnection(configId); use Db.CreateContext ", " 例如 var childDb=Db.GetConnection(configId);其中Db才能使用CreateContext,childDb不能使用"); + return null; + } + //[Obsolete("Use SqlSugarClient.GetSimpleClient() Or SqlSugarClient.GetSimpleClient() ")] + //public virtual SimpleClient SimpleClient + //{ + // get + // { + // if (this._SimpleClient == null) + // this._SimpleClient = new SimpleClient(this); + // return this._SimpleClient; + // } + //} + public virtual SimpleClient GetSimpleClient() where T : class, new() + { + return new SimpleClient(this); + } + + public RepositoryType GetRepository() where RepositoryType : ISugarRepository, new() + { + Type type = typeof(RepositoryType); + var isAnyParamter = type.GetConstructors().Any(z => z.GetParameters().Length != 0); + object o = null; + if (isAnyParamter) + { + o = Activator.CreateInstance(type, new string[] { null }); + } + else + { + o = Activator.CreateInstance(type); + } + var result = (RepositoryType)o; + if (result.Context == null) + { + result.Context = this.Context; + } + return result; + } + //public virtual SimpleClient GetSimpleClient() + //{ + // if (this._SimpleClient == null) + // this._SimpleClient = new SimpleClient(this); + // return this._SimpleClient; + //} + #endregion + + #region Dispose OR Close + public virtual void Close() + { + this.Context.Ado?.Close(); + } + public virtual void Open() + { + this.Context.Ado?.Open(); + } + public virtual void Dispose() + { + this.Context.Ado?.Dispose(); + } + #endregion + + #region Queue + public int SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.ExecuteCommand(sql, parameters); }); + } + + public async Task SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.ExecuteCommandAsync(sql, parameters); }).ConfigureAwait(false); + } + public List SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public Tuple, List> SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task, List>> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public Tuple, List, List> SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task, List, List>> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public Tuple, List, List, List> SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public Tuple, List, List, List, List> SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public Tuple, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public Tuple, List, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return SaveQueuesProvider(isTran, (sql, parameters) => { return this.Ado.SqlQuery(sql, parameters); }); + } + public async Task, List, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return await SaveQueuesProviderAsync(isTran, (sql, parameters) => { return Ado.SqlQueryAsync(sql, parameters); }).ConfigureAwait(false); + } + public void AddQueue(string sql, object parsmeters = null) + { + if (Queues == null) + { + Queues = new QueueList(); + } + var pars = this.Context.Ado.GetParameters(parsmeters); + if (pars != null) + { + foreach (var par in pars) + { + if (par.ParameterName.StartsWith(':')) + { + par.ParameterName = ("@" + par.ParameterName.Trim(':')); + } + } + } + this.Queues.Add(sql, pars); + + } + public void AddQueue(string sql, SugarParameter parsmeter) + { + if (Queues == null) + { + Queues = new QueueList(); + } + this.Queues.Add(sql, new List() { parsmeter }); + } + public void AddQueue(string sql, List parsmeters) + { + if (Queues == null) + { + Queues = new QueueList(); + } + this.Queues.Add(sql, parsmeters); + } + public QueueList Queues { get { if (_Queues == null) { _Queues = new QueueList(); } return _Queues; } set { _Queues = value; } } + + + + private async Task SaveQueuesProviderAsync(bool isTran, Func, Task> func) + { + try + { + //if (this.CurrentConnectionConfig.DbType == DbType.Oracle) + //{ + // throw new Exception("Oracle no support SaveQueues"); + //} + if (this.Queues == null || this.Queues.Count == 0) return default(T); + isTran = isTran && this.Ado.Transaction == null; + if (isTran) this.Ado.BeginTran(); + StringBuilder sqlBuilder = new StringBuilder(); + var parsmeters = new List(); + var index = 1; + if (this.Queues.HasValue()) + { + var repeatList = + Queues.SelectMany(it => it.Parameters ?? Array.Empty()).Select(it => it.ParameterName) + .GroupBy(it => it?.ToLower()) + .Where(it => it.Count() > 1); + var repeatCount = repeatList.Count(); + var isParameterNameRepeat = repeatList.Any(); + foreach (var item in Queues) + { + if (item.Sql == null) + item.Sql = string.Empty; + if (item.Parameters == null) + item.Parameters = Array.Empty(); + var itemParsmeters = item.Parameters.OrderByDescending(it => it.ParameterName.Length).ToList(); + List addParameters = new List(); + var itemSql = item.Sql; + foreach (var itemParameter in itemParsmeters) + { + var newName = itemParameter.ParameterName + "_q_" + index; + SugarParameter parameter = new SugarParameter(newName, itemParameter.Value); + parameter.DbType = itemParameter.DbType; + if (repeatCount > 500 || (isParameterNameRepeat && repeatList.Any(it => it.Key.EqualCase(itemParameter.ParameterName)))) + { + if (newName.StartsWith(':') && itemSql.Contains(itemParameter.ParameterName.ToLower().Replace(":", "@"), StringComparison.CurrentCultureIgnoreCase)) + { + itemParameter.ParameterName = itemParameter.ParameterName.Replace(":", "@"); + } + itemSql = UtilMethods.ReplaceSqlParameter(itemSql, itemParameter, newName); + addParameters.Add(parameter); + } + else + { + parameter.ParameterName = itemParameter.ParameterName; + addParameters.Add(parameter); + } + } + parsmeters.AddRange(addParameters); + itemSql = itemSql + .TrimEnd('\r') + .TrimEnd('\n') + .TrimEnd('\r') + .TrimEnd('\n') + .TrimEnd(';') + ";"; + if (itemSql == "begin;") + { + itemSql = itemSql.TrimEnd(';') + "\n"; + } + sqlBuilder.AppendLine(itemSql); + index++; + } + } + this.Queues.Clear(); + var builder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + builder.FormatSaveQueueSql(sqlBuilder); + var result = await func(sqlBuilder.ToString(), parsmeters).ConfigureAwait(false); + if (isTran) this.Ado.CommitTran(); + return result; + } + catch (Exception) + { + if (isTran) this.Ado.RollbackTran(); + throw; + } + } + private T SaveQueuesProvider(bool isTran, Func, T> func) + { + try + { + //if (this.CurrentConnectionConfig.DbType == DbType.Oracle) + //{ + // throw new Exception("Oracle no support SaveQueues"); + //} + if (this.Queues == null || this.Queues.Count == 0) return default(T); + isTran = isTran && this.Ado.Transaction == null; + if (isTran) this.Ado.BeginTran(); + StringBuilder sqlBuilder = new StringBuilder(); + var parsmeters = new List(); + var index = 1; + if (this.Queues.HasValue()) + { + var repeatList = + Queues.SelectMany(it => it.Parameters ?? Array.Empty()).Select(it => it.ParameterName) + .GroupBy(it => it?.ToLower()) + .Where(it => it.Count() > 1); + var repeatCount = repeatList.Count(); + var isParameterNameRepeat = repeatList.Any(); + foreach (var item in Queues) + { + if (item.Sql == null) + item.Sql = string.Empty; + if (item.Parameters == null) + item.Parameters = Array.Empty(); + var itemParsmeters = item.Parameters.OrderByDescending(it => it.ParameterName.Length).ToList(); + List addParameters = new List(); + var itemSql = item.Sql; + foreach (var itemParameter in itemParsmeters) + { + var newName = itemParameter.ParameterName + "_q_" + index; + SugarParameter parameter = new SugarParameter(newName, itemParameter.Value); + parameter.DbType = itemParameter.DbType; + if (repeatCount > 500 || (isParameterNameRepeat && repeatList.Any(it => it.Key.EqualCase(itemParameter.ParameterName)))) + { + if (newName.StartsWith(':') && itemSql.Contains(itemParameter.ParameterName.ToLower().Replace(":", "@"), StringComparison.CurrentCultureIgnoreCase)) + { + itemParameter.ParameterName = itemParameter.ParameterName.Replace(":", "@"); + } + itemSql = UtilMethods.ReplaceSqlParameter(itemSql, itemParameter, newName); + } + else + { + parameter.ParameterName = itemParameter.ParameterName; + } + addParameters.Add(parameter); + } + parsmeters.AddRange(addParameters); + itemSql = itemSql + .TrimEnd('\r') + .TrimEnd('\n') + .TrimEnd('\r') + .TrimEnd('\n') + .TrimEnd(';') + ";"; + if (itemSql?.StartsWith("INSERT INTO ") == true && itemSql?.EndsWith(" returning ;") == true) + { + itemSql = itemSql.Replace(" returning ;", " ;"); + } + if (itemSql == "begin;") + { + itemSql = itemSql.TrimEnd(';') + "\n"; + } + sqlBuilder.AppendLine(itemSql); + index++; + } + } + this.Queues.Clear(); + var builder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + builder.FormatSaveQueueSql(sqlBuilder); + var result = func(sqlBuilder.ToString(), parsmeters); + if (isTran) this.Ado.CommitTran(); + return result; + } + catch (Exception) + { + if (isTran) this.Ado.RollbackTran(); + throw; + } + } + + #endregion + + #region Cache + public SugarCacheProvider DataCache + { + get + { + var services = this.CurrentConnectionConfig.ConfigureExternalServices; + if (services == null) + return new SugarCacheProvider(); + if (services.DataInfoCacheService == null) + return new SugarCacheProvider(); + SugarCacheProvider cache = new SugarCacheProvider(); + cache.Servie = services.DataInfoCacheService; + return cache; + } + } + #endregion + + #region Split table + public SplitTableContext SplitHelper() where T : class, new() + { + UtilMethods.StartCustomSplitTable(this, typeof(T)); + var result = new SplitTableContext(this.Context) + { + EntityInfo = this.Context.EntityMaintenance.GetEntityInfo() + }; + return result; + } + public SplitTableContext SplitHelper(Type entityType) + { + UtilMethods.StartCustomSplitTable(this, entityType); + var result = new SplitTableContext(this.Context) + { + EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(entityType) + }; + return result; + } + public SplitTableContextResult SplitHelper(T data) where T : class, new() + { + UtilMethods.StartCustomSplitTable(this, typeof(T)); + var result = new SplitTableContext(this.Context) + { + EntityInfo = this.Context.EntityMaintenance.GetEntityInfo() + }; + return new SplitTableContextResult() + { + Items = new List { data }, + Helper = result + }; + } + public SplitTableContextResult SplitHelper(List data) where T : class, new() + { + UtilMethods.StartCustomSplitTable(this, typeof(T)); + var result = new SplitTableContext(this.Context) + { + EntityInfo = this.Context.EntityMaintenance.GetEntityInfo() + }; + return new SplitTableContextResult() + { + Items = data, + Helper = result + }; + } + #endregion + + #region AsTenant + public ITenant AsTenant() + { + if (this.Root != null) + { + return this.Root; + } + else + { + Check.Exception(true, ErrorMessage.GetThrowMessage("Child objects do not support tenant methods, var childDb= Db.GetConnection(confid) ,Db is master ", "Db子对象不支持租户方法,请使用主对象,例如:var childDb= Db.GetConnection(confid) Db是主对象,childDb是子对象 ")); + return null; + } + } + + #endregion + + #region Fastest + public IFastest Fastest() where T : class, new() + { + return new FastestProvider(this); + } + #endregion + + #region Other + public Task AsyncLock(int timeOutSeconds = 30) + { + var result = new SugarAsyncLock(this); + return result.AsyncLock(timeOutSeconds); + } + public DynamicBuilder DynamicBuilder() + { + return new DynamicBuilder(this.Context); + } + public void Tracking(T data) where T : class, new() + { + if (data != null) + { + UtilMethods.IsNullReturnNew(this.TempItems); + var key = "Tracking_" + data.GetHashCode() + ""; + if (!this.TempItems.ContainsKey(key)) + { + var newT = new T(); + FastCopy.Copy(data, newT); + this.TempItems.Add(key, newT); + } + } + } + public void ClearTracking() + { + if (this.Context.TempItems != null) + { + var removeKeys = this.Context.TempItems.Where(it => it.Key.StartsWith("Tracking_") || it.Key.StartsWith("OldData_")).Select(it => it.Key).ToList(); + foreach (string key in removeKeys) + { + this.Context.TempItems.Remove(key); + } + } + } + public void Tracking(List datas) where T : class, new() + { + foreach (var data in datas) + { + this.Tracking(data); + } + if (datas != null) + { + Check.ExceptionEasy(this.Context.TempItems.ContainsKey("OldData_" + datas.GetHashCode()), "The object already has a trace", "对象已存在跟踪,如果要在跟踪可以先清除 db.ClearTracking() "); + this.Context.TempItems.Add("OldData_" + datas.GetHashCode(), datas.Cast().ToList()); + } + } + public SqlSugarClient CopyNew() + { + var result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); + result.QueryFilter = this.QueryFilter; + return result; + } + public void ThenMapper(IEnumerable list, Action action) + { + this.Context.Utilities.PageEach(list, 200, pageList => + { + _ThenMapper(pageList, action); + }); + } + + public async Task ThenMapperAsync(IEnumerable list, Func action) + { + await Context.Utilities.PageEachAsync(list, 200, async pageList => + { + await _ThenMapperAsync(pageList, action).ConfigureAwait(false); + }).ConfigureAwait(false); + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarScopeProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarScopeProvider.cs new file mode 100644 index 000000000..95ec55a17 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/SugarProvider/SqlSugarScopeProvider.cs @@ -0,0 +1,862 @@ +using System.Data; +using System.Diagnostics; +using System.Dynamic; +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SqlSugarScopeProvider : ISqlSugarClient + { + internal SqlSugarProvider conn; + internal string initThreadMainId; + internal string initkey = null; + StackFrame[] frames; + + public SqlSugarScopeProvider(SqlSugarProvider conn) + { + this.conn = conn; + this.initThreadMainId = GetCurrentThreadId(); + var key = GetKey(); + this.initkey = key; + this.GetContext(true); + } + + private static string GetCurrentThreadId() + { + return Environment.CurrentManagedThreadId + ""; + } + + public SqlSugarProvider ScopedContext { get { return GetContext(); } } + private SqlSugarProvider GetAsyncContext(bool isInit = false) + { + if (isInit) + { + CallContextAsync.SetData(GetKey(), this.conn); + isInit = false; + return conn; + } + else + { + SqlSugarProvider result = CallContextAsync.GetData(GetKey()); + if (result == null) + { + SqlSugarProvider db = new SqlSugarProvider(this.conn.CurrentConnectionConfig); + CallContextAsync.SetData(GetKey(), db); + return db; + } + else + { + + return result; + } + } + } + private SqlSugarProvider GetThreadContext(bool isInit = false) + { + if (isInit) + { + CallContextThread.SetData(GetKey(), this.conn); + isInit = false; + return conn; + } + else + { + SqlSugarProvider result = CallContextThread.GetData(GetKey()); + if (result == null) + { + SqlSugarProvider db = new SqlSugarProvider(this.conn.CurrentConnectionConfig); + CallContextThread.SetData(GetKey(), db); + return db; + } + else + { + + return result; + } + } + } + protected virtual SqlSugarProvider GetContext(bool isInit = false) + { + SqlSugarProvider result = null; + var key = GetKey(); ; + StackTrace st = new StackTrace(true); + var methods = st.GetFrames(); + var isAsync = UtilMethods.IsAnyAsyncMethod(methods); + if (isAsync) + { + result = GetAsyncContext(isInit); + } + else + { + result = GetThreadContext(isInit); + } + return result; + } + private string GetKey() + { + if (!string.IsNullOrEmpty(this.initkey) && this.initThreadMainId == GetCurrentThreadId()) + { + return this.initkey; + } + var key = "SqlSugarProviderScope_" + conn.CurrentConnectionConfig.ConfigId; + if (frames == null) + { + frames = new StackTrace(true).GetFrames(); + } + if (true) + { + foreach (var method in frames.Take(35)) + { + var refType = method.GetMethod()?.ReflectedType; + if (refType != null) + { + var getInterfaces = refType.Name.StartsWith('<') ? refType?.ReflectedType?.GetInterfaces() : refType?.GetInterfaces(); + if (getInterfaces?.Any(it => it.Name.IsIn("IJob")) == true) + { + key = $"{key}IJob"; + break; + } + } + } + } + return key; + } + + #region API + public Task AsyncLock(int timeOutSeconds = 30) + { + return ScopedContext.AsyncLock(timeOutSeconds); + } + public SugarActionType SugarActionType { get => ScopedContext.SugarActionType; set => ScopedContext.SugarActionType = value; } + public MappingTableList MappingTables { get => ScopedContext.MappingTables; set => ScopedContext.MappingTables = value; } + public MappingColumnList MappingColumns { get => ScopedContext.MappingColumns; set => ScopedContext.MappingColumns = value; } + public IgnoreColumnList IgnoreColumns { get => ScopedContext.IgnoreColumns; set => ScopedContext.IgnoreColumns = value; } + public IgnoreColumnList IgnoreInsertColumns { get => ScopedContext.IgnoreInsertColumns; set => ScopedContext.IgnoreInsertColumns = value; } + public Dictionary TempItems { get => ScopedContext.TempItems; set => ScopedContext.TempItems = value; } + public ConfigQuery ConfigQuery { get => ScopedContext.ConfigQuery; set => ScopedContext.ConfigQuery = value; } + + public Guid ContextID { get => ScopedContext.ContextID; set => ScopedContext.ContextID = value; } + public ConnectionConfig CurrentConnectionConfig { get => ScopedContext.CurrentConnectionConfig; set => ScopedContext.CurrentConnectionConfig = value; } + + public IAdo Ado => ScopedContext.Ado; + + public AopProvider Aop => ScopedContext.Aop; + + public ICodeFirst CodeFirst => ScopedContext.CodeFirst; + + public IDbFirst DbFirst => ScopedContext.DbFirst; + + public IDbMaintenance DbMaintenance => ScopedContext.DbMaintenance; + + public EntityMaintenance EntityMaintenance { get => ScopedContext.EntityMaintenance; set => ScopedContext.EntityMaintenance = value; } + public QueryFilterProvider QueryFilter { get => ScopedContext.QueryFilter; set => ScopedContext.QueryFilter = value; } + public IContextMethods Utilities { get => ScopedContext.Utilities; set => ScopedContext.Utilities = value; } + public QueueList Queues { get => ScopedContext.Queues; set => ScopedContext.Queues = value; } + + public SugarCacheProvider DataCache => ScopedContext.DataCache; + + + public void AddQueue(string sql, object parsmeters = null) + { + ScopedContext.AddQueue(sql, parsmeters); + } + + public void AddQueue(string sql, List parsmeters) + { + ScopedContext.AddQueue(sql, parsmeters); + } + + public void AddQueue(string sql, SugarParameter parsmeter) + { + ScopedContext.AddQueue(sql, parsmeter); + } + + + public void Close() + { + ScopedContext.Close(); + } + public DeleteMethodInfo DeleteableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.DeleteableByObject(singleEntityObjectOrListObject); + } + public IDeleteable Deleteable() where T : class, new() + { + return ScopedContext.Deleteable(); + } + + public IDeleteable Deleteable(dynamic primaryKeyValue) where T : class, new() + { + return ScopedContext.Deleteable(primaryKeyValue); + } + + public IDeleteable Deleteable(dynamic[] primaryKeyValues) where T : class, new() + { + return ScopedContext.Deleteable(primaryKeyValues); + } + + public IDeleteable Deleteable(Expression> expression) where T : class, new() + { + return ScopedContext.Deleteable(expression); + } + + public IDeleteable Deleteable(List pkValue) where T : class, new() + { + return ScopedContext.Deleteable(pkValue); + } + + public IDeleteable Deleteable(List deleteObjs) where T : class, new() + { + return ScopedContext.Deleteable(deleteObjs); + } + + public IDeleteable Deleteable(T deleteObj) where T : class, new() + { + return ScopedContext.Deleteable(deleteObj); + } + + public void Dispose() + { + ScopedContext.Dispose(); + } + + public DateTime GetDate() + { + return ScopedContext.GetDate(); + } + public T CreateContext(bool isTran) where T : SugarUnitOfWork, new() + { + Check.ExceptionEasy(" var childDb=Db.GetConnection(configId); use Db.CreateContext ", " 例如 var childDb=Db.GetConnection(configId);其中Db才能使用CreateContext,childDb不能使用"); + return null; + } + public SugarUnitOfWork CreateContext(bool isTran = true) + { + Check.ExceptionEasy(" var childDb=Db.GetConnection(configId); use Db.CreateContext ", " 例如 var childDb=Db.GetConnection(configId);其中Db才能使用CreateContext,childDb不能使用"); + return null; + } + public SimpleClient GetSimpleClient() where T : class, new() + { + return ScopedContext.GetSimpleClient(); + } + public RepositoryType GetRepository() where RepositoryType : ISugarRepository, new() + { + return ScopedContext.GetRepository(); + } + public void InitMappingInfo(Type type) + { + ScopedContext.InitMappingInfo(type); + } + + public void InitMappingInfo() + { + ScopedContext.InitMappingInfo(); + } + public IInsertable> InsertableByDynamic(object insertDynamicObject) + { + return ScopedContext.InsertableByDynamic(insertDynamicObject); + } + public InsertMethodInfo InsertableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.InsertableByObject(singleEntityObjectOrListObject); + } + public IInsertable Insertable(Dictionary columnDictionary) where T : class, new() + { + return ScopedContext.Insertable(columnDictionary); + } + + public IInsertable Insertable(dynamic insertDynamicObject) where T : class, new() + { + return ScopedContext.Insertable((object)insertDynamicObject); + } + + public IInsertable Insertable(List insertObjs) where T : class, new() + { + return ScopedContext.Insertable(insertObjs); + } + + public IInsertable Insertable(T insertObj) where T : class, new() + { + return ScopedContext.Insertable(insertObj); + } + + public IInsertable Insertable(T[] insertObjs) where T : class, new() + { + return ScopedContext.Insertable(insertObjs); + } + + public void Open() + { + ScopedContext.Open(); + } + public ISugarQueryable SlaveQueryable() + { + return ScopedContext.SlaveQueryable(); + } + public ISugarQueryable MasterQueryable() + { + return ScopedContext.MasterQueryable(); + } + public ISugarQueryable Queryable(string tableName, string shortName) + { + return ScopedContext.Queryable(tableName, shortName); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) + where T : class, new() + where T2 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) + where T : class, new() + where T2 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinType, joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, JoinType joinType1, Expression> joinExpression1, JoinType joinType2, Expression> joinExpression2) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinType1, joinExpression1, joinType2, joinExpression2); + } + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, ISugarQueryable joinQueryable4, JoinType joinType1, Expression> joinExpression1, JoinType joinType2, Expression> joinExpression2, JoinType joinType3, Expression> joinExpression3) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + where T4 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinQueryable4, joinType1, joinExpression1, joinType2, joinExpression2, joinType3, joinExpression3); + } + public ISugarQueryable Queryable() + { + return ScopedContext.Queryable(); + } + + public ISugarQueryable Queryable(ISugarQueryable queryable) + { + return ScopedContext.Queryable(queryable); + } + + public ISugarQueryable Queryable(ISugarQueryable queryable, string shortName) + { + return ScopedContext.Queryable(queryable, shortName); + } + public ISugarQueryable Queryable(string shortName) + { + return ScopedContext.Queryable(shortName); + } + + public IReportable Reportable(T data) + { + return ScopedContext.Reportable(data); + } + + public IReportable Reportable(List list) + { + return ScopedContext.Reportable(list); + } + + public IReportable Reportable(T[] array) + { + return ScopedContext.Reportable(array); + } + + public int SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public List SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Task SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public ISugarQueryable SqlQueryable(string sql) where T : class, new() + { + return ScopedContext.SqlQueryable(sql); + } + public IStorageable Storageable(T[] dataList) where T : class, new() + { + return ScopedContext.Storageable(dataList); + } + public StorageableDataTable Storageable(List> dictionaryList, string tableName) + { + return ScopedContext.Storageable(dictionaryList, tableName); + } + public StorageableDataTable Storageable(Dictionary dictionary, string tableName) + { + return ScopedContext.Storageable(dictionary, tableName); + } + + public IStorageable Storageable(List dataList) where T : class, new() + { + return ScopedContext.Storageable(dataList); + } + public IStorageable Storageable(IList dataList) where T : class, new() + { + return ScopedContext.Storageable(dataList?.ToList()); + } + public IStorageable Storageable(T data) where T : class, new() + { + return ScopedContext.Storageable(data); + } + public StorageableDataTable Storageable(DataTable data) + { + return ScopedContext.Storageable(data); + } + public StorageableMethodInfo StorageableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.StorageableByObject(singleEntityObjectOrListObject); + } + + public ISugarQueryable Union(List> queryables) where T : class + { + return ScopedContext.Union(queryables); + } + + public ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class + { + return ScopedContext.Union(queryables); + } + + public ISugarQueryable UnionAll(List> queryables) where T : class + { + return ScopedContext.UnionAll(queryables); + } + + public ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class + { + return ScopedContext.UnionAll(queryables); + } + public UpdateExpressionMethodInfo UpdateableByObject(Type entityType) + { + return ScopedContext.UpdateableByObject(entityType); + } + public UpdateMethodInfo UpdateableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.UpdateableByObject(singleEntityObjectOrListObject); + } + public IUpdateable> UpdateableByDynamic(object updateDynamicObject) + { + return ScopedContext.UpdateableByDynamic(updateDynamicObject); + } + + public IUpdateable Updateable() where T : class, new() + { + return ScopedContext.Updateable(); + } + + public IUpdateable Updateable(Dictionary columnDictionary) where T : class, new() + { + return ScopedContext.Updateable(columnDictionary); + } + + public IUpdateable Updateable(dynamic updateDynamicObject) where T : class, new() + { + return ScopedContext.Updateable((object)updateDynamicObject); + } + + public IUpdateable Updateable(Expression> columns) where T : class, new() + { + return ScopedContext.Updateable(columns); + } + + public IUpdateable Updateable(Expression> columns) where T : class, new() + { + return ScopedContext.Updateable(columns); + } + + public IUpdateable Updateable(List UpdateObjs) where T : class, new() + { + return ScopedContext.Updateable(UpdateObjs); + } + + public IUpdateable Updateable(T UpdateObj) where T : class, new() + { + return ScopedContext.Updateable(UpdateObj); + } + + public IUpdateable Updateable(T[] UpdateObjs) where T : class, new() + { + return ScopedContext.Updateable(UpdateObjs); + } + public SplitTableContext SplitHelper() where T : class, new() + { + return ScopedContext.SplitHelper(); + } + public SplitTableContext SplitHelper(Type entityType) + { + return ScopedContext.SplitHelper(entityType); + } + public SplitTableContextResult SplitHelper(T data) where T : class, new() + { + return ScopedContext.SplitHelper(data); + } + public SplitTableContextResult SplitHelper(List dataList) where T : class, new() + { + return ScopedContext.SplitHelper(dataList); + } + public IFastest Fastest() where T : class, new() + { + return ScopedContext.Fastest(); + } + + public void ThenMapper(IEnumerable list, Action action) + { + ScopedContext.ThenMapper(list, action); + } + + public Task ThenMapperAsync(IEnumerable list, Func action) + { + return ScopedContext.ThenMapperAsync(list, action); + } + + public ITenant AsTenant() + { + return ScopedContext.AsTenant(); + } + + public ISaveable Saveable(List saveObjects) where T : class, new() + { + return ScopedContext.Saveable(saveObjects); + } + + public ISaveable Saveable(T saveObject) where T : class, new() + { + return ScopedContext.Saveable(saveObject); + } + public InsertNavTaskInit InsertNav(T data) where T : class, new() + { + return ScopedContext.InsertNav(data); + } + public InsertNavTaskInit InsertNav(List datas) where T : class, new() + { + return ScopedContext.InsertNav(datas); + } + public InsertNavTaskInit InsertNav(T data, InsertNavRootOptions rootOptions) where T : class, new() + { + return ScopedContext.InsertNav(data, rootOptions); + } + public InsertNavTaskInit InsertNav(List datas, InsertNavRootOptions rootOptions) where T : class, new() + { + return ScopedContext.InsertNav(datas, rootOptions); + } + public DeleteNavTaskInit DeleteNav(T data) where T : class, new() + { + return ScopedContext.DeleteNav(data); + } + public DeleteNavTaskInit DeleteNav(List datas) where T : class, new() + { + return ScopedContext.DeleteNav(datas); + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression) where T : class, new() + { + return ScopedContext.DeleteNav(whereExpression); + } + public DeleteNavTaskInit DeleteNav(T data, DeleteNavRootOptions options) where T : class, new() + { + return ScopedContext.DeleteNav(data, options); + } + public DeleteNavTaskInit DeleteNav(List datas, DeleteNavRootOptions options) where T : class, new() + { + return ScopedContext.DeleteNav(datas, options); + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression, DeleteNavRootOptions options) where T : class, new() + { + return ScopedContext.DeleteNav(whereExpression, options); + } + public UpdateNavTaskInit UpdateNav(T data) where T : class, new() + { + return ScopedContext.UpdateNav(data); + } + public UpdateNavTaskInit UpdateNav(List datas) where T : class, new() + { + return ScopedContext.UpdateNav(datas); + } + public UpdateNavTaskInit UpdateNav(List datas, UpdateNavRootOptions rootOptions) where T : class, new() + { + return this.ScopedContext.UpdateNav(datas, rootOptions); + } + public UpdateNavTaskInit UpdateNav(T data, UpdateNavRootOptions rootOptions) where T : class, new() + { + return this.ScopedContext.UpdateNav(data, rootOptions); + } + public SqlSugarClient CopyNew() + { + var result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); + result.QueryFilter = this.QueryFilter; + return result; + } + public DynamicBuilder DynamicBuilder() + { + return ScopedContext.DynamicBuilder(); + } + public void Tracking(T data) where T : class, new() + { + ScopedContext.Tracking(data); + } + public void Tracking(List datas) where T : class, new() + { + ScopedContext.Tracking(datas); + } + public QueryMethodInfo QueryableByObject(Type entityType) + { + return ScopedContext.QueryableByObject(entityType); + } + public QueryMethodInfo QueryableByObject(Type entityType, string shortName) + { + return ScopedContext.QueryableByObject(entityType, shortName); + } + public GridSaveProvider GridSave(List oldList, List saveList) where T : class, new() + { + return ScopedContext.GridSave(oldList, saveList); + } + public GridSaveProvider GridSave(List saveList) where T : class, new() + { + return ScopedContext.GridSave(saveList); + } + public void ClearTracking() + { + ScopedContext.ClearTracking(); + } + #endregion + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/ParameterUpdateable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/ParameterUpdateable.cs new file mode 100644 index 000000000..96f0ea851 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/ParameterUpdateable.cs @@ -0,0 +1,197 @@ +using System.Data; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class ParameterUpdateable where T : class, new() + { + internal UpdateableProvider Updateable { get; set; } + internal SqlSugarProvider Context { get; set; } + public int ExecuteCommand() + { + var result = 0; + var list = Updateable.UpdateObjs; + var count = list.Length; + var size = GetPageSize(20, count); + Context.Utilities.PageEach(list.ToList(), size, item => + { + Before(item.ToList()); + List allParamter = new List(); + var sql = GetSql(item); + result += Context.Ado.ExecuteCommand(sql.Key, sql.Value); + After(item.ToList()); + }); + return result < 0 ? count : result; + } + public async Task ExecuteCommandAsync() + { + var result = 0; + var list = Updateable.UpdateObjs; + var count = list.Length; + var size = GetPageSize(20, count); + await Context.Utilities.PageEachAsync(list.ToList(), size, async item => + { + Before(item.ToList()); + List allParamter = new List(); + var sql = GetSql(item); + result += await Context.Ado.ExecuteCommandAsync(sql.Key, sql.Value).ConfigureAwait(false); + After(item.ToList()); + }).ConfigureAwait(false); + return result < 0 ? count : result; + } + + + private void Before(List updateObjects) + { + if (this.Updateable.IsEnableDiffLogEvent && updateObjects.Count > 0) + { + var isDisableMasterSlaveSeparation = this.Updateable.Ado.IsDisableMasterSlaveSeparation; + this.Updateable.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = Updateable.UpdateBuilder.Parameters; + if (parameters == null) + parameters = new List(); + Updateable.diffModel.BeforeData = GetDiffTable(updateObjects); + Updateable.diffModel.Sql = this.Updateable.UpdateBuilder.ToSqlString(); + Updateable.diffModel.Parameters = parameters.ToArray(); + this.Updateable.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + } + + protected void After(List updateObjects) + { + if (this.Updateable.IsEnableDiffLogEvent && updateObjects.Count > 0) + { + var isDisableMasterSlaveSeparation = this.Updateable.Ado.IsDisableMasterSlaveSeparation; + this.Updateable.Ado.IsDisableMasterSlaveSeparation = true; + Updateable.diffModel.AfterData = GetDiffTable(updateObjects); + Updateable.diffModel.Time = this.Context.Ado.SqlExecutionTime; + if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) + this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(Updateable.diffModel); + this.Updateable.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + if (this.Updateable.RemoveCacheFunc != null) + { + this.Updateable.RemoveCacheFunc(); + } + } + private List GetDiffTable(List updateObjects) + { + var builder = Updateable.UpdateBuilder.Builder; + var tableWithString = builder.GetTranslationColumnName(Updateable.UpdateBuilder.TableName); + var wheres = Updateable.WhereColumnList ?? Updateable.UpdateBuilder.PrimaryKeys; + if (wheres == null) + { + wheres = Updateable.UpdateBuilder.DbColumnInfoList + .Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).Distinct().ToList(); + } + var sqlDb = this.Context.CopyNew(); + sqlDb.Aop.DataExecuting = null; + var dataColumns = sqlDb.Updateable(updateObjects).UpdateBuilder.DbColumnInfoList; + List parameters = new List(); + StringBuilder allWhereString = new StringBuilder(); + string columnStr = string.Join(",", dataColumns.Select(x => x.DbColumnName).Distinct().ToList()); + foreach (var item in dataColumns.GroupBy(it => it.TableId)) + { + StringBuilder whereString = new StringBuilder(); + foreach (var whereItem in wheres) + { + var pk = item.FirstOrDefault(it => it.DbColumnName.EqualCase(whereItem)); + var paraterName = FormatValue(pk.PropertyType, pk.DbColumnName, pk.Value, parameters); + whereString.Append($" {pk.DbColumnName} = {paraterName} AND"); + } + allWhereString.Append($" {Regex.Replace(whereString.ToString(), "AND$", "")} OR"); + } + string key = $"SELECT {columnStr} FROM {tableWithString} WHERE {Regex.Replace(allWhereString.ToString(), "OR$", "")}"; + + var dt = sqlDb.Ado.GetDataTable(key, parameters); + return Updateable.GetTableDiff(dt); + } + + #region Values Helper + + public KeyValuePair GetSql(List updateObjects) + { + var inserable = Updateable as UpdateableProvider; + var builder = inserable.UpdateBuilder.Builder; + var columns = inserable.UpdateBuilder.DbColumnInfoList.GroupBy(it => it.DbColumnName).Select(it => it.Key).Distinct().ToList(); + var tableWithString = builder.GetTranslationColumnName(inserable.UpdateBuilder.TableName); + var wheres = inserable.WhereColumnList ?? inserable.UpdateBuilder.PrimaryKeys; + if (wheres == null) + { + wheres = inserable.UpdateBuilder.DbColumnInfoList + .Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).Distinct().ToList(); + } + StringBuilder sbAllSql = new StringBuilder(); + var sqlTemp = ($" UPDATE {tableWithString} SET {{0}} WHERE {{1}};\r\n"); + List parameters = new List(); + Check.ExceptionEasy(wheres?.Count == 0, "Updates cannot be without a primary key or condition", "更新不能没有主键或者条件"); + var sqlDb = this.Context.CopyNew(); + sqlDb.Aop.DataExecuting = null; + foreach (var item in sqlDb.Updateable(updateObjects).UpdateBuilder.DbColumnInfoList.GroupBy(it => it.TableId)) + { + var list = item.ToList(); + Check.ExceptionEasy(list?.Count == 0, "Set has no columns", "更新Set没有列"); + StringBuilder setString = new StringBuilder(); + foreach (var setItem in list) + { + if (setItem.IsPrimarykey) { continue; } + if (Updateable.UpdateBuilder.UpdateColumns?.Count > 0) + { + if (!Updateable.UpdateBuilder.UpdateColumns.Any(it => it.EqualCase(setItem.DbColumnName))) + { + continue; + } + } + if (Updateable.UpdateBuilder.IgnoreColumns?.Count > 0) + { + if (Updateable.UpdateBuilder.IgnoreColumns.Any(it => it.EqualCase(setItem.DbColumnName))) + { + continue; + } + } + var paraterName = FormatValue(setItem.PropertyType, setItem.DbColumnName, setItem.Value, parameters); + setString.Append($" {builder.GetTranslationColumnName(setItem.DbColumnName)} = {paraterName} ,"); + } + StringBuilder whereString = new StringBuilder(); + foreach (var whereItem in wheres) + { + var pk = list.FirstOrDefault(it => it.DbColumnName.EqualCase(whereItem)); + var paraterName = FormatValue(pk.PropertyType, pk.DbColumnName, pk.Value, parameters); + whereString.Append($" {pk.DbColumnName} = {paraterName} AND"); + } + var builderItem = string.Format(sqlTemp, setString.ToString().TrimEnd(','), whereString.ToString().TrimEnd('D').TrimEnd('N').TrimEnd('A')); + sbAllSql.Append(builderItem); + } + builder.FormatSaveQueueSql(sbAllSql); + return new KeyValuePair(sbAllSql.ToString(), parameters.ToArray()); + } + + private int GetPageSize(int pageSize, int count) + { + if (pageSize * count > 2100) + { + pageSize = 50; + } + if (pageSize * count > 2100) + { + pageSize = 20; + } + if (pageSize * count > 2100) + { + pageSize = 10; + } + + return pageSize; + } + private string FormatValue(Type type, string name, object value, List allParamter) + { + var keyword = this.Updateable.UpdateBuilder.Builder.SqlParameterKeyWord; + var result = keyword + name + allParamter.Count; + var addParameter = new SugarParameter(result, value, type); + allParamter.Add(addParameter); + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/SplitTableUpdateByObjectProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/SplitTableUpdateByObjectProvider.cs new file mode 100644 index 000000000..d9ee88343 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/SplitTableUpdateByObjectProvider.cs @@ -0,0 +1,164 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class SplitTableUpdateByObjectProvider where T : class, new() + { + public SqlSugarProvider Context; + public UpdateableProvider updateobj; + public T[] UpdateObjects { get; set; } + + public IEnumerable Tables { get; set; } + internal List WhereColumns { get; set; } + internal bool IsEnableDiffLogEvent { get; set; } + internal object BusinessData { get; set; } + + public int ExecuteCommandWithOptLock(bool isThrowError = false) + { + List groupModels; + int result; + GroupDataList(UpdateObjects, out groupModels, out result); + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + this.Context.Aop.DataExecuting = null; + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + if (IsVersion()) + { + Check.ExceptionEasy(addList.Count > 1, "The version number can only be used for single record updates", "版本号只能用于单条记录更新"); + result += this.Context.Updateable(addList.First()) + .WhereColumns(this.WhereColumns?.ToArray()) + .EnableDiffLogEventIF(this.IsEnableDiffLogEvent, this.BusinessData) + .UpdateColumns(updateobj.UpdateBuilder.UpdateColumns?.ToArray()) + .IgnoreColumns(this.updateobj.UpdateBuilder.IsNoUpdateNull, this.updateobj.UpdateBuilder.IsOffIdentity, this.updateobj.UpdateBuilder.IsNoUpdateDefaultValue) + .IgnoreColumns(GetIgnoreColumns()).AS(item.Key).ExecuteCommandWithOptLock(isThrowError); + } + else + { + result += this.Context.Updateable(addList) + .WhereColumns(this.WhereColumns?.ToArray()) + .EnableDiffLogEventIF(this.IsEnableDiffLogEvent, this.BusinessData) + .UpdateColumns(updateobj.UpdateBuilder.UpdateColumns?.ToArray()) + .IgnoreColumns(this.updateobj.UpdateBuilder.IsNoUpdateNull, this.updateobj.UpdateBuilder.IsOffIdentity, this.updateobj.UpdateBuilder.IsNoUpdateDefaultValue) + .IgnoreColumns(GetIgnoreColumns()).AS(item.Key).ExecuteCommandWithOptLock(isThrowError); + } + } + this.Context.Aop.DataExecuting = dataEvent; + return result; + } + public int ExecuteCommand() + { + List groupModels; + int result; + GroupDataList(UpdateObjects, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + this.Context.Aop.DataExecuting = null; + result += this.Context.Updateable(addList) + .EnableDiffLogEventIF(this.IsEnableDiffLogEvent, this.BusinessData) + .WhereColumns(this.WhereColumns?.ToArray()) + .UpdateColumns(updateobj.UpdateBuilder.UpdateColumns?.ToArray()) + .IgnoreColumns(this.updateobj.UpdateBuilder.IsNoUpdateNull, this.updateobj.UpdateBuilder.IsOffIdentity, this.updateobj.UpdateBuilder.IsNoUpdateDefaultValue) + .IgnoreColumns(GetIgnoreColumns()).AS(item.Key).ExecuteCommand(); + this.Context.Aop.DataExecuting = dataEvent; + } + return result; + } + + + public async Task ExecuteCommandAsync() + { + List groupModels; + int result; + GroupDataList(UpdateObjects, out groupModels, out result); + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + this.Context.Aop.DataExecuting = null; + result += await Context.Updateable(addList) + .WhereColumns(WhereColumns?.ToArray()) + .EnableDiffLogEventIF(IsEnableDiffLogEvent, BusinessData) + .UpdateColumns(updateobj.UpdateBuilder.UpdateColumns?.ToArray()) + .IgnoreColumns(updateobj.UpdateBuilder.IsNoUpdateNull, updateobj.UpdateBuilder.IsOffIdentity, updateobj.UpdateBuilder.IsNoUpdateDefaultValue) + .IgnoreColumns(GetIgnoreColumns()).AS(item.Key).ExecuteCommandAsync().ConfigureAwait(false); + this.Context.Aop.DataExecuting = dataEvent; + } + return result; + } + public async Task ExecuteCommandWithOptLockAsync(bool isThrowError = false) + { + List groupModels; + int result; + GroupDataList(UpdateObjects, out groupModels, out result); + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + this.Context.Aop.DataExecuting = null; + foreach (var item in groupModels.GroupBy(it => it.GroupName)) + { + var addList = item.Select(it => it.Item).ToList(); + if (IsVersion()) + { + Check.ExceptionEasy(addList.Count > 1, "The version number can only be used for single record updates", "版本号只能用于单条记录更新"); + result += await Context.Updateable(addList.First()) + .WhereColumns(WhereColumns?.ToArray()) + .EnableDiffLogEventIF(IsEnableDiffLogEvent, BusinessData) + .UpdateColumns(updateobj.UpdateBuilder.UpdateColumns?.ToArray()) + .IgnoreColumns(updateobj.UpdateBuilder.IsNoUpdateNull, updateobj.UpdateBuilder.IsOffIdentity, updateobj.UpdateBuilder.IsNoUpdateDefaultValue) + .IgnoreColumns(GetIgnoreColumns()).AS(item.Key).ExecuteCommandWithOptLockAsync(isThrowError).ConfigureAwait(false); + + } + else + { + result += await Context.Updateable(addList) + .WhereColumns(WhereColumns?.ToArray()) + .EnableDiffLogEventIF(IsEnableDiffLogEvent, BusinessData) + .UpdateColumns(updateobj.UpdateBuilder.UpdateColumns?.ToArray()) + .IgnoreColumns(updateobj.UpdateBuilder.IsNoUpdateNull, updateobj.UpdateBuilder.IsOffIdentity, updateobj.UpdateBuilder.IsNoUpdateDefaultValue) + .IgnoreColumns(GetIgnoreColumns()).AS(item.Key).ExecuteCommandWithOptLockAsync(isThrowError).ConfigureAwait(false); + } + } + this.Context.Aop.DataExecuting = dataEvent; + return result; + } + private string[] GetIgnoreColumns() + { + if (this.updateobj.UpdateBuilder.DbColumnInfoList.Count != 0) + { + var columns = this.updateobj.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName).Distinct().ToList(); + var result = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(x => !columns.Any(y => y.EqualCase(x.DbColumnName))).Select(it => it.DbColumnName).ToArray(); + result = result.Where(it => !string.IsNullOrEmpty(it)).ToArray(); + return result; + } + else + { + return null; + } + } + private void GroupDataList(T[] datas, out List groupModels, out int result) + { + var attribute = typeof(T).GetCustomAttribute() as SplitTableAttribute; + Check.Exception(attribute == null, $"{typeof(T).Name} need SplitTableAttribute"); + groupModels = new List(); + var db = this.Context; + foreach (var item in datas) + { + var value = db.SplitHelper().GetValue(attribute.SplitType, item); + var tableName = db.SplitHelper().GetTableName(attribute.SplitType, value); + groupModels.Add(new GroupModel() { GroupName = tableName, Item = item }); + } + result = 0; + } + private bool IsVersion() + { + return this.Context.EntityMaintenance.GetEntityInfo().Columns.Any(it => it.IsEnableUpdateVersionValidation); + } + + internal class GroupModel + { + public string GroupName { get; set; } + public T Item { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/SplitTableUpdateProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/SplitTableUpdateProvider.cs new file mode 100644 index 000000000..ae177822d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/SplitTableUpdateProvider.cs @@ -0,0 +1,109 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SplitTableUpdateProvider where T : class, new() + { + public SqlSugarProvider Context; + public UpdateableProvider updateobj; + + public IEnumerable Tables { get; set; } + + public int ExecuteCommandWithOptLock(bool isThrowError = false) + { + var updates = updateobj.UpdateObjs; + var tableName = this.Context.SplitHelper(updates.FirstOrDefault()).GetTableName(); + var names = updateobj.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName).Distinct().ToArray(); + return this.Context.Updateable(updates).AS(tableName) + .UpdateColumns(names).ExecuteCommandWithOptLock(isThrowError); + } + public int ExecuteCommand() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = _ExecuteCommand(); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return _ExecuteCommand(); + } + } + public async Task ExecuteCommandWithOptLockAsync(bool isThrowError = false) + { + var updates = updateobj.UpdateObjs; + var tableName = this.Context.SplitHelper(updates.FirstOrDefault()).GetTableName(); + var names = updateobj.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName).Distinct().ToArray(); + return await Context.Updateable(updates).AS(tableName) + .UpdateColumns(names).ExecuteCommandWithOptLockAsync(isThrowError).ConfigureAwait(false); + } + public async Task ExecuteCommandAsync() + { + if (this.Context.Ado.Transaction == null) + { + try + { + this.Context.Ado.BeginTran(); + var result = await _ExecuteCommandAsync().ConfigureAwait(false); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception) + { + this.Context.Ado.RollbackTran(); + throw; + } + } + else + { + return await _ExecuteCommandAsync().ConfigureAwait(false); + } + } + private int _ExecuteCommand() + { + var result = 0; + var sqlobj = updateobj.ToSql(); + + foreach (var item in Tables) + { + var newsqlobj = GetSqlObj(sqlobj, item.TableName); + result += this.Context.Ado.ExecuteCommand(newsqlobj.Key, newsqlobj.Value); + } + return result; + } + + private async Task _ExecuteCommandAsync() + { + var result = 0; + var sqlobj = updateobj.ToSql(); + foreach (var item in Tables) + { + var newsqlobj = GetSqlObj(sqlobj, item.TableName); + result += await Context.Ado.ExecuteCommandAsync(newsqlobj.Key, newsqlobj.Value).ConfigureAwait(false); + } + return result; + } + + private KeyValuePair> GetSqlObj(KeyValuePair> keyValuePair, string asName) + { + List pars = new List(); + string sql = keyValuePair.Key; + if (keyValuePair.Value != null) + { + pars = keyValuePair.Value.Select(it => new SugarParameter(it.ParameterName, it.Value)).ToList(); + } + sql = Regex.Replace(sql, updateobj.EntityInfo.DbTableName, asName, RegexOptions.IgnoreCase); + return new KeyValuePair>(sql, pars); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateExpressionMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateExpressionMethodInfo.cs new file mode 100644 index 000000000..8c82aba0d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateExpressionMethodInfo.cs @@ -0,0 +1,61 @@ +using System.Reflection; +namespace SqlSugar +{ + public class UpdateExpressionMethodInfo + { + internal SqlSugarProvider Context { get; set; } + internal MethodInfo MethodInfo { get; set; } + internal object objectValue { get; set; } + internal Type Type { get; set; } + + public int ExecuteCommand() + { + if (Context == null) return 0; + var result = objectValue.GetType().GetMethod("ExecuteCommand").Invoke(objectValue, Array.Empty()); + return (int)result; + } + + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var result = objectValue.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(objectValue, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + + public UpdateExpressionMethodInfo Where(string expShortName, FormattableString whereExpressionString) + { + var newMethod = objectValue.GetType().GetMyMethod("Where", 1); + var exp = DynamicCoreHelper.GetWhere(Type, expShortName, whereExpressionString); + var result = newMethod.Invoke(objectValue, new object[] { exp }); + return new UpdateExpressionMethodInfo() + { + objectValue = result, + Type = this.Type, + Context = this.Context + }; + } + public UpdateExpressionMethodInfo SetColumns(string expShortName, FormattableString fieldExpressionString) + { + + var newMethod = objectValue.GetType().GetMethods() + .Where(it => + { + var isTrue = it.Name == "SetColumns" && it.GetParameters().Length == 1; + if (isTrue) + { + return it.GetParameters().First().ToString().Contains(",System.Boolean"); + } + return false; + }) + .Single(); + var exp1 = DynamicCoreHelper.GetWhere(Type, expShortName, fieldExpressionString); + var result = newMethod.Invoke(objectValue, new object[] { exp1 }); + return new UpdateExpressionMethodInfo() + { + objectValue = result, + Type = this.Type, + Context = this.Context + }; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateMethodInfo.cs new file mode 100644 index 000000000..5742abb27 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateMethodInfo.cs @@ -0,0 +1,122 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class UpdateMethodInfo + { + internal SqlSugarProvider Context { get; set; } + internal MethodInfo MethodInfo { get; set; } + internal object objectValue { get; set; } + + public int ExecuteCommandWithOptLock(bool isThrowError = false) + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMyMethod("ExecuteCommandWithOptLock", 1, typeof(bool)).Invoke(inertable, new object[] { isThrowError }); + return (int)result; + } + + public async Task ExecuteCommandWithOptLockAsync(bool isThrowError = false) + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMyMethod("ExecuteCommandWithOptLockAsync", 1, typeof(bool)).Invoke(inertable, new object[] { isThrowError }); + return await ((Task)result).ConfigureAwait(false); + } + public int ExecuteCommand() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMethod("ExecuteCommand").Invoke(inertable, Array.Empty()); + return (int)result; + } + + public async Task ExecuteCommandAsync() + { + if (Context == null) return 0; + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var result = inertable.GetType().GetMyMethod("ExecuteCommandAsync", 0).Invoke(inertable, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public UpdateCommonMethodInfo EnableDiffLogEvent(object businessData = null) + { + if (Context == null) + { + return new UpdateCommonMethodInfo(); + } + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("EnableDiffLogEvent", 1, typeof(object)); + var result = newMethod.Invoke(inertable, new object[] { businessData }); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + public UpdateCommonMethodInfo IgnoreColumns(params string[] ignoreColumns) + { + if (Context == null) + { + return new UpdateCommonMethodInfo(); + } + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("IgnoreColumns", 1, typeof(string[])); + var result = newMethod.Invoke(inertable, new object[] { ignoreColumns }); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + public UpdateCommonMethodInfo IgnoreNullColumns() + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("IgnoreNullColumns", 0); + var result = newMethod.Invoke(inertable, Array.Empty()); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + public UpdateCommonMethodInfo UpdateColumns(params string[] updateColumns) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("UpdateColumns", 1, typeof(string[])); + var result = newMethod.Invoke(inertable, new object[] { updateColumns }); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + + public UpdateCommonMethodInfo WhereColumns(params string[] whereColumns) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("WhereColumns", 1, typeof(string[])); + var result = newMethod.Invoke(inertable, new object[] { whereColumns }); + return new UpdateCommonMethodInfo() + { + Context = result, + }; + } + + public UpdateCommonMethodInfo AS(string tableName) + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("AS", 1, typeof(string)); + var result = newMethod.Invoke(inertable, new object[] { tableName }); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + public UpdateCommonMethodInfo SplitTable() + { + var inertable = MethodInfo.Invoke(Context, new object[] { objectValue }); + var newMethod = inertable.GetType().GetMyMethod("SplitTable", 0); + var result = newMethod.Invoke(inertable, Array.Empty()); + return new UpdateCommonMethodInfo() + { + Context = result + }; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateNavMethodInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateNavMethodInfo.cs new file mode 100644 index 000000000..6906cbf6e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateNavMethodInfo.cs @@ -0,0 +1,49 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class UpdateNavMethodInfo + { + internal object MethodInfos { get; set; } + internal SqlSugarProvider Context { get; set; } + + public UpdateNavMethodInfo IncludeByNameString(string navMemberName, UpdateNavOptions updateNavOptions = null) + { + var type = MethodInfos.GetType().GetGenericArguments()[0]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.MethodInfos.GetType().GetMyMethod("Include", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this.MethodInfos, new object[] { exp, updateNavOptions }); + this.MethodInfos = obj; + return this; + } + public UpdateNavMethodInfo ThenIncludeByNameString(string navMemberName, UpdateNavOptions updateNavOptions = null) + { + var type = MethodInfos.GetType().GetGenericArguments()[1]; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type); + Type properyItemType; + bool isList; + Expression exp = UtilMethods.GetIncludeExpression(navMemberName, entityInfo, out properyItemType, out isList); + var method = this.MethodInfos.GetType().GetMyMethod("ThenInclude", 2, isList) + .MakeGenericMethod(properyItemType); + var obj = method.Invoke(this.MethodInfos, new object[] { exp, updateNavOptions }); + this.MethodInfos = obj; + return this; + } + public async Task ExecuteCommandAsync() + { + if (Context == null) return false; + var result = MethodInfos.GetType().GetMethod("ExecuteCommandAsync").Invoke(MethodInfos, Array.Empty()); + return await ((Task)result).ConfigureAwait(false); + } + public bool ExecuteCommand() + { + if (Context == null) return false; + var result = MethodInfos.GetType().GetMethod("ExecuteCommand").Invoke(MethodInfos, Array.Empty()); + return (bool)result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableFilter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableFilter.cs new file mode 100644 index 000000000..8f402adb5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableFilter.cs @@ -0,0 +1,102 @@ +namespace SqlSugar +{ + public class UpdateableFilter where T : class, new() + { + public T[] DataList { get; set; } + public SqlSugarProvider Context { get; set; } + public int PageSize { get; internal set; } + public string TableName { get; internal set; } + public bool IsEnableDiffLogEvent { get; internal set; } + public DiffLogModel DiffModel { get; internal set; } + public List UpdateColumns { get; internal set; } + public int ExecuteCommand() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + PageSize = 1; + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + this.Context.Utilities.PageEach(DataList, PageSize, pageItem => + { + result += SetFilterSql(this.Context.Updateable(pageItem.First()).AS(TableName).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).UpdateColumns(UpdateColumns.ToArray())).ExecuteCommand(); + }); + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return result; + } + + + + public async Task ExecuteCommandAsync() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + PageSize = 1; + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + await Context.Utilities.PageEachAsync(DataList, PageSize, async pageItem => + { + result += await SetFilterSql(Context.Updateable(pageItem.First()).AS(TableName).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).UpdateColumns(UpdateColumns.ToArray())).ExecuteCommandAsync().ConfigureAwait(false); + }).ConfigureAwait(false); + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return result; + } + + + private IUpdateable SetFilterSql(IUpdateable updateable) + { + var queryable = this.Context.Queryable(); + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 10000; + var sqlobj = queryable.ToSql(); + var sql = UtilMethods.RemoveBeforeFirstWhere(sqlobj.Key); + if (sql != sqlobj.Key) + { + updateable.UpdateBuilder.AppendWhere = sql; + } + if (sqlobj.Value != null) + { + updateable.UpdateBuilder.Parameters.AddRange(sqlobj.Value); + } + return updateable; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableHelper.cs new file mode 100644 index 000000000..8057d5a20 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableHelper.cs @@ -0,0 +1,889 @@ +using System.Data; +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class UpdateableProvider : IUpdateable where T : class, new() + { + private bool IsUpdateNullByList() + { + return this.UpdateObjs.Length > 1 && (this.UpdateBuilder.IsNoUpdateNull || this.UpdateBuilder.IsNoUpdateDefaultValue); + } + + private int DatasTrackingExecommand() + { + var trakRows = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + int i = 0; + foreach (var item in this.UpdateObjs) + { + var newUpdateable = this.Clone(); + (newUpdateable as UpdateableProvider).UpdateObjs = new[] { item }; + newUpdateable.UpdateBuilder.IsListUpdate = null; + newUpdateable.UpdateBuilder.DbColumnInfoList = + newUpdateable.UpdateBuilder.DbColumnInfoList.Where(it => it.TableId == i).ToList(); + AppendTracking(item, newUpdateable); + if (newUpdateable.UpdateBuilder.DbColumnInfoList?.Count > 0) + { + trakRows += newUpdateable.ExecuteCommand(); + } + ++i; + } + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return trakRows; + } + private async Task DatasTrackingExecommandAsync() + { + var isNoTran = this.Context.Ado.IsNoTran(); + var trakRows = 0; + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + int i = 0; + foreach (var item in this.UpdateObjs) + { + var newUpdateable = this.Clone(); + (newUpdateable as UpdateableProvider).UpdateObjs = new[] { item }; + newUpdateable.UpdateBuilder.IsListUpdate = null; + newUpdateable.UpdateBuilder.DbColumnInfoList = + newUpdateable.UpdateBuilder.DbColumnInfoList.Where(it => it.TableId == i).ToList(); + AppendTracking(item, newUpdateable); + if (newUpdateable.UpdateBuilder.DbColumnInfoList?.Count > 0) + { + trakRows += await newUpdateable.ExecuteCommandAsync().ConfigureAwait(false); + } + ++i; + } + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return trakRows; + } + private bool UpdateObjectNotWhere() + { + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) + { + return false; + } + return this.Context.CurrentConnectionConfig.DbType != DbType.MySql + && this.Context.CurrentConnectionConfig.DbType != DbType.MySqlConnector + && this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer; + } + private void AppendTracking(T item, IUpdateable newUpdateable) + { + if (IsTrakingData() || IsTrakingDatas()) + { + var trackingData = this.Context.TempItems.FirstOrDefault(it => it.Key.StartsWith("Tracking_" + item.GetHashCode())); + var diffColumns = FastCopy.GetDiff(item, (T)trackingData.Value); + if (diffColumns.Count > 0) + { + var pks = EntityInfo.Columns + .Where(it => it.IsPrimarykey).Select(it => it.PropertyName).ToList(); + diffColumns = diffColumns.Where(it => !pks.Contains(it)).ToList(); + if (diffColumns.Count > 0) + { + newUpdateable.UpdateColumns(diffColumns.ToArray()); + } + } + else + { + (newUpdateable as UpdateableProvider).UpdateObjs = new T[] { null }; + newUpdateable.UpdateBuilder.DbColumnInfoList = new List(); + } + } + } + private void AppendSets() + { + if (SetColumnsIndex > 0) + { + var keys = UpdateBuilder.SetValues.Select(it => SqlBuilder.GetNoTranslationColumnName(it.Key.ToLower())).ToList(); + var addKeys = keys.Where(k => !this.UpdateBuilder.DbColumnInfoList.Any(it => it.PropertyName.Equals(k, StringComparison.CurrentCultureIgnoreCase) || it.DbColumnName.Equals(k, StringComparison.CurrentCultureIgnoreCase))).ToList(); + var addItems = this.EntityInfo.Columns.Where(it => !GetPrimaryKeys().Any(p => p.Equals(it.PropertyName?.ToLower(), StringComparison.CurrentCultureIgnoreCase) || p.Equals(it.DbColumnName?.ToLower(), StringComparison.CurrentCultureIgnoreCase)) && addKeys.Any(k => it.PropertyName?.ToLower() == k || it.DbColumnName?.ToLower() == k)).ToList(); + this.UpdateBuilder.DbColumnInfoList.AddRange(addItems.Select(it => new DbColumnInfo() { PropertyName = it.PropertyName, DbColumnName = it.DbColumnName })); + } + SetColumnsIndex++; + } + private string _ExecuteCommand() + { + CheckWhere(); + PreToSql(); + AutoRemoveDataCache(); + Check.ExceptionEasy(this.UpdateParameterIsNull && this.UpdateBuilder.DbColumnInfoList.Count == this.UpdateObjs.Length && this.UpdateObjs.Length == this.UpdateBuilder.DbColumnInfoList.Count(it => it.IsPrimarykey), "The primary key cannot be updated", "主键不能更新,更新主键会对代码逻辑存在未知隐患,如果非要更新:建议你删除在插入或者新建一个没主键的类。"); + Check.Exception(UpdateBuilder.WhereValues.IsNullOrEmpty() && GetPrimaryKeys().IsNullOrEmpty(), "You cannot have no primary key and no conditions"); + string sql = UpdateBuilder.ToSqlString(); + ValidateVersion(); + RestoreMapping(); + Before(sql); + return sql; + } + + private void CheckWhere() + { + if (UpdateParameterIsNull && UpdateBuilder.WhereValues.IsNullOrEmpty()) + { + Check.ExceptionEasy("Update requires conditions", "更新需要条件 Where"); + } + } + + private void _WhereColumn(string columnName) + { + var columnInfos = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.OrdinalIgnoreCase) || it.PropertyName.Equals(columnName, StringComparison.OrdinalIgnoreCase)).ToList(); + if (!this.UpdateBuilder.DbColumnInfoList.Any(y => y.DbColumnName == columnInfos.First().DbColumnName)) + { + this.UpdateBuilder.DbColumnInfoList.AddRange(columnInfos); + } + } + + private void AutoRemoveDataCache() + { + var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (moreSetts?.IsAutoRemoveDataCache == true && extService?.DataInfoCacheService != null) + { + this.RemoveDataCache(); + } + } + internal void Init() + { + this.UpdateBuilder.TableName = EntityInfo.EntityName; + if (IsMappingTable) + { + var mappingInfo = this.Context.MappingTables.SingleOrDefault(it => it.EntityName == EntityInfo.EntityName); + if (mappingInfo != null) + { + this.UpdateBuilder.TableName = mappingInfo.DbTableName; + } + } + //Check.Exception(UpdateObjs == null || UpdateObjs.Any(), "UpdateObjs is null"); + int i = 0; + if (this.EntityInfo.Columns.Any(it => it.IsPrimarykey)) + { + this.UpdateBuilder.OldPrimaryKeys = this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + foreach (var item in UpdateObjs) + { + List updateItem = new List(); + var isDic = item is Dictionary; + if (item is Dictionary) + { + Check.ExceptionEasy("To use Updateable dictionary, use string or object", "Updateable字典请使用string,object类型"); + } + if (isDic) + { + SetUpdateItemByDic(i, item, updateItem); + } + else + { + DataAop(item); + SetUpdateItemByEntity(i, item, updateItem); + Tracking(item); + } + ++i; + } + this.columns = this.UpdateBuilder.DbColumnInfoList; + + var ignoreColumns = EntityInfo.Columns.Where(it => it.IsOnlyIgnoreUpdate).ToList(); + if (ignoreColumns != null && ignoreColumns.Count != 0) + { + this.IgnoreColumns(ignoreColumns.Select(it => it.PropertyName).ToArray()); + } + } + + private void Tracking(T item) + { + if (IsTrakingData()) + { + var trackingData = this.Context.TempItems.FirstOrDefault(it => it.Key.StartsWith("Tracking_" + item.GetHashCode())); + if (trackingData.Key == null && trackingData.Value == null) + { + return; + } + var diffColumns = FastCopy.GetDiff(item, (T)trackingData.Value); + if (diffColumns.Count > 0) + { + var pks = EntityInfo.Columns + .Where(it => it.IsPrimarykey).Select(it => it.PropertyName).ToList(); + diffColumns = diffColumns.Where(it => !pks.Contains(it)).ToList(); + if (diffColumns.Count > 0) + { + this.UpdateColumns(diffColumns.ToArray()); + } + } + else + { + this.UpdateObjs = new T[] { null }; + this.UpdateBuilder.DbColumnInfoList = new List(); + } + } + } + + private bool IsTrakingData() + { + return this.UpdateParameterIsNull == false + && this.Context.TempItems?.Any(it => it.Key.StartsWith("Tracking_")) == true + && this.UpdateObjs.Length == 1; + } + + private bool IsTrakingDatas() + { + return this.UpdateParameterIsNull == false + && this.Context.TempItems?.Any(it => it.Key.StartsWith("Tracking_")) == true + && this.UpdateObjs.Length > 1; + } + private void DataAop(T item) + { + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (dataEvent != null && item != null) + { + foreach (var columnInfo in this.EntityInfo.Columns) + { + if (columnInfo.ForOwnsOnePropertyInfo != null) + { + var data = columnInfo.ForOwnsOnePropertyInfo.GetValue(item, null); + if (data != null) + { + dataEvent(columnInfo.PropertyInfo.GetValue(data, null), new DataFilterModel() { OperationType = DataFilterType.UpdateByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + else if (columnInfo.PropertyInfo.Name == "Item" && columnInfo.IsIgnore) + { + //class index + } + else + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.UpdateByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + } + + private void DataChangesAop(T[] items) + { + if (typeof(T).FullName.StartsWith("System.Collections.Generic.Dictionary`")) + { + return; + } + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataChangesExecuted; + if (dataEvent != null) + { + foreach (var item in items) + { + if (item != null) + { + foreach (var columnInfo in this.EntityInfo.Columns) + { + if (columnInfo.ForOwnsOnePropertyInfo != null) + { + var data = columnInfo.ForOwnsOnePropertyInfo.GetValue(item, null); + if (data != null) + { + dataEvent(columnInfo.PropertyInfo.GetValue(data, null), new DataFilterModel() { OperationType = DataFilterType.UpdateByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + else if (columnInfo.PropertyInfo.Name == "Item" && columnInfo.IsIgnore) + { + //class index + } + else + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.UpdateByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + } + } + } + + private void CheckTranscodeing(bool checkIsJson = true) + { + if (this.EntityInfo.Columns.Any(it => it.IsTranscoding)) + { + Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsTranscoding", "SetColumns方式更新不支持IsTranscoding,你可以使用db.Updateable(实体)的方式更新")); + } + //if (checkIsJson && this.EntityInfo.Columns.Any(it => it.IsJson)) + //{ + // Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsJson", "SetColumns方式更新不支持IsJson,你可以使用db.Updateable(实体)的方式更新")); + //} + //if (this.EntityInfo.Columns.Any(it => it.IsArray)) + //{ + // Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsArray", "SetColumns方式更新不支持IsArray,你可以使用db.Updateable(实体)的方式更新")); + //} + } + private void SetUpdateItemByDic(int i, T item, List updateItem) + { + foreach (var column in (item as Dictionary).OrderBy(it => it.Key)) + { + var columnInfo = new DbColumnInfo() + { + Value = column.Value, + DbColumnName = column.Key, + PropertyName = column.Key, + PropertyType = column.Value == null ? DBNull.Value.GetType() : UtilMethods.GetUnderType(column.Value.GetType()), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.PropertyType = UtilConstants.StringType; + columnInfo.Value = columnInfo.Value.ToString(); + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + updateItem.Add(columnInfo); + } + this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); + } + private void SetUpdateItemByEntity(int i, T item, List updateItem) + { + foreach (var column in EntityInfo.Columns) + { + if (column.IsIgnore) continue; + Check.ExceptionEasy(item == null, "db.Updateable(data) data is required ", "db.Updateable(data) data不能是null"); + var columnInfo = new DbColumnInfo() + { + Value = GetValue(item, column), + DbColumnName = GetDbColumnName(column.PropertyName), + PropertyName = column.PropertyName, + PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), + SqlParameterDbType = column.SqlParameterDbType, + TableId = i, + UpdateSql = column.UpdateSql, + UpdateServerTime = column.UpdateServerTime, + IsPrimarykey = column.IsPrimarykey + }; + if (column.ForOwnsOnePropertyInfo != null) + { + columnInfo.DbColumnName = column.DbColumnName; + } + if (columnInfo.PropertyType.IsEnum() && columnInfo.Value != null) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.PropertyType = UtilConstants.StringType; + columnInfo.Value = columnInfo.Value.ToString(); + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + if (column.IsJson) + { + columnInfo.IsJson = true; + if (columnInfo.Value != null) + columnInfo.Value = this.Context.Utilities.SerializeObject(columnInfo.Value); + } + if (column.IsArray) + { + columnInfo.IsArray = true; + } + var tranColumn = EntityInfo.Columns.FirstOrDefault(it => it.IsTranscoding && it.DbColumnName.Equals(column.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (tranColumn != null && columnInfo.Value.HasValue()) + { + columnInfo.Value = UtilMethods.EncodeBase64(columnInfo.Value.ToString()); + } + updateItem.Add(columnInfo); + } + this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); + } + + private static object GetValue(T item, EntityColumnInfo column) + { + if (column.ForOwnsOnePropertyInfo != null) + { + var owsPropertyValue = column.ForOwnsOnePropertyInfo.GetValue(item, null); + return column.PropertyInfo.GetValue(owsPropertyValue, null); + } + else + { + return column.PropertyInfo.GetValue(item, null); + } + } + private string GetSetSql(string value, Expression> columns) + { + if (value.Contains("= \"SYSDATE\"")) + { + value = value.Replace("= \"SYSDATE\"", "= SYSDATE"); + } + var shortName = (columns as LambdaExpression).Parameters.First().Name; + var replaceKey = "," + this.SqlBuilder.GetTranslationColumnName(shortName) + "."; + var newKey = "," + this.SqlBuilder.GetTranslationColumnName(this.EntityInfo.DbTableName) + "."; + if (replaceKey != newKey) + { + value = value.Replace(replaceKey, ","); + } + return value; + } + + private void PreToSql() + { + if (this.UpdateBuilder.UpdateColumns.HasValue()) + { + var columns = this.UpdateBuilder.UpdateColumns; + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => GetPrimaryKeys().Select( + iit => iit.ToLower()).Contains(it.DbColumnName.ToLower()) + || columns.Contains(it.PropertyName, StringComparer.OrdinalIgnoreCase) + || columns.Contains(it.DbColumnName, StringComparer.OrdinalIgnoreCase)).ToList(); + } + UpdateBuilder.EntityInfo = this.EntityInfo; + UpdateBuilder.PrimaryKeys = GetPrimaryKeys(); + if (this.IsWhereColumns) + { + foreach (var pkName in UpdateBuilder.PrimaryKeys) + { + if (WhereColumnList?.Count > 0) + { + continue; + } + var isContains = this.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName.ToLower()).Contains(pkName.ToLower()); + Check.Exception(isContains == false, "Use UpdateColumns().WhereColumn() ,UpdateColumns need {0}", pkName); + } + } + #region IgnoreColumns + if (this.Context.IgnoreColumns?.Any() == true) + { + var currentIgnoreColumns = this.Context.IgnoreColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => + { + return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); + }).ToList(); + } + #endregion + if (this.IsSingle) + { + var isDic = this.EntityInfo.DbTableName.StartsWith("Dictionary`"); + foreach (var item in this.UpdateBuilder.DbColumnInfoList) + { + if (this.UpdateBuilder.Parameters == null) this.UpdateBuilder.Parameters = new List(); + if (this.UpdateBuilder.SetValues.Any(it => this.SqlBuilder.GetNoTranslationColumnName(it.Key) == item.PropertyName)) + { + continue; + } + if (item.SqlParameterDbType is Type) + { + continue; + } + var parameter = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, item.PropertyType); + if (item.IsJson) + { + parameter.IsJson = true; + SqlBuilder.ChangeJsonType(parameter); + } + if (item.IsArray) + { + parameter.IsArray = true; + if (parameter.Value == null || parameter.Value == DBNull.Value) + { + ArrayNull(item, parameter); + } + } + if (item.Value == null && isDic) + { + var type = this.SqlBuilder.GetNullType(this.UpdateBuilder.GetTableNameString, item.DbColumnName); + if (type != null) + { + parameter = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, type); + } + } + this.UpdateBuilder.Parameters.Add(parameter); + } + } + + #region Identities + List identities = GetIdentityKeys(); + if (identities != null && identities.Count != 0) + { + this.UpdateBuilder.DbColumnInfoList.ForEach(it => + { + var mappingInfo = identities.SingleOrDefault(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null && mappingInfo.Length != 0) + { + it.IsIdentity = true; + } + }); + } + #endregion + List primaryKey = GetPrimaryKeys(); + if (primaryKey?.Count > 0) + { + this.UpdateBuilder.DbColumnInfoList.ForEach(it => + { + var mappingInfo = primaryKey.SingleOrDefault(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null && mappingInfo.Length != 0) + { + it.IsPrimarykey = true; + } + }); + } + if (this.UpdateBuilder.Parameters.HasValue() && this.UpdateBuilder.SetValues.IsValuable()) + { + this.UpdateBuilder.Parameters.RemoveAll(it => this.UpdateBuilder.SetValues.Any(v => (SqlBuilder.SqlParameterKeyWord + SqlBuilder.GetNoTranslationColumnName(v.Key)) == it.ParameterName)); + } + } + + private static void ArrayNull(DbColumnInfo item, SugarParameter parameter) + { + if (item.PropertyType.IsIn(typeof(Guid[]), typeof(Guid?[]))) + { + parameter.DbType = System.Data.DbType.Guid; + } + else if (item.PropertyType.IsIn(typeof(int[]), typeof(int?[]))) + { + parameter.DbType = System.Data.DbType.Int32; + } + else if (item.PropertyType.IsIn(typeof(long[]), typeof(long?[]))) + { + parameter.DbType = System.Data.DbType.Int64; + } + else if (item.PropertyType.IsIn(typeof(short[]), typeof(short?[]))) + { + parameter.DbType = System.Data.DbType.Int16; + } + } + private void OptRollBack(int updateRows, T updateData, object oldValue, string name) + { + if (updateRows == 0) + { + var verInfo = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == name); + if (verInfo != null) + { + verInfo.PropertyInfo.SetValue(updateData, oldValue); + } + } + } + private string GetDbColumnName(string propertyName) + { + if (!IsMappingColumns) + { + return propertyName; + } + if (this.Context.MappingColumns.Any(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase))) + { + this.MappingColumnList = this.Context.MappingColumns.Where(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + } + if (MappingColumnList == null || MappingColumnList.Count == 0) + { + return propertyName; + } + else + { + var mappInfo = this.MappingColumnList.FirstOrDefault(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return mappInfo == null ? propertyName : mappInfo.DbColumnName; + } + } + protected List GetPrimaryKeys() + { + if (this.WhereColumnList.HasValue()) + { + return this.WhereColumnList; + } + else + { + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + } + protected virtual List GetIdentityKeys() + { + + return this.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); + } + private void RestoreMapping() + { + if (IsAs) + { + this.Context.MappingTables = OldMappingTableList; + } + } + + + private void ValidateVersion() + { + var versionColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsEnableUpdateVersionValidation); + var pks = this.UpdateBuilder.DbColumnInfoList.Where(it => it.IsPrimarykey).ToList(); + if (versionColumn != null && this.IsVersionValidation) + { + Check.Exception(pks.IsNullOrEmpty(), "UpdateVersionValidation the primary key is required."); + List conModels = new List(); + foreach (var item in pks) + { + conModels.Add(new ConditionalModel() { CSharpTypeName = item.PropertyType.Name, FieldName = item.DbColumnName, ConditionalType = ConditionalType.Equal, FieldValue = item.Value.ObjToString() }); + } + var dbInfo = this.Context.Queryable().Where(conModels).First(); + if (dbInfo != null) + { + var currentVersion = this.EntityInfo.Type.GetProperty(versionColumn.PropertyName).GetValue(UpdateObjs.Last(), null); + var dbVersion = this.EntityInfo.Type.GetProperty(versionColumn.PropertyName).GetValue(dbInfo, null); + Check.Exception(currentVersion == null, "UpdateVersionValidation entity property {0} is not null", versionColumn.PropertyName); + Check.Exception(dbVersion == null, "UpdateVersionValidation database column {0} is not null", versionColumn.DbColumnName); + if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.IntType, UtilConstants.LongType)) + { + if (Convert.ToInt64(dbVersion) != Convert.ToInt64(currentVersion)) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); + } + } + else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.DateType)) + { + if (dbVersion.ObjToDate() != currentVersion.ObjToDate()) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); + } + } + else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.ByteArrayType)) + { + if (UtilMethods.GetLong((byte[])dbVersion) != UtilMethods.GetLong((byte[])currentVersion)) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); + } + } + else + { + Check.ThrowNotSupportedException(string.Format("UpdateVersionValidation Not Supported Type [ {0} ] , {1}", versionColumn.PropertyInfo.PropertyType, versionColumn.PropertyName)); + } + } + } + } + private void After(string sql) + { + if (this.IsEnableDiffLogEvent && !string.IsNullOrEmpty(sql)) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = UpdateBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.AfterData = GetDiffTable(sql, parameters); + diffModel.Time = this.Context.Ado.SqlExecutionTime; + if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) + this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + if (this.RemoveCacheFunc != null) + { + this.RemoveCacheFunc(); + } + + DataChangesAop(this.UpdateObjs); + } + private string _ExecuteCommandWithOptLock(T updateData, ref object oldVerValue) + { + Check.ExceptionEasy(UpdateParameterIsNull == true, "Optimistic lock can only be an entity update method", "乐观锁只能是实体更新方式"); + var verColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsEnableUpdateVersionValidation); + Check.ExceptionEasy(verColumn == null, $" {this.EntityInfo.EntityName} need IsEnableUpdateVersionValidation=true ", $"实体{this.EntityInfo.EntityName}没有找到版本标识特性 IsEnableUpdateVersionValidation"); + Check.ExceptionEasy(UpdateObjs.Length > 1, $"Optimistic lock can only handle a single update ", $"乐观锁只能处理单条更新"); + Check.ExceptionEasy(!verColumn.UnderType.IsIn(UtilConstants.StringType, UtilConstants.LongType, UtilConstants.GuidType, UtilConstants.DateType), $"Optimistic locks can only be guid, long, and string types", $"乐观锁只能是Guid、Long和字符串类型"); + var oldValue = verColumn.PropertyInfo.GetValue(updateData); + oldVerValue = oldValue; + var newValue = UtilMethods.GetRandomByType(verColumn.UnderType); + verColumn.PropertyInfo.SetValue(updateData, newValue); + var data = this.UpdateBuilder.DbColumnInfoList.FirstOrDefault(it => + it.PropertyName.EqualCase(verColumn.PropertyName)); + if (data == null) + { + data = new DbColumnInfo() { DbColumnName = verColumn.DbColumnName, PropertyName = verColumn.PropertyName, Value = newValue }; + this.UpdateBuilder.DbColumnInfoList.Add(data); + } + data.Value = newValue; + var pks = GetPrimaryKeys(); + Check.ExceptionEasy(pks.Count == 0, "need primary key or WhereColumn", "需要主键或者WhereColumn"); + this.Where(verColumn.DbColumnName, "=", oldValue); + foreach (var p in pks) + { + var pkColumn = this.EntityInfo.Columns.FirstOrDefault( + it => it.DbColumnName.EqualCase(p) || it.PropertyName.EqualCase(p)); + this.Where(pkColumn.DbColumnName, "=", pkColumn.PropertyInfo.GetValue(updateData)); + } + return verColumn.PropertyName; + } + private void Before(string sql) + { + if (this.IsEnableDiffLogEvent && !string.IsNullOrEmpty(sql)) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = UpdateBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.BeforeData = GetDiffTable(sql, parameters); + diffModel.Sql = sql; + diffModel.Parameters = parameters.ToArray(); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + } + private bool IsPrimaryKey(DbColumnInfo it) + { + var result = GetPrimaryKeys().Any(p => p.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || p.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)); + return result; + } + + internal List GetTableDiff(DataTable dt) + { + List result = new List(); + if (dt.Rows?.Count > 0) + { + foreach (DataRow row in dt.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt.Columns) + { + try + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; + addItem.ColumnDescription = sugarColumn.ColumnDescription; + item.Columns.Add(addItem); + } + catch (Exception ex) + { + Check.ExceptionEasy(col.ColumnName + " No corresponding entity attribute found in difference log ." + ex.Message, col.ColumnName + "在差异日志中可能没有找到相应的实体属性,详细:" + ex.Message); + } + } + result.Add(item); + } + } + return result; + } + private List GetDiffTable(string sql, List parameters) + { + List result = new List(); + DataTable dt = null; + if (this.UpdateParameterIsNull) + { + var whereSql = Regex.Replace(sql, ".* WHERE ", "", RegexOptions.Singleline); + if (IsExists(sql)) + { + if (this.UpdateBuilder.SetValues != null) + { + foreach (var item in this.UpdateBuilder.SetValues) + { + if (item.Value?.Contains("SELECT") == true) + { + sql = sql.Replace(item.Value, null); + } + } + } + whereSql = UtilMethods.RemoveBeforeFirstWhere(sql); + } + dt = this.Context.Queryable().AS(this.UpdateBuilder.TableName).Filter(null, true).Where(whereSql).AddParameters(parameters).ToDataTable(); + } + else + { + if (this.UpdateObjs.ToList().Count == 0) + { + dt = new DataTable(); + } + else if (this.WhereColumnList?.Count > 0) + { + dt = this.Context.Queryable().Filter(null, true).WhereClassByWhereColumns(this.UpdateObjs.ToList(), this.WhereColumnList.ToArray()).ToDataTable(); + } + else if (this.UpdateBuilder.TableName.HasValue()) + { + dt = this.Context.Queryable().AS(this.UpdateBuilder.TableName).Filter(null, true).WhereClassByPrimaryKey(this.UpdateObjs.ToList()).ToDataTable(); + } + else + { + dt = this.Context.Queryable().Filter(null, true).WhereClassByPrimaryKey(this.UpdateObjs.ToList()).ToDataTable(); + } + } + if (dt.Rows?.Count > 0) + { + foreach (DataRow row in dt.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt.Columns) + { + try + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; + addItem.ColumnDescription = sugarColumn.ColumnDescription; + item.Columns.Add(addItem); + } + catch (Exception ex) + { + Check.ExceptionEasy(col.ColumnName + " No corresponding entity attribute found in difference log ." + ex.Message, col.ColumnName + "在差异日志中可能没有找到相应的实体属性,详细:" + ex.Message); + } + } + result.Add(item); + } + } + return result; + } + + private static bool IsExists(string sql) + { + return UtilMethods.CountSubstringOccurrences(sql, "WHERE") > 1; + } + protected bool IsCorrectErrorSqlParameterName() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true; + } + + protected void ThrowUpdateByExpression() + { + Check.Exception(UpdateParameterIsNull == true, ErrorMessage.GetThrowMessage(" no support UpdateColumns and WhereColumns", "根据表达式更新 db.Updateable() 禁止使用 UpdateColumns和WhereColumns,你可以使用 SetColumns Where 等。更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新, 具体用法请查看文档 ")); + } + protected void ThrowUpdateByObject() + { + Check.Exception(UpdateParameterIsNull == false, ErrorMessage.GetThrowMessage(" no support SetColumns and Where", "根据对像更新 db.Updateabe(对象) 禁止使用 SetColumns和Where ,你可以使用WhereColumns 和 UpdateColumns。 更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新 , 具体用法请查看文档 ")); + } + protected void ThrowUpdateByExpressionByMesage(string message) + { + Check.Exception(UpdateParameterIsNull == true, ErrorMessage.GetThrowMessage(" no support " + message, "根据表达式更新 db.Updateable()禁止使用 " + message + "。 更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新 , 具体用法请查看文档 ")); + } + private void ThrowUpdateByObjectByMesage(string message) + { + Check.Exception(UpdateParameterIsNull == false, ErrorMessage.GetThrowMessage(" no support " + message, "根据对象更新 db.Updateable(对象)禁止使用 " + message + "。 更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新 , 具体用法请查看文档 ")); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateablePage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateablePage.cs new file mode 100644 index 000000000..5dab32102 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateablePage.cs @@ -0,0 +1,101 @@ +namespace SqlSugar +{ + public class UpdateablePage where T : class, new() + { + public T[] DataList { get; set; } + public SqlSugarProvider Context { get; set; } + public int PageSize { get; internal set; } + public string TableName { get; internal set; } + public bool IsEnableDiffLogEvent { get; internal set; } + public DiffLogModel DiffModel { get; internal set; } + public List UpdateColumns { get; internal set; } + public string[] WhereColumnList { get; internal set; } + public Dictionary ReSetValueBySqlExpList { get; internal set; } + + public UpdateableFilter EnableQueryFilter() + { + return new UpdateableFilter() + { + Context = Context, + DataList = DataList, + DiffModel = DiffModel, + IsEnableDiffLogEvent = IsEnableDiffLogEvent, + PageSize = PageSize, + TableName = TableName, + UpdateColumns = UpdateColumns + }; + } + public int ExecuteCommand() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + this.Context.Ado.BeginTran(); + } + this.Context.Utilities.PageEach(DataList, PageSize, pageItem => + { + var updateable = this.Context.Updateable(pageItem).AS(TableName); + updateable.UpdateBuilder.ReSetValueBySqlExpList = this.ReSetValueBySqlExpList; + result += updateable.WhereColumns(WhereColumnList).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).UpdateColumns(UpdateColumns.ToArray()).ExecuteCommand(); + }); + if (isNoTran) + { + this.Context.Ado.CommitTran(); + } + } + catch (Exception) + { + if (isNoTran) + { + this.Context.Ado.RollbackTran(); + } + throw; + } + return result; + } + public async Task ExecuteCommandAsync() + { + if (DataList.Length == 1 && DataList.First() == null) + { + return 0; + } + if (PageSize == 0) { PageSize = 1000; } + var result = 0; + var isNoTran = this.Context.Ado.IsNoTran(); + try + { + if (isNoTran) + { + await Context.Ado.BeginTranAsync().ConfigureAwait(false); + } + await Context.Utilities.PageEachAsync(DataList, PageSize, async pageItem => + { + var updateable = Context.Updateable(pageItem); + updateable.UpdateBuilder.ReSetValueBySqlExpList = ReSetValueBySqlExpList; + result += await updateable.AS(TableName).WhereColumns(WhereColumnList).EnableDiffLogEventIF(IsEnableDiffLogEvent, DiffModel).UpdateColumns(UpdateColumns.ToArray()).ExecuteCommandAsync().ConfigureAwait(false); + }).ConfigureAwait(false); + if (isNoTran) + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + } + } + catch (Exception) + { + if (isNoTran) + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + } + throw; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProvider.cs new file mode 100644 index 000000000..439418899 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProvider.cs @@ -0,0 +1,1015 @@ +using System.Data; +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class UpdateableProvider : IUpdateable where T : class, new() + { + #region Property + public SqlSugarProvider Context { get; internal set; } + public EntityInfo EntityInfo { get; internal set; } + public ISqlBuilder SqlBuilder { get; internal set; } + public UpdateBuilder UpdateBuilder { get; set; } + public IAdo Ado { get { return Context.Ado; } } + public T[] UpdateObjs { get; set; } + /// + /// true : by expression update + /// false: by object update + /// + public bool UpdateParameterIsNull { get; set; } + public bool IsMappingTable { get { return this.Context.MappingTables?.Any() == true; } } + public bool IsMappingColumns { get { return this.Context.MappingColumns?.Any() == true; } } + public bool IsSingle { get { return this.UpdateObjs.Length == 1; } } + public List MappingColumnList { get; set; } + private List IgnoreColumnNameList { get; set; } + internal List WhereColumnList { get; set; } + private bool IsWhereColumns { get; set; } + private bool IsOffIdentity { get; set; } + private bool IsVersionValidation { get; set; } + public MappingTableList OldMappingTableList { get; set; } + public bool IsAs { get; set; } + public bool IsEnableDiffLogEvent { get; set; } + public DiffLogModel diffModel { get; set; } + internal Action RemoveCacheFunc { get; set; } + private int SetColumnsIndex { get; set; } + private List columns { get; set; } + #endregion + + #region Core + public virtual string ToSqlString() + { + var sqlObj = this.ToSql(); + var result = sqlObj.Key; + if (result == null) return null; + result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig, sqlObj); + return result; + } + + public KeyValuePair> ToSql() + { + PreToSql(); + string sql = UpdateBuilder.ToSqlString(); + RestoreMapping(); + return new KeyValuePair>(sql, UpdateBuilder.Parameters); + } + public void AddQueue() + { + var sqlObj = this.ToSql(); + this.Context.Queues.Add(sqlObj.Key, sqlObj.Value); + } + public virtual int ExecuteCommandWithOptLockIF(bool? IsVersionValidation, bool? IsOptLock = null) + { + if (IsOptLock == true) + { + return ExecuteCommandWithOptLock(IsVersionValidation ?? false); + } + else + { + return this.ExecuteCommand(); + } + } + public virtual int ExecuteCommandWithOptLock(bool IsVersionValidation = false) + { + Check.ExceptionEasy(UpdateObjs?.Length > 1, " OptLock can only be used on a single object, and the argument cannot be List", "乐观锁只能用于单个对象,参数不能是List,如果是一对多操作请更新主表统一用主表验证"); + var updateData = UpdateObjs.FirstOrDefault(); + if (updateData == null) return 0; + object oldValue = null; + var name = _ExecuteCommandWithOptLock(updateData, ref oldValue); + var result = this.ExecuteCommand(); + OptRollBack(result, updateData, oldValue, name); + if (result == 0 && IsVersionValidation) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", name)); + } + return result; + } + + public virtual int ExecuteCommand() + { + //if (this.UpdateBuilder.UpdateColumns.HasValue()) + //{ + // var columns = this.UpdateBuilder.UpdateColumns; + // this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => GetPrimaryKeys().Select(iit => iit.ToLower()).Contains(it.DbColumnName.ToLower()) || columns.Contains(it.PropertyName, StringComparer.OrdinalIgnoreCase)).ToList(); + //} + if (this.IsTrakingDatas() || IsUpdateNullByList()) + { + int trakRows = DatasTrackingExecommand(); + return trakRows; + } + string sql = _ExecuteCommand(); + if (this.UpdateBuilder.AppendWhere.HasValue()) + { + sql += " AND " + this.UpdateBuilder.AppendWhere; + } + if (string.IsNullOrEmpty(sql)) + { + return 0; + } + var result = 0; + if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) + { + UpdateBuilder.Parameters = UpdateBuilder.Parameters.Where(it => UtilMethods.NoErrorParameter(it.ParameterName)).ToList(); + } + List oldParas = null; + if (IsEnableDiffLogEvent) + { + oldParas = UtilMethods.CopySugarParameters(UpdateBuilder.Parameters); + } + if (sql != Environment.NewLine) + { + result = this.Ado.ExecuteCommand(sql, UpdateBuilder.Parameters == null ? null : UpdateBuilder.Parameters.ToArray()); + } + if (oldParas != null && UpdateBuilder.Parameters != null) + { + if (string.Join(",", oldParas.Select(it => it.ParameterName)) != string.Join(",", UpdateBuilder.Parameters.Select(it => it.ParameterName))) + { + UpdateBuilder.Parameters = oldParas; + } + } + After(sql); + return result; + } + public bool ExecuteCommandHasChange() + { + return this.ExecuteCommand() > 0; + } + + public virtual async Task ExecuteCommandWithOptLockAsync(bool IsVersionValidation = false) + { + Check.ExceptionEasy(UpdateObjs?.Length > 1, " OptLock can only be used on a single object, and the argument cannot be List", "乐观锁只能用于单个对象,参数不能是List,如果是一对多操作请更新主表统一用主表验证"); + var updateData = UpdateObjs.FirstOrDefault(); + if (updateData == null) return 0; + object oldValue = null; + var name = _ExecuteCommandWithOptLock(updateData, ref oldValue); + var result = await ExecuteCommandAsync().ConfigureAwait(false); + OptRollBack(result, updateData, oldValue, name); + if (result == 0 && IsVersionValidation) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", name)); + } + return result; + } + public Task ExecuteCommandAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ExecuteCommandAsync(); + } + public virtual async Task ExecuteCommandAsync() + { + //if (this.UpdateBuilder.UpdateColumns.HasValue()) + //{ + // var columns = this.UpdateBuilder.UpdateColumns; + // this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => GetPrimaryKeys().Select(iit => iit.ToLower()).Contains(it.DbColumnName.ToLower()) || columns.Contains(it.PropertyName, StringComparer.OrdinalIgnoreCase)).ToList(); + //} + if (this.IsTrakingDatas() || IsUpdateNullByList()) + { + int trakRows = await DatasTrackingExecommandAsync().ConfigureAwait(false); + return trakRows; + } + string sql = _ExecuteCommand(); + if (this.UpdateBuilder.AppendWhere.HasValue()) + { + sql += " AND " + this.UpdateBuilder.AppendWhere; + } + if (string.IsNullOrEmpty(sql)) + { + return 0; + } + var result = await Ado.ExecuteCommandAsync(sql, UpdateBuilder.Parameters == null ? null : UpdateBuilder.Parameters.ToArray()).ConfigureAwait(false); + After(sql); + return result; + } + public Task ExecuteCommandHasChangeAsync(CancellationToken token) + { + this.Context.Ado.CancellationToken = token; + return ExecuteCommandHasChangeAsync(); + } + + public async Task ExecuteCommandHasChangeAsync() + { + return await ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + #endregion + + #region Common + public UpdateablePage PageSize(int pageSize) + { + ThrowUpdateByExpressionByMesage(" PageSize(num) "); + UpdateablePage result = new UpdateablePage(); + result.PageSize = pageSize; + result.Context = this.Context; + result.DataList = this.UpdateObjs; + result.TableName = this.UpdateBuilder.TableName; + result.IsEnableDiffLogEvent = this.IsEnableDiffLogEvent; + result.WhereColumnList = this.WhereColumnList?.ToArray(); + result.DiffModel = this.diffModel; + result.ReSetValueBySqlExpList = this.UpdateBuilder.ReSetValueBySqlExpList; + if (this.UpdateBuilder.DbColumnInfoList.Count != 0) + result.UpdateColumns = this.UpdateBuilder.DbColumnInfoList.GroupBy(it => it.TableId).First().Select(it => it.DbColumnName).ToList(); + if (this.UpdateBuilder?.UpdateColumns?.Count > 0) + result.UpdateColumns = this.UpdateBuilder.UpdateColumns; + return result; + } + public IUpdateable InnerJoin(Expression> joinExpress) + { + UpdateableProvider result = new UpdateableProvider(); + result.updateableObj = this; + var querybale = this.Context.Queryable().LeftJoin(joinExpress); + result.updateableObj.UpdateBuilder.JoinInfos = querybale.QueryBuilder.JoinQueryInfos; + result.updateableObj.UpdateBuilder.ShortName = joinExpress.Parameters.FirstOrDefault()?.Name; + return result; + } + public IUpdateable InnerJoin(ISugarQueryable queryable, Expression> joinExpress) + { + var tableName = $" ({queryable.Clone().ToSqlString()}) "; ; + return this.InnerJoin(joinExpress, tableName); + } + public IUpdateable InnerJoin(Expression> joinExpress, string TableName) + { + UpdateableProvider result = new UpdateableProvider(); + result.updateableObj = this; + var querybale = this.Context.Queryable().LeftJoin(joinExpress); + result.updateableObj.UpdateBuilder.JoinInfos = querybale.QueryBuilder.JoinQueryInfos; + result.updateableObj.UpdateBuilder.ShortName = joinExpress.Parameters.FirstOrDefault()?.Name; + result.updateableObj.UpdateBuilder.TableName = TableName; + return result; + } + public IUpdateable Clone() + { + this.Context.SugarActionType = SugarActionType.Update; + var result = InstanceFactory.GetUpdateableProvider(this.Context.CurrentConnectionConfig); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); ; + result.Context = this.Context; + result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + result.SqlBuilder = sqlBuilder; + result.SqlBuilder.Context = this.Context; + result.UpdateObjs = UpdateObjs; + result.WhereColumnList = this.WhereColumnList; + result.IsWhereColumns = this.IsWhereColumns; + result.IgnoreColumnNameList = this.IgnoreColumnNameList; + result.IsAs = this.IsAs; + result.IsOffIdentity = this.IsOffIdentity; + result.IsEnableDiffLogEvent = this.IsEnableDiffLogEvent; + result.diffModel = this.diffModel; + result.UpdateParameterIsNull = this.UpdateParameterIsNull; + result.RemoveCacheFunc = this.RemoveCacheFunc; + result.SetColumnsIndex = this.SetColumnsIndex; + result.OldMappingTableList = this.OldMappingTableList; + result.MappingColumnList = this.MappingColumnList; + result.columns = this.columns.ToList(); + result.UpdateBuilder = InstanceFactory.GetUpdateBuilder(this.Context.CurrentConnectionConfig); + result.UpdateBuilder.Builder = sqlBuilder; + result.UpdateBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig); + result.Context = this.Context; + result.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.ToList(); + result.UpdateBuilder.TableName = this.UpdateBuilder.TableName; + result.UpdateBuilder.WhereValues = this.UpdateBuilder?.WhereValues?.ToList(); + result.UpdateBuilder.Parameters = this.UpdateBuilder?.Parameters?.ToList(); + result.UpdateBuilder.IsListUpdate = this.UpdateBuilder.IsListUpdate; + result.UpdateBuilder.IsWhereColumns = this.UpdateBuilder.IsWhereColumns; + result.UpdateBuilder.WhereValues = this.UpdateBuilder?.WhereValues?.ToList(); + result.UpdateBuilder.IsNoUpdateDefaultValue = this.UpdateBuilder.IsNoUpdateDefaultValue; + result.UpdateBuilder.IsNoUpdateNull = this.UpdateBuilder.IsNoUpdateNull; + result.UpdateBuilder.SetValues = this.UpdateBuilder?.SetValues?.ToList(); + result.UpdateBuilder.UpdateColumns = this.UpdateBuilder?.UpdateColumns?.ToList(); + result.UpdateBuilder.Context = this.Context; + return result; + } + public IUpdateable With(string lockString) + { + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + this.UpdateBuilder.TableWithString = lockString; + return this; + } + public SplitTableUpdateProvider SplitTable(Func, IEnumerable> getTableNamesFunc) + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + this.Context.MappingTables.Add(this.EntityInfo.EntityName, this.EntityInfo.DbTableName); + SplitTableUpdateProvider result = new SplitTableUpdateProvider(); + result.Context = this.Context; + SplitTableContext helper = new SplitTableContext(Context) + { + EntityInfo = this.EntityInfo + }; + var tables = getTableNamesFunc(helper.GetTables()); + result.Tables = tables; + result.updateobj = this; + return result; + } + public SplitTableUpdateByObjectProvider SplitTable() + { + UtilMethods.StartCustomSplitTable(this.Context, typeof(T)); + Check.ExceptionEasy(UpdateParameterIsNull, "SplitTable() not supported db.Updateable(),use db.Updateable(list)", ".SplitTable()不支持 db.Updateable()方式更新,请使用 db.Updateable(list) 对象方式更新, 或者使用 .SplitTable(+1)重载"); + SplitTableUpdateByObjectProvider result = new SplitTableUpdateByObjectProvider(); + result.Context = this.Context; + result.UpdateObjects = this.UpdateObjs; + result.IsEnableDiffLogEvent = this.IsEnableDiffLogEvent; + result.BusinessData = this.diffModel?.BusinessData; + if (this.IsWhereColumns) + result.WhereColumns = this.WhereColumnList; + SplitTableContext helper = new SplitTableContext(Context) + { + EntityInfo = this.EntityInfo + }; + result.updateobj = this; + return result; + } + public IUpdateable RemoveDataCache() + { + this.RemoveCacheFunc = () => + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + CacheSchemeMain.RemoveCache(cacheService, this.Context.EntityMaintenance.GetTableName()); + }; + return this; + } + public IUpdateable RemoveDataCache(string likeString) + { + this.RemoveCacheFunc = () => + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + CacheSchemeMain.RemoveCacheByLike(cacheService, likeString); + }; + return this; + } + public IUpdateable IsEnableUpdateVersionValidation() + { + this.IsVersionValidation = true; + return this; + } + public IUpdateable AsType(Type tableNameType) + { + return AS(this.Context.EntityMaintenance.GetEntityInfo(tableNameType).DbTableName); + } + public IUpdateable AS(string tableName) + { + //if (tableName == null) return this; + //var entityName = typeof(T).Name; + //IsAs = true; + //OldMappingTableList = this.Context.MappingTables; + //this.Context.MappingTables = this.Context.Utilities.TranslateCopy(this.Context.MappingTables); + //if (this.Context.MappingTables.Any(it => it.EntityName == entityName)) + //{ + // this.Context.MappingTables.Add(this.Context.MappingTables.First(it => it.EntityName == entityName).DbTableName, tableName); + //} + //this.Context.MappingTables.Add(entityName, tableName); + this.UpdateBuilder.TableName = tableName; + if (tableName.IsNullOrEmpty()) + this.UpdateBuilder.TableName = this.EntityInfo.DbTableName; + return this; ; + } + public IUpdateable EnableDiffLogEventIF(bool isEnableDiffLog, object businessData = null) + { + if (isEnableDiffLog) + { + return EnableDiffLogEvent(businessData); + } + return this; + } + public IUpdateable EnableDiffLogEvent(object businessData = null) + { + //Check.Exception(this.UpdateObjs.HasValue() && this.UpdateObjs.Count() > 1, "DiffLog does not support batch operations"); + diffModel = new DiffLogModel(); + this.IsEnableDiffLogEvent = true; + diffModel.BusinessData = businessData; + diffModel.DiffType = DiffType.update; + return this; + } + + + + public IUpdateable IgnoreColumns(bool ignoreAllNullColumns, bool isOffIdentity = false, bool ignoreAllDefaultValue = false) + { + //Check.Exception(this.UpdateObjs.Count() > 1 && ignoreAllNullColumns, ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert", "ignoreNullColumn 不支持批量操作")); + UpdateBuilder.IsOffIdentity = isOffIdentity; + if (this.UpdateBuilder.LambdaExpressions == null) + this.UpdateBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig); + this.UpdateBuilder.IsNoUpdateNull = ignoreAllNullColumns; + this.UpdateBuilder.IsNoUpdateDefaultValue = ignoreAllDefaultValue; + return this; + } + public IUpdateable IgnoreColumns(Expression> columns) + { + var ignoreColumns = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it).ToLower()).ToList(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Contains(it.PropertyName.ToLower())).ToList(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Contains(it.DbColumnName.ToLower())).ToList(); + this.UpdateBuilder.IgnoreColumns = ignoreColumns; + return this; + } + public IUpdateable IgnoreColumnsIF(bool IsIgnore, Expression> columns) + { + if (IsIgnore) this.IgnoreColumns(columns); + return this; + } + public IUpdateable IgnoreNullColumns(bool isIgnoreNull = true) + { + if (isIgnoreNull) + { + return IgnoreColumns(isIgnoreNull); + } + else + { + return this; + } + } + public IUpdateable IgnoreColumns(string[] columns) + { + if (columns.HasValue()) + { + var ignoreColumns = columns.Select(it => it.ToLower()).ToList(); + this.UpdateBuilder.IgnoreColumns = ignoreColumns; + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Contains(it.PropertyName.ToLower())).ToList(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Contains(it.DbColumnName.ToLower())).ToList(); + } + return this; + } + + + public IUpdateable ReSetValue(Action setValueExpression) + { + ThrowUpdateByExpression(); + if (this.UpdateObjs.HasValue()) + { + var oldColumns = this.UpdateBuilder.DbColumnInfoList.Select(it => it.PropertyName).ToList(); + foreach (var item in UpdateObjs) + { + setValueExpression(item); + } + this.UpdateBuilder.DbColumnInfoList = new List(); + Init(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => oldColumns.Contains(it.PropertyName)).ToList(); + } + return this; + } + public IUpdateable PublicSetColumns(Expression> filedNameExpression, string computationalSymbol) + { + if (UpdateParameterIsNull == true) + { + Check.Exception(UpdateParameterIsNull == true, ErrorMessage.GetThrowMessage("The PublicSetColumns(exp,string) overload can only be used to update entity objects: db.Updateable(object)", "PublicSetColumns(exp,string)重载只能用在实体对象更新:db.Updateable(对象),请区分表达式更新和实体对象更不同用法 ")); + } + else + { + var name = ExpressionTool.GetMemberName(filedNameExpression); + if (name == null) + { + Check.ExceptionEasy(filedNameExpression + " format error ", filedNameExpression + "参数格式错误"); + } + //var value = this.UpdateBuilder.GetExpressionValue(ValueExpExpression, ResolveExpressType.WhereSingle).GetResultString(); + if (this.UpdateBuilder.ReSetValueBySqlExpList == null) + { + this.UpdateBuilder.ReSetValueBySqlExpList = new Dictionary(); + } + if (!this.UpdateBuilder.ReSetValueBySqlExpList.ContainsKey(name)) + { + this.UpdateBuilder.ReSetValueBySqlExpList.Add(name, new ReSetValueBySqlExpListModel() + { + Type = ReSetValueBySqlExpListModelType.List, + Sql = computationalSymbol, + DbColumnName = this.SqlBuilder.GetTranslationColumnName(this.EntityInfo.Columns.First(it => it.PropertyName == name).DbColumnName) + }); + } + } + return this; + } + + public IUpdateable PublicSetColumns(Expression> filedNameExpression, Expression> ValueExpExpression) + { + if (UpdateParameterIsNull == true) + { + return SetColumns(filedNameExpression, ValueExpExpression); + } + else + { + var name = ExpressionTool.GetMemberName(filedNameExpression); + if (name == null) + { + Check.ExceptionEasy(filedNameExpression + " format error ", filedNameExpression + "参数格式错误"); + } + var value = this.UpdateBuilder.GetExpressionValue(ValueExpExpression, ResolveExpressType.WhereSingle).GetResultString(); + if (this.UpdateBuilder.ReSetValueBySqlExpList == null) + { + this.UpdateBuilder.ReSetValueBySqlExpList = new Dictionary(); + } + if (!this.UpdateBuilder.ReSetValueBySqlExpList.ContainsKey(name)) + { + this.UpdateBuilder.ReSetValueBySqlExpList.Add(name, new ReSetValueBySqlExpListModel() + { + Sql = value, + DbColumnName = this.SqlBuilder.GetTranslationColumnName(this.EntityInfo.Columns.First(it => it.PropertyName == name).DbColumnName) + }); ; + } + } + return this; + } + #endregion + + #region Update by object + public IUpdateable CallEntityMethod(Expression> method) + { + ThrowUpdateByExpression(); + if (this.UpdateObjs.HasValue()) + { + var oldColumns = this.UpdateBuilder.DbColumnInfoList.Select(it => it.PropertyName).ToList(); + var expression = (LambdaExpression.Lambda(method).Body as LambdaExpression).Body; + Check.Exception(!(expression is MethodCallExpression), method.ToString() + " is not method"); + var callExpresion = expression as MethodCallExpression; + UtilMethods.DataInoveByExpresson(this.UpdateObjs, callExpresion); + this.UpdateBuilder.DbColumnInfoList = new List(); + Init(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => oldColumns.Contains(it.PropertyName)).ToList(); + } + return this; + } + + public IUpdateable WhereColumns(Expression> columns) + { + ThrowUpdateByExpression(); + this.IsWhereColumns = true; + UpdateBuilder.IsWhereColumns = true; + Check.Exception(UpdateParameterIsNull == true, "Updateable().Updateable is error,Use Updateable(obj).WhereColumns"); + var whereColumns = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + if (this.WhereColumnList == null) this.WhereColumnList = new List(); + foreach (var item in whereColumns) + { + _WhereColumn(item); + var columnInfo = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(item)); + if (columnInfo != null) + { + this.WhereColumnList.Add(columnInfo.DbColumnName); + } + else + { + this.WhereColumnList.Add(item); + } + } + return this; + } + public IUpdateable WhereColumns(string columnName) + { + + ThrowUpdateByExpression(); + if (this.WhereColumnList == null) this.WhereColumnList = new List(); + _WhereColumn(columnName); + this.WhereColumnList.Add(columnName); + return this; + } + + public IUpdateable WhereColumns(string[] columnNames) + { + if (columnNames == null) return this; + + ThrowUpdateByExpression(); + if (this.WhereColumnList == null) this.WhereColumnList = new List(); + foreach (var columnName in columnNames) + { + _WhereColumn(columnName); + this.WhereColumnList.Add(columnName); + } + return this; + } + public IUpdateable UpdateColumns(Expression> columns, bool appendColumnsByDataFilter) + { + ThrowUpdateByExpression(); + var updateColumns = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + return UpdateColumns(updateColumns.ToArray(), appendColumnsByDataFilter); + } + public IUpdateable UpdateColumns(Expression> columns) + { + ThrowUpdateByExpression(); + var updateColumns = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + if (this.UpdateBuilder.UpdateColumns == null) + { + this.UpdateBuilder.UpdateColumns = new List(); + } + this.UpdateBuilder.UpdateColumns.AddRange(updateColumns); + //List primaryKeys = GetPrimaryKeys(); + //foreach (var item in this.UpdateBuilder.DbColumnInfoList) + //{ + // var mappingInfo = primaryKeys.SingleOrDefault(i => item.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + // if (mappingInfo != null && mappingInfo.Any()) + // { + // item.IsPrimarykey = true; + // } + //} + //this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => updateColumns.Any(uc => uc.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase) || uc.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey || it.IsIdentity).ToList(); + return this; + } + public IUpdateable UpdateColumns(string[] columns, bool appendColumnsByDataFilter) + { + List updateColumns = new List(); + if (appendColumnsByDataFilter) + { + var newData = new T() { }; + UtilMethods.ClearPublicProperties(newData, this.EntityInfo); + var data = ((UpdateableProvider)this.Context.Updateable(newData)).UpdateObjs.First(); + foreach (var item in this.EntityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIgnore && !it.IsOnlyIgnoreUpdate)) + { + var value = item.PropertyInfo.GetValue(data); + if (value?.Equals("") == false) + { + if (!value.Equals(UtilMethods.GetDefaultValue(item.UnderType))) + { + updateColumns.Add(item.PropertyName); + } + } + } + } + updateColumns.AddRange(columns); + return UpdateColumns(updateColumns.ToArray()); + } + public IUpdateable UpdateColumns(string[] columns) + { + if (columns == null || columns.Length == 0) return this; + ThrowUpdateByExpression(); + if (this.UpdateBuilder.UpdateColumns == null) + { + this.UpdateBuilder.UpdateColumns = new List(); + } + this.UpdateBuilder.UpdateColumns.AddRange(columns); + //if (columns.HasValue()) + //{ + + // //this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => GetPrimaryKeys().Select(iit => iit.ToLower()).Contains(it.DbColumnName.ToLower()) || columns.Contains(it.PropertyName, StringComparer.OrdinalIgnoreCase)).ToList(); + //} + return this; + } + public IUpdateable UpdateColumnsIF(bool isUpdateColumns, Expression> columns) + { + ThrowUpdateByExpression(); + if (isUpdateColumns) + UpdateColumns(columns); + return this; + } + public IUpdateable UpdateColumnsIF(bool isUpdateColumns, string[] columns) + { + ThrowUpdateByExpression(); + if (isUpdateColumns) + UpdateColumns(columns); + return this; + } + #endregion + + #region Update by expression + public IUpdateable EnableQueryFilter() + { + try + { + ThrowUpdateByObject(); + } + catch + { + Check.ExceptionEasy("Updateable(obj) no support, use Updateable().SetColumn ", "更新过滤器只能用在表达式方式更新 ,更新分为实体更新和表达式更新 。正确用法 Updateable().SetColum(..).Where(..)"); + } + var queryable = this.Context.Queryable(); + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 1000; + var sqlable = queryable.ToSql(); + var whereInfos = Regex.Split(sqlable.Key, " Where ", RegexOptions.IgnoreCase); + if (whereInfos.Length > 1) + { + this.Where(whereInfos.Last(), sqlable.Value); + } + return this; + } + public virtual IUpdateable SetColumns(string fieldName, object fieldValue) + { + ThrowUpdateByObject(); + var columnInfo = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(fieldName)); + if (columnInfo != null) + { + fieldName = columnInfo.DbColumnName; + } + var parameterName = this.SqlBuilder.SqlParameterKeyWord + "Const" + this.UpdateBuilder.LambdaExpressions.ParameterIndex; + this.UpdateBuilder.LambdaExpressions.ParameterIndex = this.UpdateBuilder.LambdaExpressions.ParameterIndex + 1; + if (UpdateBuilder.Parameters == null) + { + UpdateBuilder.Parameters = new List(); + } + UpdateBuilder.Parameters.Add(new SugarParameter(parameterName, fieldValue)); + if (columnInfo?.UpdateServerTime == true) + { + var nowTime = this.Context.Queryable().QueryBuilder.LambdaExpressions.DbMehtods.GetDate(); + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(fieldName), $"{SqlBuilder.GetTranslationColumnName(fieldName)}={nowTime}")); + } + else + { + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(fieldName), $"{SqlBuilder.GetTranslationColumnName(fieldName)}={parameterName}")); + } + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => (UpdateParameterIsNull == false && IsPrimaryKey(it)) || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + if (!this.UpdateBuilder.DbColumnInfoList.Any(it => it.DbColumnName.EqualCase(fieldName))) + { + this.UpdateBuilder.DbColumnInfoList.Add(new DbColumnInfo() + { + DbColumnName = fieldName, + Value = fieldValue, + PropertyName = fieldName, + PropertyType = fieldValue?.GetType() + }); + } + AppendSets(); + return this; + } + public IUpdateable SetColumnsIF(bool isUpdateColumns, Expression> filedNameExpression, object fieldValue) + { + if (isUpdateColumns) + { + return SetColumns(filedNameExpression, fieldValue); + } + else + { + return this; + } + } + public virtual IUpdateable SetColumns(Expression> filedNameExpression, Expression> valueExpression) + { + if (valueExpression == null) + { + return SetColumns(filedNameExpression, (object)null); + } + var name = UpdateBuilder.GetExpressionValue(filedNameExpression, ResolveExpressType.FieldSingle).GetString(); + name = UpdateBuilder.Builder.GetTranslationColumnName(name); + var exp = ExpressionTool.RemoveConvert((valueExpression as LambdaExpression).Body); + var value = UpdateBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString(); + value = $" {name}={value} "; + this.UpdateBuilder.SetValues.Add(new KeyValuePair(name, value)); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => (UpdateParameterIsNull == false && IsPrimaryKey(it)) || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + AppendSets(); + if (typeof(T) == UtilConstants.ObjType) + { + this.UpdateBuilder.DbColumnInfoList.Add(new DbColumnInfo() + { + DbColumnName = UpdateBuilder.Builder.GetNoTranslationColumnName(name), + Value = value, + PropertyName = name, + SqlParameterDbType = typeof(SqlSugar.DbConvert.NoParameterCommonPropertyConvert) + }); + } + return this; + } + public virtual IUpdateable SetColumns(Expression> filedNameExpression, object fieldValue) + { + var name = UpdateBuilder.GetExpressionValue(filedNameExpression, ResolveExpressType.FieldSingle).GetString(); + name = UpdateBuilder.Builder.GetNoTranslationColumnName(name); + return SetColumns(name, fieldValue); + } + public virtual IUpdateable SetColumns(Expression> columns) + { + ThrowUpdateByObject(); + var expResult = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.Update); + var resultArray = expResult.GetResultArray(); + Check.ArgumentNullException(resultArray, "UpdateColumns Parameter error, UpdateColumns(it=>new T{ it.id=1}) is valid, UpdateColumns(it=>T) is error"); + var keys = ExpressionTool.GetNewExpressionItemList(columns).ToArray(); + if (resultArray.HasValue()) + { + int i = 0; + foreach (var item in resultArray) + { + string key = key = keys[i].Key; + i++; + var value = item; + value = GetSetSql(value, columns); + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(key), value)); + } + } + this.UpdateBuilder.DbColumnInfoList = UpdateBuilder.DbColumnInfoList.Where(it => it.UpdateServerTime == true || it.UpdateSql.HasValue() || (UpdateParameterIsNull == false && IsPrimaryKey(it)) || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + CheckTranscodeing(false); + AppendSets(); + return this; + } + + + public virtual IUpdateable SetColumns(Expression> columns, bool appendColumnsByDataFilter) + { + ThrowUpdateByObject(); + var expResult = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.Update); + var resultArray = expResult.GetResultArray(); + Check.ArgumentNullException(resultArray, "UpdateColumns Parameter error, UpdateColumns(it=>new T{ it.id=1}) is valid, UpdateColumns(it=>T) is error"); + if (resultArray.HasValue()) + { + foreach (var item in resultArray) + { + string key = SqlBuilder.GetNoTranslationColumnName(item); + var value = item; + if (value.Contains("= \"SYSDATE\"")) + { + value = value.Replace("= \"SYSDATE\"", "= SYSDATE"); + } + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(key), value)); + } + } + if (appendColumnsByDataFilter) + { + var newData = new T() { }; + UtilMethods.ClearPublicProperties(newData, this.EntityInfo); + var data = ((UpdateableProvider)this.Context.Updateable(newData)).UpdateObjs.First(); + foreach (var item in this.EntityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIgnore && !it.IsOnlyIgnoreUpdate)) + { + var value = item.PropertyInfo.GetValue(data); + if (value?.Equals("") == false) + { + if (!value.Equals(UtilMethods.GetDefaultValue(item.UnderType))) + { + var pName = this.SqlBuilder.SqlParameterKeyWord + item.PropertyName + 1000; + var p = new SugarParameter(pName, value); + this.UpdateBuilder.Parameters.Add(p); + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(item.DbColumnName), SqlBuilder.GetTranslationColumnName(item.DbColumnName) + "=" + pName)); + } + } + } + } + if (this.EntityInfo.Columns.Any(it => it.UpdateServerTime || it.UpdateSql.HasValue())) + { + var appendColumns = this.EntityInfo.Columns.Where(it => it.UpdateServerTime || it.UpdateSql.HasValue()); + foreach (var item in appendColumns) + { + if (item.UpdateServerTime) + { + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(item.DbColumnName), SqlBuilder.GetTranslationColumnName(item.DbColumnName) + "=" + UpdateBuilder.LambdaExpressions.DbMehtods.GetDate())); + } + else if (item.UpdateSql.HasValue()) + { + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(item.DbColumnName), SqlBuilder.GetTranslationColumnName(item.DbColumnName) + "=" + item.UpdateSql)); + } + } + } + this.UpdateBuilder.DbColumnInfoList = UpdateBuilder.DbColumnInfoList.Where(it => it.UpdateServerTime || it.UpdateSql.HasValue() || (UpdateParameterIsNull == false && IsPrimaryKey(it)) || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + CheckTranscodeing(false); + AppendSets(); + return this; + } + public virtual IUpdateable SetColumns(Expression> columns) + { + ThrowUpdateByObject(); + + var binaryExp = columns.Body as BinaryExpression; + Check.Exception(!binaryExp.NodeType.IsIn(ExpressionType.Equal), "No support {0}", columns.ToString()); + Check.Exception(!(binaryExp.Left is MemberExpression) && !(binaryExp.Left is UnaryExpression), "No support {0}", columns.ToString()); + Check.Exception(ExpressionTool.IsConstExpression(binaryExp.Left as MemberExpression), "No support {0}", columns.ToString()); + if (UpdateBuilder.LambdaExpressions.ParameterIndex <= 1 && + this.EntityInfo.Columns + .Select(it => it.PropertyName.TrimEnd('2')) + .GroupBy(it => it) + .Any(it => it.Count() > 1) + ) + { + UpdateBuilder.LambdaExpressions.ParameterIndex = 100; + } + var expResult = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.WhereSingle).GetResultString().Replace(")", " )").Replace("(", "( ").Trim().TrimStart('(').TrimEnd(')').Replace("= =", "="); + if (IsCorrectErrorSqlParameterName()) + { + expResult = UpdateBuilder.GetExpressionValue(binaryExp.Right, ResolveExpressType.WhereSingle).GetResultString().Trim(); + } + if (expResult.EndsWith(" IS NULL ")) + { + expResult = Regex.Split(expResult, " IS NULL ")[0] + " = NULL "; + } + else if (!expResult.Contains('=') && expResult.Contains("IS NULL ")) + { + expResult = Regex.Split(expResult, "IS NULL ")[0] + " = NULL "; + } + string key = SqlBuilder.GetNoTranslationColumnName(expResult); + if (IsCorrectErrorSqlParameterName() && binaryExp.Left is MemberExpression member) + { + key = this.EntityInfo.Columns.First(it => it.PropertyName == member.Member.Name).DbColumnName; + expResult = $" {this.SqlBuilder.GetTranslationColumnName(key)}={expResult} "; + } + if (EntityInfo.Columns.Where(it => it.IsJson || it.IsTranscoding).Any(it => it.DbColumnName.EqualCase(key) || it.PropertyName.EqualCase(key))) + { + CheckTranscodeing(); + } + + if (columns.ToString().Contains("Subqueryable().")) + { + expResult = expResult.Replace(this.SqlBuilder.GetTranslationColumnName((ExpressionTool.RemoveConvert(binaryExp.Left) as MemberExpression).Expression + "") + ".", this.UpdateBuilder.GetTableNameString.TrimEnd() + "."); + } + + UpdateBuilder.SetValues.Add(new KeyValuePair(SqlBuilder.GetTranslationColumnName(key), expResult)); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => (UpdateParameterIsNull == false && IsPrimaryKey(it)) || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + AppendSets(); + return this; + } + public IUpdateable SetColumnsIF(bool isUpdateColumns, Expression> columns) + { + ThrowUpdateByObject(); + if (isUpdateColumns) + SetColumns(columns); + return this; + } + public IUpdateable SetColumnsIF(bool isUpdateColumns, Expression> columns) + { + ThrowUpdateByObject(); + if (isUpdateColumns) + SetColumns(columns); + return this; + } + public IUpdateable In(Expression> inField, ISugarQueryable childQueryExpression) + { + var lamResult = UpdateBuilder.GetExpressionValue(inField, ResolveExpressType.FieldSingle); + this.UpdateBuilder.LambdaExpressions.ParameterIndex = childQueryExpression.QueryBuilder.LambdaExpressions.ParameterIndex + 1; + var fieldName = lamResult.GetResultString(); + if (this.UpdateBuilder.SetValues.Count == 0) + { + var sql = childQueryExpression.ToSql(); + Where($" {fieldName} IN ( SELECT {fieldName} FROM ( {sql.Key} ) SUBDEL) ", sql.Value); + } + else + { + Where($" {fieldName} IN ( SELECT {fieldName} FROM ( {childQueryExpression.ToSqlString()} ) SUBDEL) "); + } + return this; + } + public IUpdateable WhereIF(bool isWhere, Expression> expression) + { + if (UpdateBuilder.WhereValues.Count != 0 != true) + { + Check.ExceptionEasy(!StaticConfig.EnableAllWhereIF, "Need to program startup configuration StaticConfig. EnableAllWhereIF = true; Tip: This operation is very risky if there are no conditions it is easy to update the entire table", " 需要程序启动时配置StaticConfig.EnableAllWhereIF=true; 提示:该操作存在很大的风险如果没有条件很容易将整个表全部更新"); + } + if (isWhere) + { + return Where(expression); + } + return this; + } + public IUpdateable Where(Expression> expression) + { + Check.Exception(UpdateObjectNotWhere() && UpdateObjs.Length > 1, ErrorMessage.GetThrowMessage("update List no support where", "集合更新不支持Where请使用WhereColumns")); + var expResult = UpdateBuilder.GetExpressionValue(expression, ResolveExpressType.WhereSingle); + var whereString = expResult.GetResultString(); + if (expression.ToString().Contains("Subqueryable()")) + { + var entityTableName = this.EntityInfo.DbTableName; + if (UpdateBuilder.TableName.HasValue()) + { + entityTableName = UpdateBuilder.TableName; + } + if (ExpressionTool.GetParameters(expression).First().Type == typeof(T)) + { + var tableName = this.SqlBuilder.GetTranslationColumnName(entityTableName); + whereString = whereString.Replace(tableName, $"( SELECT * FROM {tableName}) "); + } + whereString = whereString.Replace(this.SqlBuilder.GetTranslationColumnName(expression.Parameters.First().Name) + ".", this.SqlBuilder.GetTranslationTableName(entityTableName) + "."); + } + else if (expResult.IsNavicate) + { + var entityTableName2 = this.EntityInfo.DbTableName; + if (this.UpdateBuilder.TableName.HasValue()) + { + entityTableName2 = this.UpdateBuilder.TableName; + } + whereString = whereString.Replace(expression.Parameters.First().Name + ".", this.SqlBuilder.GetTranslationTableName(entityTableName2) + "."); + whereString = whereString.Replace(this.SqlBuilder.GetTranslationColumnName(expression.Parameters.First().Name) + ".", this.SqlBuilder.GetTranslationTableName(entityTableName2) + "."); + } + UpdateBuilder.WhereValues.Add(whereString); + return this; + } + public IUpdateable Where(string whereSql, object parameters = null) + { + Check.Exception(UpdateObjectNotWhere() && UpdateObjs.Length > 1, ErrorMessage.GetThrowMessage("update List no support where", "集合更新不支持Where请使用WhereColumns")); + if (whereSql.HasValue()) + { + UpdateBuilder.WhereValues.Add(whereSql); + } + if (parameters != null) + { + UpdateBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + } + return this; + } + public IUpdateable Where(string fieldName, string conditionalType, object fieldValue) + { + Check.Exception(UpdateObjectNotWhere() && UpdateObjs.Length > 1, ErrorMessage.GetThrowMessage("update List no support where", "集合更新不支持Where请使用WhereColumns")); + var whereSql = this.SqlBuilder.GetWhere(fieldName, conditionalType, 0); + this.Where(whereSql); + string parameterName = this.SqlBuilder.SqlParameterKeyWord + fieldName + "0"; + this.UpdateBuilder.Parameters.Add(new SugarParameter(parameterName, fieldValue)); + return this; + } + public IUpdateable Where(List conditionalModels) + { + Check.Exception(UpdateObjectNotWhere() && UpdateObjs.Length > 1, ErrorMessage.GetThrowMessage("update List no support where", "集合更新不支持Where请使用WhereColumns")); + var sql = this.Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + var result = this; + result.Where(sql.Key, sql.Value); + return result; + } + public ParameterUpdateable UseParameter() + { + ThrowUpdateByExpressionByMesage(ErrorMessage.GetThrowMessage("UseParameter can only be updated through entity objects", "UseParameter只能通过实体对象更新,不能是表达式方式更新")); + ParameterUpdateable parameter = new ParameterUpdateable(); + parameter.Context = this.Context; + parameter.Updateable = (UpdateableProvider)this; + return parameter; + } + public IUpdateable In(object[] ids) + { + ThrowUpdateByObjectByMesage(" In(object[] ids) "); + List conditionalModels = new List(); + var column = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + Check.ExceptionEasy(column == null, "In need primary key", "In需要实体有主键"); + conditionalModels.Add(new ConditionalModel() { FieldName = column.DbColumnName, ConditionalType = ConditionalType.In, FieldValue = string.Join(",", ids), CSharpTypeName = column.UnderType?.Name }); + return this.Where(conditionalModels); + } + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT2.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT2.cs new file mode 100644 index 000000000..bf7f05d0e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT2.cs @@ -0,0 +1,57 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class UpdateableProvider : IUpdateable where T : class, new() + { + public IUpdateable updateableObj { get; set; } + public int ExecuteCommand() + { + return this.updateableObj.ExecuteCommand(); + } + + public Task ExecuteCommandAsync() + { + return this.updateableObj.ExecuteCommandAsync(); + } + + public IUpdateable InnerJoin(Expression> joinExpress) + { + updateableObj.UpdateBuilder.Context.InitMappingInfo(); + UpdateableProvider result = new UpdateableProvider(); + result.updateableObj = updateableObj; + var joinIno = ((QueryableProvider)updateableObj.UpdateBuilder.Context.Queryable()).GetJoinInfo(joinExpress, JoinType.Inner); + result.updateableObj.UpdateBuilder.JoinInfos.Add(joinIno); + result.updateableObj.UpdateBuilder.ShortName = joinExpress.Parameters.FirstOrDefault()?.Name; + return result; + } + + public IUpdateable SetColumns(Expression> columns) + { + var exp = ((columns as LambdaExpression).Body as MemberInitExpression).Bindings; + var items = ExpressionTool.GetMemberBindingItemList(exp); + var UpdateBuilder = updateableObj.UpdateBuilder; + var SqlBuilder = UpdateBuilder.Builder; + UpdateBuilder.LambdaExpressions.IsSingle = false; + foreach (var item in items) + { + var dbColumnName = updateableObj.UpdateBuilder.Context.EntityMaintenance.GetDbColumnName(item.Key); + var value = updateableObj.UpdateBuilder.GetExpressionValue(ExpressionTool.RemoveConvert(item.Value), ResolveExpressType.WhereMultiple).GetString(); + if (ExpressionTool.GetMethodName(ExpressionTool.RemoveConvert(item.Value)) == "End") + { + value = UtilMethods.RemoveEqualOne(value); + } + this.updateableObj.UpdateBuilder.SetValues.Add(new KeyValuePair(dbColumnName, value)); + } + UpdateBuilder.DbColumnInfoList = UpdateBuilder.DbColumnInfoList + .Where(it => it.UpdateServerTime == true || it.UpdateSql.HasValue() || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + return this; + } + + public IUpdateable Where(Expression> whereExpression) + { + var value = updateableObj.UpdateBuilder.GetExpressionValue(whereExpression, ResolveExpressType.WhereMultiple).GetString(); + updateableObj.UpdateBuilder.WhereValues.Add(value); + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT3.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT3.cs new file mode 100644 index 000000000..64105b975 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT3.cs @@ -0,0 +1,55 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class UpdateableProvider : IUpdateable where T : class, new() + { + internal IUpdateable updateableObj; + + public int ExecuteCommand() + { + return this.updateableObj.ExecuteCommand(); + } + + public Task ExecuteCommandAsync() + { + return this.updateableObj.ExecuteCommandAsync(); + } + + public IUpdateable InnerJoin(Expression> joinExpress) + { + updateableObj.UpdateBuilder.Context.InitMappingInfo(); + UpdateableProvider result = new UpdateableProvider(); + result.updateableObj = updateableObj; + var joinIno = ((QueryableProvider)updateableObj.UpdateBuilder.Context.Queryable()).GetJoinInfo(joinExpress, JoinType.Inner); + result.updateableObj.UpdateBuilder.JoinInfos.Add(joinIno); + result.updateableObj.UpdateBuilder.ShortName = joinExpress.Parameters.FirstOrDefault()?.Name; + return result; + } + + public IUpdateable SetColumns(Expression> columns) + { + var exp = ((columns as LambdaExpression).Body as MemberInitExpression).Bindings; + var items = ExpressionTool.GetMemberBindingItemList(exp); + var UpdateBuilder = updateableObj.UpdateBuilder; + var SqlBuilder = UpdateBuilder.Builder; + foreach (var item in items) + { + updateableObj.UpdateBuilder.LambdaExpressions.IsSingle = false; + var dbColumnName = updateableObj.UpdateBuilder.Context.EntityMaintenance.GetDbColumnName(item.Key); + var value = updateableObj.UpdateBuilder.GetExpressionValue(ExpressionTool.RemoveConvert(item.Value), ResolveExpressType.WhereMultiple).GetString(); + this.updateableObj.UpdateBuilder.SetValues.Add(new KeyValuePair(dbColumnName, value)); + } + UpdateBuilder.DbColumnInfoList = UpdateBuilder.DbColumnInfoList + .Where(it => it.UpdateServerTime == true || it.UpdateSql.HasValue() || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + return this; + } + + public IUpdateable Where(Expression> whereExpression) + { + + var value = updateableObj.UpdateBuilder.GetExpressionValue(whereExpression, ResolveExpressType.WhereMultiple).GetString(); + updateableObj.UpdateBuilder.WhereValues.Add(value); + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT4.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT4.cs new file mode 100644 index 000000000..2bcf86153 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Abstract/UpdateProvider/UpdateableProviderT4.cs @@ -0,0 +1,44 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class UpdateableProvider : IUpdateable where T : class, new() + { + public IUpdateable updateableObj { get; set; } + public int ExecuteCommand() + { + return this.updateableObj.ExecuteCommand(); + } + + public Task ExecuteCommandAsync() + { + return this.updateableObj.ExecuteCommandAsync(); + } + + public IUpdateable SetColumns(Expression> columns) + { + updateableObj.UpdateBuilder.Context.InitMappingInfo(); + var exp = ((columns as LambdaExpression).Body as MemberInitExpression).Bindings; + var items = ExpressionTool.GetMemberBindingItemList(exp); + var UpdateBuilder = updateableObj.UpdateBuilder; + var SqlBuilder = UpdateBuilder.Builder; + foreach (var item in items) + { + updateableObj.UpdateBuilder.LambdaExpressions.IsSingle = false; + var dbColumnName = updateableObj.UpdateBuilder.Context.EntityMaintenance.GetDbColumnName(item.Key); + var value = updateableObj.UpdateBuilder.GetExpressionValue(ExpressionTool.RemoveConvert(item.Value), ResolveExpressType.WhereMultiple).GetString(); + this.updateableObj.UpdateBuilder.SetValues.Add(new KeyValuePair(dbColumnName, value)); + } + UpdateBuilder.DbColumnInfoList = UpdateBuilder.DbColumnInfoList + .Where(it => it.UpdateServerTime == true || it.UpdateSql.HasValue() || UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); + return this; + } + + public IUpdateable Where(Expression> whereExpression) + { + + var value = updateableObj.UpdateBuilder.GetExpressionValue(whereExpression, ResolveExpressType.WhereMultiple).GetString(); + updateableObj.UpdateBuilder.WhereValues.Add(value); + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/CacheScheme/CacheKeyBuider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/CacheScheme/CacheKeyBuider.cs new file mode 100644 index 000000000..c5a068cac --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/CacheScheme/CacheKeyBuider.cs @@ -0,0 +1,73 @@ +namespace SqlSugar +{ + internal static class CacheKeyBuider + { + public static CacheKey GetKey(SqlSugarProvider context, QueryBuilder queryBuilder) + { + CacheKey result = new CacheKey(); + result.Database = context.Context.Ado.Connection.Database; + AddTables(context, queryBuilder, result); + AddIdentificationList(queryBuilder, result); + if (queryBuilder.ResultType != null) + { + result.IdentificationList.Add(queryBuilder.ResultType.FullName); + } + return result; + } + + private static void AddIdentificationList(QueryBuilder queryBuilder, CacheKey result) + { + result.IdentificationList = new List(); + result.IdentificationList.Add(queryBuilder.GetTableNameString); + result.IdentificationList.Add(queryBuilder.GetJoinValueString); + result.IdentificationList.Add(queryBuilder.GetOrderByString); + result.IdentificationList.Add(queryBuilder.GetGroupByString); + result.IdentificationList.Add(queryBuilder.GetWhereValueString); + result.IdentificationList.Add(queryBuilder.PartitionByValue); + result.IdentificationList.Add(queryBuilder.Take.ObjToString()); + result.IdentificationList.Add(queryBuilder.Skip.ObjToString()); + result.IdentificationList.Add(queryBuilder.IsCount.ObjToString()); + result.IdentificationList.Add(UtilMethods.GetMD5(queryBuilder.GetSelectValue.ObjToString())); + if (queryBuilder.Parameters.HasValue()) + { + foreach (var item in queryBuilder.Parameters) + { + result.IdentificationList.Add(item.ParameterName + "_" + item.Value); + } + } + } + + private static void AddTables(SqlSugarProvider context, QueryBuilder queryBuilder, CacheKey result) + { + result.Tables = new List(); + result.Tables.Add(context.EntityMaintenance.GetTableName(queryBuilder.EntityName)); + if (queryBuilder.EasyJoinInfos.HasValue()) + { + foreach (var item in queryBuilder.EasyJoinInfos) + { + result.Tables.Add(context.EntityMaintenance.GetTableName(item.Value)); + } + } + if (queryBuilder.JoinQueryInfos.HasValue()) + { + foreach (var item in queryBuilder.JoinQueryInfos) + { + result.Tables.Add(queryBuilder.Builder.GetNoTranslationColumnName(item.TableName)); + } + } + } + } + + internal class SugarCacheDictionary + { + + } + internal class SugarCacheDictionaryList + { + + } + internal class SugarCacheDataTable + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/CacheScheme/CacheSchemeMain.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/CacheScheme/CacheSchemeMain.cs new file mode 100644 index 000000000..d225bfe6b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/CacheScheme/CacheSchemeMain.cs @@ -0,0 +1,61 @@ +namespace SqlSugar +{ + internal static class CacheSchemeMain + { + public static T GetOrCreate(ICacheService cacheService, QueryBuilder queryBuilder, Func getData, int cacheDurationInSeconds, SqlSugarProvider context, string cacheKey) + { + CacheKey key = CacheKeyBuider.GetKey(context, queryBuilder); + key.AppendKey = cacheKey; + string keyString = key.ToString(); + var result = cacheService.GetOrCreate(keyString, getData, cacheDurationInSeconds); + return result; + } + + public static void RemoveCache(ICacheService cacheService, string tableName) + { + if (cacheService == null) + { + return; + } + if (StaticConfig.CacheRemoveByLikeStringFunc != null) + { + StaticConfig.CacheRemoveByLikeStringFunc(cacheService, UtilConstants.Dot + tableName.ToLower() + UtilConstants.Dot); + return; + } + var keys = cacheService.GetAllKey(); + if (keys.HasValue()) + { + foreach (var item in keys) + { + if (item.Contains($"{UtilConstants.Dot}{tableName}{UtilConstants.Dot}", StringComparison.CurrentCultureIgnoreCase)) + { + cacheService.Remove(item); + } + } + } + } + public static void RemoveCacheByLike(ICacheService cacheService, string likeString) + { + if (cacheService == null) + { + return; + } + if (StaticConfig.CacheRemoveByLikeStringFunc != null) + { + StaticConfig.CacheRemoveByLikeStringFunc(cacheService, likeString); + return; + } + var keys = cacheService.GetAllKey(); + if (keys.HasValue()) + { + foreach (var item in keys) + { + if (item?.Contains(likeString, StringComparison.CurrentCultureIgnoreCase) == true) + { + cacheService.Remove(item); + } + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/DisposableAction.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/DisposableAction.cs new file mode 100644 index 000000000..a28b064c5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/DisposableAction.cs @@ -0,0 +1,19 @@ +namespace SqlSugar.DistributedSystem.Snowflake +{ + public class DisposableAction : IDisposable + { + readonly Action _action; + + public DisposableAction(Action action) + { + if (action == null) + throw new ArgumentNullException(nameof(action)); + _action = action; + } + + public void Dispose() + { + _action(); + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/IdWorker.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/IdWorker.cs new file mode 100644 index 000000000..111d45544 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/IdWorker.cs @@ -0,0 +1,129 @@ +/* Copyright 2010-2012 Twitter, Inc.*/ + +/* + * An object that generates IDs. + * This is broken into a separate class in case + * we ever want to support multiple worker threads + * per process + */ + +namespace SqlSugar.DistributedSystem.Snowflake +{ + public class IdWorker + { + public const long Twepoch = 1288834974657L; + + const int WorkerIdBits = 5; + const int DatacenterIdBits = 5; + const int SequenceBits = 12; + const long MaxWorkerId = -1L ^ (-1L << WorkerIdBits); + const long MaxDatacenterId = -1L ^ (-1L << DatacenterIdBits); + + private const int WorkerIdShift = SequenceBits; + private const int DatacenterIdShift = SequenceBits + WorkerIdBits; + public const int TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits; + private const long SequenceMask = -1L ^ (-1L << SequenceBits); + + private long _sequence = 0L; + private long _lastTimestamp = -1L; + + + public IdWorker(long workerId, long datacenterId, long sequence = 0L) + { + WorkerId = workerId; + DatacenterId = datacenterId; + _sequence = sequence; + + // sanity check for workerId + if (workerId > MaxWorkerId || workerId < 0) + { + throw new ArgumentException(String.Format("worker Id can't be greater than {0} or less than 0", MaxWorkerId)); + } + + if (datacenterId > MaxDatacenterId || datacenterId < 0) + { + throw new ArgumentException(String.Format("datacenter Id can't be greater than {0} or less than 0", MaxDatacenterId)); + } + + //log.info( + // String.Format("worker starting. timestamp left shift {0}, datacenter id bits {1}, worker id bits {2}, sequence bits {3}, workerid {4}", + // TimestampLeftShift, DatacenterIdBits, WorkerIdBits, SequenceBits, workerId) + // ); + } + + public long WorkerId { get; protected set; } + public long DatacenterId { get; protected set; } + + public long Sequence + { + get { return _sequence; } + internal set { _sequence = value; } + } + + // def get_timestamp() = System.currentTimeMillis + + readonly object _lock = new Object(); + public long getID() + { + return NextId(); + } + public virtual long NextId() + { + if (StaticConfig.CustomSnowFlakeFunc != null) + { + return StaticConfig.CustomSnowFlakeFunc(); + } + lock (_lock) + { + var timestamp = TimeGen(); + + if (timestamp < _lastTimestamp) + { + if (StaticConfig.CustomSnowFlakeTimeErrorFunc != null) + { + return StaticConfig.CustomSnowFlakeTimeErrorFunc(); + } + //exceptionCounter.incr(1); + //log.Error("clock is moving backwards. Rejecting requests until %d.", _lastTimestamp); + throw new InvalidSystemClock(String.Format( + "服务器时间出现回退你可以使用StaticConfig.CustomSnowFlakeTimeErrorFunc=【自定义方法】处理让他不报错返回新ID,Clock moved backwards. Refusing to generate id for {0} milliseconds", _lastTimestamp - timestamp)); + } + + if (_lastTimestamp == timestamp) + { + _sequence = (_sequence + 1) & SequenceMask; + if (_sequence == 0) + { + timestamp = TilNextMillis(_lastTimestamp); + } + } + else + { + _sequence = 0; + } + + _lastTimestamp = timestamp; + var id = ((timestamp - Twepoch) << TimestampLeftShift) | + (DatacenterId << DatacenterIdShift) | + (WorkerId << WorkerIdShift) | _sequence; + + return id; + } + } + + protected virtual long TilNextMillis(long lastTimestamp) + { + var timestamp = TimeGen(); + while (timestamp <= lastTimestamp) + { + timestamp = TimeGen(); + } + return timestamp; + } + + protected virtual long TimeGen() + { + return System.CurrentTimeMillis(); + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/InvalidSystemClock.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/InvalidSystemClock.cs new file mode 100644 index 000000000..56831f81b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/InvalidSystemClock.cs @@ -0,0 +1,15 @@ +namespace SqlSugar.DistributedSystem.Snowflake +{ + public class InvalidSystemClock : Exception + { + public InvalidSystemClock(string message) : base(message) { } + + public InvalidSystemClock() : base() + { + } + + public InvalidSystemClock(string? message, Exception? innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/SnowFlakeSingle.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/SnowFlakeSingle.cs new file mode 100644 index 000000000..3ab5ff447 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/SnowFlakeSingle.cs @@ -0,0 +1,39 @@ +namespace SqlSugar +{ + public sealed class SnowFlakeSingle + { + private static object LockObject = new object(); + private static DistributedSystem.Snowflake.IdWorker worker; + public static int WorkId = 1; + public static int DatacenterId = 1; + private SnowFlakeSingle() + { + + } + static SnowFlakeSingle() { } + public static DistributedSystem.Snowflake.IdWorker Instance + { + get + { + if (worker == null) + { + lock (LockObject) + { + if (worker == null) + { + worker = new DistributedSystem.Snowflake.IdWorker(WorkId, DatacenterId); + } + } + } + return worker; + } + } + public static DistributedSystem.Snowflake.IdWorker instance + { + get + { + return Instance; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/TimeExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/TimeExtensions.cs new file mode 100644 index 000000000..7b6e8d1e5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/TimeExtensions.cs @@ -0,0 +1,38 @@ +namespace SqlSugar.DistributedSystem.Snowflake +{ + public static class System + { + public static Func currentTimeFunc = InternalCurrentTimeMillis; + + public static long CurrentTimeMillis() + { + return currentTimeFunc(); + } + + public static IDisposable StubCurrentTime(Func func) + { + currentTimeFunc = func; + return new DisposableAction(() => + { + currentTimeFunc = InternalCurrentTimeMillis; + }); + } + + public static IDisposable StubCurrentTime(long millis) + { + currentTimeFunc = () => millis; + return new DisposableAction(() => + { + currentTimeFunc = InternalCurrentTimeMillis; + }); + } + + private static readonly DateTime Jan1st1970 = new DateTime + (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + private static long InternalCurrentTimeMillis() + { + return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/ValueToStringConverter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/ValueToStringConverter.cs new file mode 100644 index 000000000..63547ca21 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/DistributedSystem/Snowflake/ValueToStringConverter.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; + +namespace SqlSugar +{ + public class ValueToStringConverter : JsonConverter + { + public override bool CanRead => false; + + public override bool CanConvert(Type objectType) => objectType.IsValueType; + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + => throw new NotSupportedException(); + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var str = value?.ToString(); + writer.WriteValue(str); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/AsyncRef.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/AsyncRef.cs new file mode 100644 index 000000000..3e2e6cac6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/AsyncRef.cs @@ -0,0 +1,16 @@ +namespace SqlSugar +{ + public class RefAsync + { + public RefAsync() { } + public RefAsync(T value) { Value = value; } + public T Value { get; set; } + public override string ToString() + { + T value = Value; + return value == null ? "" : value.ToString(); + } + public static implicit operator T(RefAsync r) { return r.Value; } + public static implicit operator RefAsync(T value) { return new RefAsync(value); } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/CacheKey.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/CacheKey.cs new file mode 100644 index 000000000..66cb935f1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/CacheKey.cs @@ -0,0 +1,16 @@ +namespace SqlSugar +{ + public class CacheKey + { + public string AppendKey { get; set; } + public string Database { get; set; } + public List Tables { get; set; } + public List IdentificationList { get; set; } + public new string ToString() + { + var result = "SqlSugarDataCache" + UtilConstants.Dot + string.Join(UtilConstants.Dot, this.Tables) + UtilConstants.Dot + string.Join(UtilConstants.Dot, this.IdentificationList.Where(it => it.HasValue())); + result = result + AppendKey; + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConditionalModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConditionalModel.cs new file mode 100644 index 000000000..d33140e0b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConditionalModel.cs @@ -0,0 +1,38 @@ +namespace SqlSugar +{ + public interface IConditionalModel + { + + } + public class ConditionalCollections : IConditionalModel + { + public List> ConditionalList { get; set; } + } + public class ConditionalTree : IConditionalModel + { + public List> ConditionalList { get; set; } + } + public class ConditionalModel : IConditionalModel + { + public ConditionalModel() + { + this.ConditionalType = ConditionalType.Equal; + } + public string FieldName { get; set; } + public string FieldValue { get; set; } + public string CSharpTypeName { get; set; } + + + public ICustomConditionalFunc CustomConditionalFunc { get; set; } + public object CustomParameterValue { get; set; } + + public ConditionalType ConditionalType { get; set; } + [Newtonsoft.Json.JsonIgnoreAttribute] + public Func FieldValueConvertFunc { get; set; } + + public static List Create(params IConditionalModel[] conditionalModel) + { + return conditionalModel.ToList(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConfigQuery.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConfigQuery.cs new file mode 100644 index 000000000..79c3683ac --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConfigQuery.cs @@ -0,0 +1,62 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class ConfigQuery + { + public SqlSugarProvider Context { get; set; } + public void SetTable(Expression> keyExpression, Expression> valueTextExpression, string uniqueCode = null, Expression> whereExpression = null) + { + lock (SqlFuncExtendsion.TableInfos) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + ExpressionContext context = new ExpressionContext(); + var query = Context.Queryable().QueryBuilder; + var keyValue = query.GetExpressionValue(keyExpression, ResolveExpressType.FieldSingle).GetString(); + var ValueValue = query.GetExpressionValue(valueTextExpression, ResolveExpressType.FieldSingle).GetString(); + string where = null; + if (whereExpression != null) + { + where = query.GetExpressionValue(whereExpression, ResolveExpressType.WhereSingle).GetResultString(); + } + context.MappingTables = this.Context.MappingTables; + if (!SqlFuncExtendsion.TableInfos.Any(y => y.Type == typeof(T) && y.Code == uniqueCode)) + { + SqlFuncExtendsion.TableInfos.Add(new ConfigTableInfo() + { + Type = typeof(T), + TableName = entity.DbTableName, + Key = keyValue, + Value = ValueValue, + Where = where, + Parameter = query.Parameters, + Code = uniqueCode + }); + } + else + { + Check.Exception(true, "SetKeyValue error , entity & uniqueCode already exist"); + } + } + } + public void SetTable(Expression> key, Expression> value) + { + SetTable(key, value, null, null); + } + + public bool Any() + { + return SqlFuncExtendsion.TableInfos.Count != 0; + } + } + + public class ConfigTableInfo + { + public string Code { get; set; } + public Type Type { get; set; } + public string TableName { get; set; } + public string Key { get; set; } + public string Value { get; set; } + public string Where { get; set; } + public List Parameter { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConnMoreSettings.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConnMoreSettings.cs new file mode 100644 index 000000000..9570f1415 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConnMoreSettings.cs @@ -0,0 +1,37 @@ +namespace SqlSugar +{ + public class ConnMoreSettings + { + public bool IsAutoRemoveDataCache { get; set; } + public bool IsWithNoLockQuery { get; set; } + public bool DisableWithNoLockWithTran { get; set; } + public bool IsWithNoLockSubquery { get; set; } + + public bool DisableNvarchar { get; set; } + public bool DisableMillisecond { get; set; } + public bool PgSqlIsAutoToLower { get; set; } = true; + public bool PgSqlIsAutoToLowerCodeFirst { get; set; } = true; + public bool PgSqlIsAutoToLowerSchema { get; set; } = true; + public bool EnableILike { get; set; } + public bool IsAutoToUpper { get; set; } = true; + public int DefaultCacheDurationInSeconds { get; set; } + public bool? TableEnumIsString { get; set; } + public DateTime? DbMinDate { get; set; } = DateTime.MinValue.Date.AddYears(1900 - 1); + public bool IsNoReadXmlDescription { get; set; } + public bool SqlServerCodeFirstNvarchar { get; set; } + public bool OracleCodeFirstNvarchar2 { get; set; } + public bool SqliteCodeFirstEnableDefaultValue { get; set; } + public bool SqliteCodeFirstEnableDescription { get; set; } + public bool IsAutoUpdateQueryFilter { get; set; } + public bool IsAutoDeleteQueryFilter { get; set; } + public bool EnableModelFuncMappingColumn { get; set; } + public bool EnableOracleIdentity { get; set; } + public bool EnableCodeFirstUpdatePrecision { get; set; } + public bool SqliteCodeFirstEnableDropColumn { get; set; } + public bool IsCorrectErrorSqlParameterName { get; set; } + public int MaxParameterNameLength { get; set; } + public bool DisableQueryWhereColumnRemoveTrim { get; set; } + public DbType? DatabaseModel { get; set; } + public bool ClickHouseEnableFinal { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConnectionConfig.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConnectionConfig.cs new file mode 100644 index 000000000..5fbaac673 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ConnectionConfig.cs @@ -0,0 +1,155 @@ +using Newtonsoft.Json; + +using System.Data; +using System.Reflection; +namespace SqlSugar +{ + public class ConnectionConfig + { + /// + ///Connection unique code + /// + public object ConfigId { get; set; } + /// + ///DbType.SqlServer Or Other + /// + public DbType DbType { get; set; } + /// + ///Database Connection string + /// + public string ConnectionString { get; set; } + /// + /// QueryableWithAttr queries go to DbLinkName, which is commonly used for cross-library queries + /// + public string DbLinkName { get; set; } + /// + /// true does not need to close the connection + /// + public bool IsAutoCloseConnection { get; set; } + /// + /// Default Attribute + /// + public InitKeyType InitKeyType = InitKeyType.Attribute; + /// + /// Exception prompt language + /// + public LanguageType LanguageType { get => ErrorMessage.SugarLanguageType; set => ErrorMessage.SugarLanguageType = value; } + + /// + /// Configure External Services replace default services,For example, Redis storage + /// + [JsonIgnore] + public ConfigureExternalServices ConfigureExternalServices = new ConfigureExternalServices(); + /// + /// If SlaveConnectionStrings has value,ConnectionString is write operation, SlaveConnectionStrings is read operation. + /// All operations within a transaction is ConnectionString + /// + public List SlaveConnectionConfigs { get; set; } + /// + /// More Gobal Settings + /// + public ConnMoreSettings MoreSettings { get; set; } + ///// + ///// Used for debugging errors or BUG,Used for debugging, which has an impact on Performance + ///// + //public SugarDebugger Debugger { get; set; } + + public string IndexSuffix { get; set; } + + [JsonIgnore] + public AopEvents AopEvents { get; set; } + + public SqlMiddle SqlMiddle { get; set; } + } + public class SqlMiddle + { + public bool? IsSqlMiddle { get; set; } + public Func GetScalar { get; set; } = (s, p) => throw new Exception("SqlMiddle.GetScalar is null"); + public Func ExecuteCommand { get; set; } = (s, p) => throw new Exception("SqlMiddle.ExecuteCommand is null"); + public Func GetDataReader { get; set; } = (s, p) => throw new Exception("SqlMiddle.GetDataReader is null"); + public Func GetDataSetAll { get; set; } = (s, p) => throw new Exception("SqlMiddle.GetDataSetAll is null"); + public Func> GetScalarAsync { get; set; } = (s, p) => throw new Exception("SqlMiddle.GetScalarAsync is null"); + public Func> ExecuteCommandAsync { get; set; } = (s, p) => throw new Exception("SqlMiddle.ExecuteCommandAsync is null"); + public Func> GetDataReaderAsync { get; set; } = (s, p) => throw new Exception("SqlMiddle.GetDataReaderAsync is null"); + public Func> GetDataSetAllAsync { get; set; } = (s, p) => throw new Exception("SqlMiddle.GetDataSetAllAsync is null"); + + } + public class AopEvents + { + public Action OnDiffLogEvent { get; set; } + public Action OnError { get; set; } + public Action OnLogExecuting { get; set; } + public Action OnLogExecuted { get; set; } + public Func> OnExecutingChangeSql { get; set; } + public Action DataExecuting { get; set; } + public Action DataChangesExecuted { get; set; } + public Action DataExecuted { get; set; } + public Action CheckConnectionExecuting { get; set; } + public Action CheckConnectionExecuted { get; set; } + public Action OnGetDataReadering { get; set; } + public Action OnGetDataReadered { get; set; } + } + public class ConfigureExternalServices + { + + private ISerializeService _SerializeService; + private ICacheService _ReflectionInoCache; + private ICacheService _DataInfoCache; + private IRazorService _RazorService; + public ISplitTableService SplitTableService { get; set; } + public IRazorService RazorService + { + get + { + if (_RazorService == null) + return _RazorService; + else + return _RazorService; + } + set { _RazorService = value; } + } + + public ISerializeService SerializeService + { + get + { + if (_SerializeService == null) + return DefaultServices.Serialize; + else + return _SerializeService; + } + set { _SerializeService = value; } + } + + public ICacheService ReflectionInoCacheService + { + get + { + if (_ReflectionInoCache == null) + return DefaultServices.ReflectionInoCache; + else + return _ReflectionInoCache; + } + set { _ReflectionInoCache = value; } + } + + public ICacheService DataInfoCacheService + { + get + { + if (_DataInfoCache == null) + return DefaultServices.DataInoCache; + else + return _DataInfoCache; + } + set { _DataInfoCache = value; } + } + + public List SqlFuncServices { get; set; } + public List> AppendDataReaderTypeMappings { get; set; } + + + public Action EntityService { get; set; } + public Action EntityNameService { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbColumnInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbColumnInfo.cs new file mode 100644 index 000000000..5052e7de8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbColumnInfo.cs @@ -0,0 +1,31 @@ +namespace SqlSugar +{ + public class DbColumnInfo + { + public string TableName { get; set; } + public int TableId { get; set; } + public string DbColumnName { get; set; } + public string PropertyName { get; set; } + public string DataType { get; set; } + public string OracleDataType { get; set; } + public Type PropertyType { get; set; } + public int Length { get; set; } + public string ColumnDescription { get; set; } + public string DefaultValue { get; set; } + public bool IsNullable { get; set; } + public bool IsIdentity { get; set; } + public bool IsPrimarykey { get; set; } + public object Value { get; set; } + public int DecimalDigits { get; set; } + public int Scale { get; set; } + public bool IsArray { get; set; } + public bool IsJson { get; set; } + public bool? IsUnsigned { get; set; } + public int CreateTableFieldSort { get; set; } + public bool InsertServerTime { get; set; } + public string InsertSql { get; set; } + public bool UpdateServerTime { get; set; } + public string UpdateSql { get; set; } + public object SqlParameterDbType { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbFastestProperties.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbFastestProperties.cs new file mode 100644 index 000000000..bca5764d7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbFastestProperties.cs @@ -0,0 +1,13 @@ +namespace SqlSugar +{ + public class DbFastestProperties + { + public bool HasOffsetTime { get; set; } + public string[] WhereColumns { get; set; } + public bool IsOffIdentity { get; set; } + public bool IsMerge { get; set; } + public bool IsNoCopyDataTable { get; set; } + public bool IsConvertDateTimeOffsetToDateTime { get; set; } + public bool NoPage { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbResult.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbResult.cs new file mode 100644 index 000000000..b986af799 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbResult.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public class DbResult + { + public bool IsSuccess { get; set; } + public Exception ErrorException { get; set; } + public string ErrorMessage { get; set; } + public T Data { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbTableInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbTableInfo.cs new file mode 100644 index 000000000..c10c6ca7f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DbTableInfo.cs @@ -0,0 +1,30 @@ +namespace SqlSugar +{ + public class DbTableInfo + { + public string Name { get; set; } + public string Description { get; set; } + public DbObjectType DbObjectType { get; set; } + } + + public class RazorTableInfo + { + public string DbTableName { get; set; } + public string ClassName { get; set; } + public string Description { get; set; } + public DbObjectType DbObjectType { get; set; } + public List Columns { get; set; } + } + + public class RazorColumnInfo + { + public string DbColumnName { get; set; } + public string DataType { get; set; } + public int Length { get; set; } + public string ColumnDescription { get; set; } + public string DefaultValue { get; set; } + public bool IsNullable { get; set; } + public bool IsIdentity { get; set; } + public bool IsPrimarykey { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DefaultCustom.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DefaultCustom.cs new file mode 100644 index 000000000..8e0797763 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DefaultCustom.cs @@ -0,0 +1,107 @@ +using System.Data; +using System.Text; + +namespace SqlSugar.DbConvert +{ + public class EnumToStringConvert : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + var name = "@MyEnum" + columnIndex; + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + if (columnValue == null) + { + return new SugarParameter(name, null); + } + else + { + var enumObjString = Enum.Parse(undertype, columnValue + "").ToString(); + return new SugarParameter(name, enumObjString); + } + } + + public T QueryConverter(IDataRecord dr, int i) + { + + var str = dr.GetString(i); + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + return (T)Enum.Parse(undertype, str); + } + } + + public class NoParameterCommonPropertyConvert : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + if (columnValue == null) + { + return new SugarParameter("null", null, null); + } + return new SugarParameter($"{columnValue}", null, null); + } + + public T QueryConverter(IDataRecord dr, int i) + { + + var value = dr.GetValue(i); + return (T)UtilMethods.ChangeType2(value, typeof(T)); + } + } + public class CommonPropertyConvert : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + var name = "@Common" + columnIndex; + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + return new SugarParameter(name, columnValue, undertype); + } + + public T QueryConverter(IDataRecord dr, int i) + { + + + var value = dr.GetValue(i); + if (value is byte[] && typeof(T) != UtilConstants.ByteArrayType) + { + value = Encoding.UTF8.GetString((byte[])value); + } + return (T)UtilMethods.ChangeType2(value, typeof(T)); + + } + } + + + public class Nvarchar2PropertyConvert : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + var name = "@Common" + columnIndex; + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + return new SugarParameter(name, columnValue, undertype) { IsNvarchar2 = true }; + } + + public T QueryConverter(IDataRecord dr, int i) + { + + var value = dr.GetString(i); + return (T)(object)value; + } + } + + public class NClobPropertyConvert : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + var name = "@Common" + columnIndex; + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + return new SugarParameter(name, columnValue, undertype) { IsNClob = true }; + } + + public T QueryConverter(IDataRecord dr, int i) + { + + var value = dr.GetString(i); + return (T)(object)value; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DefaultServices.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DefaultServices.cs new file mode 100644 index 000000000..20ce86e6e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DefaultServices.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public static class DefaultServices + { + public static ICacheService ReflectionInoCache = new ReflectionInoCacheService(); + public static ICacheService DataInoCache = null; + public static ISerializeService Serialize = new SerializeService(); + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DeleteNavOptions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DeleteNavOptions.cs new file mode 100644 index 000000000..8f6960030 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DeleteNavOptions.cs @@ -0,0 +1,63 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class DeleteNavOptions + { + public bool ManyToManyIsDeleteA { get; set; } + public bool ManyToManyIsDeleteB { get; set; } + } + public class DeleteNavRootOptions + { + public bool IsDiffLogEvent { get; set; } + public object DiffLogBizData { get; set; } + } + public class InsertNavRootOptions + { + public string[] IgnoreColumns { get; set; } + public string[] InsertColumns { get; set; } + public bool IsDiffLogEvent { get; set; } + public object DiffLogBizData { get; set; } + } + //public class InertNavRootOptions + //{ + // public string[] IgnoreColumns { get; set; } + // public string[] InsertColumns { get; set; } + //} + public class UpdateNavRootOptions + { + public string[] IgnoreColumns { get; set; } + public string[] UpdateColumns { get; set; } + public bool IsIgnoreAllNullColumns { get; set; } + public bool IsInsertRoot { get; set; } + public bool IsDisableUpdateRoot { get; set; } + public bool IsDiffLogEvent { get; set; } + public object DiffLogBizData { get; set; } + public string[] IgnoreInsertColumns { get; set; } + public bool IsOptLock { get; set; } + + } + public class UpdateNavOptions + { + public bool ManyToManyIsUpdateA { get; set; } + public bool ManyToManyIsUpdateB { get; set; } + public object ManyToManySaveMappingTemplate { get; set; } + public bool ManyToManyEnableLogicDelete { get; set; } + public bool OneToManyDeleteAll { get; set; } + public bool OneToManyEnableLogicDelete { get; set; } + public bool OneToManyNoDeleteNull { get; set; } + public bool OneToManyInsertOrUpdate { get; set; } + public Expression RootFunc { get; set; } + public Expression CurrentFunc { get; set; } + public string[] IgnoreColumns { get; set; } + public bool IgnoreNullColumns { get; set; } + public bool OneToOneSaveByPrimaryKey { get; set; } + } + + public class InsertNavOptions + { + public bool OneToManyIfExistsNoInsert { get; set; } + public bool ManyToManyNoDeleteMap { get; set; } + public object ManyToManySaveMappingTemplate { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiffLogModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiffLogModel.cs new file mode 100644 index 000000000..e30c7e134 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiffLogModel.cs @@ -0,0 +1,26 @@ +namespace SqlSugar +{ + public class DiffLogModel + { + public List AfterData { get; set; } + public List BeforeData { get; set; } + public SugarParameter[] Parameters { get; set; } + public string Sql { get; set; } + public TimeSpan? Time { get; set; } + public object BusinessData { get; set; } + public DiffType DiffType { get; set; } + } + public class DiffLogTableInfo + { + public string TableName { get; set; } + public string TableDescription { get; set; } + public List Columns { get; set; } + } + public class DiffLogColumnInfo + { + public string ColumnName { get; set; } + public string ColumnDescription { get; set; } + public object Value { get; set; } + public bool IsPrimaryKey { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiffType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiffType.cs new file mode 100644 index 000000000..11acb5bef --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiffType.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public enum DiffType + { + insert = 0, + update = 1, + delete = 2 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiscriminatorObject .cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiscriminatorObject .cs new file mode 100644 index 000000000..3bcbd5f7b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DiscriminatorObject .cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public struct DiscriminatorObject + { + public string FieldName { get; set; } + public string FieldValue { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DynamicSelectModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DynamicSelectModel.cs new file mode 100644 index 000000000..88910390a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/DynamicSelectModel.cs @@ -0,0 +1,183 @@ +namespace SqlSugar +{ + public class DynamicCoreSelectModel + { + public object Value { get; set; } + + public object ToList() + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("ToList", 0); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a ToList method with no parameters."); + } + + return method.Invoke(Value, null); + } + + public async Task ToListAsync() + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("ToListAsync", 0); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a ToListAsync method with no parameters."); + } + + var task = (Task)method.Invoke(Value, null); + return await GetTask(task).ConfigureAwait(false); + } + + public object ToPageList(int pageNumber, int pageSize) + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("ToPageList", 2); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a ToPageList method with two parameters."); + } + + return method.Invoke(Value, new object[] { pageNumber, pageSize }); + } + + public async Task ToPageListAsync(int pageNumber, int pageSize) + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("ToPageListAsync", 2); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a ToPageListAsync method with two parameters."); + } + + var task = (Task)method.Invoke(Value, new object[] { pageNumber, pageSize }); + return await GetTask(task).ConfigureAwait(false); + } + + public object ToPageList(int pageNumber, int pageSize, ref int totalNumber) + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("ToPageList", 3); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a ToPageList method with three parameters."); + } + + var parameters = new object[] { pageNumber, pageSize, totalNumber }; + var result = method.Invoke(Value, parameters); + totalNumber = (int)parameters[2]; + return result; + } + + public async Task ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber) + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("ToPageListAsync", 3, typeof(int), typeof(int), typeof(RefAsync)); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a ToPageListAsync method with three parameters."); + } + + var parameters = new object[] { pageNumber, pageSize, totalNumber }; + var task = (Task)method.Invoke(Value, parameters); + var result = await GetTask(task).ConfigureAwait(false); + return result; + } + public object Single() + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("Single", 0); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a Single method with no parameters."); + } + + return method.Invoke(Value, null); + } + public object First() + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("First", 0); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a First method with no parameters."); + } + + return method.Invoke(Value, null); + } + + public async Task SingleAsync() + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("SingleAsync", 0); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a SingleAsync method with no parameters."); + } + + var task = (Task)method.Invoke(Value, null); + return await GetTask(task).ConfigureAwait(false); + } + + public async Task FirstAsync() + { + if (Value is null) + { + throw new InvalidOperationException("Value cannot be null."); + } + + var method = Value.GetType().GetMyMethod("FirstAsync", 0); + if (method == null) + { + throw new InvalidOperationException("The Value object does not have a FirstAsync method with no parameters."); + } + + var task = (Task)method.Invoke(Value, null); + return await GetTask(task).ConfigureAwait(false); + } + + private static async Task GetTask(Task task) + { + await task.ConfigureAwait(false); // 等待任务完成 + var resultProperty = task.GetType().GetProperty("Result"); + var value = resultProperty.GetValue(task); + return value; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/EntityColumnInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/EntityColumnInfo.cs new file mode 100644 index 000000000..7fca005ff --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/EntityColumnInfo.cs @@ -0,0 +1,49 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class EntityColumnInfo + { + public PropertyInfo PropertyInfo { get; set; } + public string PropertyName { get; set; } + public string DbColumnName { get; set; } + public string OldDbColumnName { get; set; } + public int Length { get; set; } + public string ColumnDescription { get; set; } + public string DefaultValue { get; set; } + public bool IsNullable { get; set; } + public bool IsIdentity { get; set; } + public bool IsPrimarykey { get; set; } + public bool IsTreeKey { get; set; } + public bool IsEnableUpdateVersionValidation { get; set; } + public object SqlParameterDbType { get; set; } + public string EntityName { get; set; } + public string DbTableName { get; set; } + public bool IsIgnore { get; set; } + public string DataType { get; set; } + public int DecimalDigits { get; set; } + public string OracleSequenceName { get; set; } + public bool IsOnlyIgnoreInsert { get; set; } + public bool IsOnlyIgnoreUpdate { get; set; } + public bool IsTranscoding { get; set; } + public string SerializeDateTimeFormat { get; set; } + public bool IsJson { get; set; } + public bool NoSerialize { get; set; } + public string[] IndexGroupNameList { get; set; } + public string[] UIndexGroupNameList { get; set; } + public bool IsArray { get; set; } + public Type UnderType { get; set; } + public Navigate Navigat { get; set; } + public int CreateTableFieldSort { get; set; } + public object SqlParameterSize { get; set; } + public string InsertSql { get; set; } + public bool InsertServerTime { get; set; } + public bool UpdateServerTime { get; set; } + public string UpdateSql { get; set; } + public object ExtendedAttribute { get; set; } + public bool IsDisabledAlterColumn { get; set; } + public string QuerySql { get; set; } + public bool IsOwnsOne { get; set; } + public PropertyInfo ForOwnsOnePropertyInfo { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/EntityInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/EntityInfo.cs new file mode 100644 index 000000000..69fa341b9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/EntityInfo.cs @@ -0,0 +1,17 @@ +namespace SqlSugar +{ + public class EntityInfo + { + private string _DbTableName; + public string EntityName { get; set; } + public string DbTableName { get { return _DbTableName == null ? EntityName : _DbTableName; } set { _DbTableName = value; } } + public string TableDescription { get; set; } + public Type Type { get; set; } + public List Columns { get; set; } + public bool IsDisabledDelete { get; set; } + public bool IsDisabledUpdateAll { get; set; } + public List Indexs { get; set; } + public bool IsCreateTableFiledSort { get; set; } + public string Discrimator { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinInfoParameter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinInfoParameter.cs new file mode 100644 index 000000000..731c6f5e5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinInfoParameter.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public class JoinInfoParameter + { + public string TableName { get; set; } + public string ShortName { get; set; } + public IFuncModel Models { get; set; } + public JoinType Type { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinMapper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinMapper.cs new file mode 100644 index 000000000..bc36ed222 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinMapper.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class JoinMapper + { + public string AsName { get; set; } + public string DbName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinQueryInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinQueryInfo.cs new file mode 100644 index 000000000..8c2c68599 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/JoinQueryInfo.cs @@ -0,0 +1,61 @@ +namespace SqlSugar +{ + + public class JoinQueryInfo + { + public JoinType JoinType { get; set; } + public string TableName { get; set; } + public string ShortName { get; set; } + public int JoinIndex { get; set; } + public string JoinWhere { get; set; } + public Type EntityType { get; set; } + } + public class JoinQueryInfos + { + private JoinQueryInfos() { } + public JoinQueryInfos(JoinType joinType, bool whereExpress) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5, JoinType joinType6, bool whereExpress6) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5, JoinType joinType6, bool whereExpress6, JoinType joinType7, bool whereExpress7) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5, JoinType joinType6, bool whereExpress6, JoinType joinType7, bool whereExpress7, JoinType joinType8, bool whereExpress8) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5, JoinType joinType6, bool whereExpress6, JoinType joinType7, bool whereExpress7, JoinType joinType8, bool whereExpress8, JoinType joinType9, bool whereExpress9) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5, JoinType joinType6, bool whereExpress6, JoinType joinType7, bool whereExpress7, JoinType joinType8, bool whereExpress8, JoinType joinType9, bool whereExpress9, JoinType joinType10, bool whereExpress10) + { + + } + public JoinQueryInfos(JoinType joinType, bool whereExpress, JoinType joinType2, bool whereExpress2, JoinType joinType3, bool whereExpress3, JoinType joinType4, bool whereExpress4, JoinType joinType5, bool whereExpress5, JoinType joinType6, bool whereExpress6, JoinType joinType7, bool whereExpress7, JoinType joinType8, bool whereExpress8, JoinType joinType9, bool whereExpress9, JoinType joinType10, bool whereExpress10, JoinType joinType11, bool whereExpress11) + { + + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ManyToManyConfig.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ManyToManyConfig.cs new file mode 100644 index 000000000..574f7378e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ManyToManyConfig.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public class ManyToMany + { + public static ManyToMany Config(AField aField, BField bField) + { + return null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/MapperCache.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/MapperCache.cs new file mode 100644 index 000000000..55fae56d0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/MapperCache.cs @@ -0,0 +1,153 @@ +namespace SqlSugar +{ + public class MapperCache + { + private Dictionary caches = new Dictionary(); + private List _list { get; set; } + private ISqlSugarClient _context { get; set; } + public int GetIndex { get; set; } + private MapperCache() + { + } + public MapperCache(List list, ISqlSugarClient context) + { + _list = list; + _context = context; + } + public Result Get(Func, Result> action) + { + GetIndex++; + string key = "Get" + typeof(Result) + action.GetHashCode() + action.Method.Name; + if (caches.TryGetValue(key, out object? value)) + { + return (Result)value; + } + else + { + var result = action(_list); + caches.Add(key, result); + return result; + } + } + public Result Get(Func, Result> action, string cachekey) + { + GetIndex++; + string key = "Get" + typeof(Result) + action.GetHashCode() + action.Method.Name + cachekey; + if (caches.TryGetValue(key, out object? value)) + { + return (Result)value; + } + else + { + var result = action(_list); + caches.Add(key, result); + return result; + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + public List GetListByPrimaryKeys(Func action) where Result : class, new() + { + { + string key = "GetListById" + typeof(Result) + action.GetHashCode().ToString(); + return GetListByPrimaryKeys(action, key); + } + } + private List GetListByPrimaryKeys(Func action, string key) where Result : class, new() + { + if (caches.TryGetValue(key, out object? value)) + { + return (List)value; + } + else + { + var ids = _list.Select(action).ToList().Distinct().ToList(); + var result = _context.Queryable().In(ids).ToList(); + caches.Add(key, result); + return result; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/IgnoreComumn.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/IgnoreComumn.cs new file mode 100644 index 000000000..e2ac38a3b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/IgnoreComumn.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class IgnoreColumn + { + public string EntityName { get; set; } + public string PropertyName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/MappingColumn.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/MappingColumn.cs new file mode 100644 index 000000000..b1e69472e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/MappingColumn.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public class MappingColumn + { + public string PropertyName { get; set; } + public string DbColumnName { get; set; } + public string EntityName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/MappingTable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/MappingTable.cs new file mode 100644 index 000000000..bf1cd7d73 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/MappingTable.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public class MappingTable + { + public string EntityName { get; set; } + public string DbTableName { get; set; } + public string DbShortTaleName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/SugarMappingAttribute.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/SugarMappingAttribute.cs new file mode 100644 index 000000000..1ab98a5a5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/Mapping/SugarMappingAttribute.cs @@ -0,0 +1,463 @@ +namespace SqlSugar +{ + [AttributeUsage(AttributeTargets.Class, Inherited = true)] + public class SugarTable : Attribute + { + public SugarTable() { } + public string TableName { get; set; } + public string TableDescription { get; set; } + public bool IsDisabledDelete { get; set; } + public bool IsDisabledUpdateAll { get; set; } + public bool IsCreateTableFiledSort { get; set; } + public string Discrimator { get; set; } + public SugarTable(string tableName) + { + this.TableName = tableName; + } + public SugarTable(string tableName, string tableDescription) + { + this.TableName = tableName; + this.TableDescription = tableDescription; + } + + public SugarTable(string tableName, string tableDescription, bool isDisabledDelete) + { + this.TableName = tableName; + this.TableDescription = tableDescription; + this.IsDisabledDelete = isDisabledDelete; + } + public SugarTable(string tableName, string tableDescription, bool isDisabledDelete, bool isCreateTableFieldSort) + { + this.TableName = tableName; + this.TableDescription = tableDescription; + this.IsDisabledDelete = isDisabledDelete; + this.IsCreateTableFiledSort = isCreateTableFieldSort; + } + } + [AttributeUsage(AttributeTargets.Property, Inherited = true)] + public class SugarColumn : Attribute + { + private string _ColumnName; + public string ColumnName + { + get { return _ColumnName; } + set { _ColumnName = value; } + } + + private bool _IsIgnore; + public bool IsIgnore + { + get { return _IsIgnore; } + set { _IsIgnore = value; } + } + + private bool _IsPrimaryKey; + public bool IsPrimaryKey + { + get { return _IsPrimaryKey; } + set { _IsPrimaryKey = value; } + } + + private bool _IsIdentity; + public bool IsIdentity + { + get { return _IsIdentity; } + set { _IsIdentity = value; } + } + + private string _MappingKeys; + public string MappingKeys + { + get { return _MappingKeys; } + set { _MappingKeys = value; } + } + + private string _ColumnDescription; + public string ColumnDescription + { + get { return _ColumnDescription; } + set { _ColumnDescription = value; } + } + + private int _Length; + public int Length + { + get { return _Length; } + set { _Length = value; } + } + + private bool _IsNullable; + public bool IsNullable + { + get { return _IsNullable; } + set { _IsNullable = value; } + } + + private string _OldColumnName; + public string OldColumnName + { + get { return _OldColumnName; } + set { _OldColumnName = value; } + } + + private string _ColumnDataType; + public string ColumnDataType + { + get { return _ColumnDataType; } + set { _ColumnDataType = value; } + } + + private int _DecimalDigits; + public int DecimalDigits + { + get { return _DecimalDigits; } + set { _DecimalDigits = value; } + } + + private string _OracleSequenceName; + public string OracleSequenceName + { + get { return _OracleSequenceName; } + set { _OracleSequenceName = value; } + } + + private bool _IsOnlyIgnoreInsert; + public bool IsOnlyIgnoreInsert + { + get { return _IsOnlyIgnoreInsert; } + set { _IsOnlyIgnoreInsert = value; } + } + + private bool _IsOnlyIgnoreUpdate; + public bool IsOnlyIgnoreUpdate + { + get { return _IsOnlyIgnoreUpdate; } + set { _IsOnlyIgnoreUpdate = value; } + } + + + private bool _IsEnableUpdateVersionValidation; + public bool IsEnableUpdateVersionValidation + { + get { return _IsEnableUpdateVersionValidation; } + set { _IsEnableUpdateVersionValidation = value; } + } + + + + private bool _IsTranscoding; + public bool IsTranscoding + { + get { return _IsTranscoding; } + set { _IsTranscoding = value; } + } + + private bool _NoSerialize; + public bool NoSerialize + { + get { return _NoSerialize; } + set { _NoSerialize = value; } + } + + private string _SerializeDateTimeFormat; + public string SerializeDateTimeFormat + { + get { return _SerializeDateTimeFormat; } + set { _SerializeDateTimeFormat = value; } + } + + private bool _IsJson; + public bool IsJson + { + get { return _IsJson; } + set { _IsJson = value; } + } + + + private string _DefaultValue; + public string DefaultValue + { + get { return _DefaultValue; } + set { _DefaultValue = value; } + } + + private string[] _IndexGroupNameList; + public string[] IndexGroupNameList + { + get { return _IndexGroupNameList; } + set { _IndexGroupNameList = value; } + } + + public string[] UniqueGroupNameList { get; set; } + + private bool _IsArray; + public bool IsArray + { + get { return _IsArray; } + set { _IsArray = value; } + } + + private bool _IsTreeKey; + public bool IsTreeKey + { + get { return _IsTreeKey; } + set { _IsTreeKey = value; } + } + + public object SqlParameterDbType { get; set; } + public object SqlParameterSize { get; set; } + public int CreateTableFieldSort { get; set; } + public bool InsertServerTime { get; set; } + public string InsertSql { get; set; } + public string QuerySql { get; set; } + public bool UpdateServerTime { get; set; } + public string UpdateSql { get; set; } + public object ExtendedAttribute { get; set; } + public bool IsDisabledAlterColumn { get; set; } + public bool IsOwnsOne { get; set; } + } + + + [AttributeUsage(AttributeTargets.Class, Inherited = true)] + public class TenantAttribute : Attribute + { + public object configId { get; set; } + public TenantAttribute(object configId) + { + this.configId = configId; + } + } + + [AttributeUsage(AttributeTargets.Property, Inherited = true)] + public class Navigate : Attribute + { + internal string Name { get; set; } + internal string Name2 { get; set; } + internal Type MappingType { get; set; } + internal string MappingAId { get; set; } + internal string MappingBId { get; set; } + internal NavigateType NavigatType { get; set; } + internal string WhereSql { get; set; } + internal string AClassId { get; set; } + + internal string BClassId { get; set; } + + public string GetName() + { + return Name; + } + public string GetName2() + { + return Name2; + } + public Type GetMappingType() + { + return MappingType; + } + public string GetMappingAId() + { + return MappingAId; + } + public string GetMappingBId() + { + return MappingBId; + } + public NavigateType GetNavigateType() + { + return NavigatType; + } + + public string GetWhereSql() + { + return WhereSql; + } + public Navigate(NavigateType navigatType, string ifSingleMasterTableColumn_IfListChildTableColumn) + { + this.Name = ifSingleMasterTableColumn_IfListChildTableColumn; + this.NavigatType = navigatType; + } + public Navigate(NavigateType navigatType, string ifSingleMasterTableColumn_IfListChildTableColumn, string ifSingleChildTableColumn_IfListMasterTableColumn) + { + Check.ExceptionEasy(navigatType == NavigateType.ManyToMany, "Correct usage [Navigate(typeof(ABMapping), nameof(abmapping.aid), nameof(abmapp.bid))], incorrect usage: [Navigate(Navigate.ManyToMany, nameof(ABMapping.Aid), nameof(ABMapping.BId))]", "多对多第一个参数是Type不是NavigateType,正确用法[Navigate(typeof(ABMapping), nameof(ABMapping.Aid), nameof(ABMapping.BId))],错误用法:[Navigate(Navigate.ManyToMany, nameof(ABMapping.Aid), nameof(ABMapping.BId))]"); + this.Name = ifSingleMasterTableColumn_IfListChildTableColumn; + this.Name2 = ifSingleChildTableColumn_IfListMasterTableColumn; + this.NavigatType = navigatType; + } + + public Navigate(NavigateType navigatType, string ifSingleMasterTableColumn_IfListChildTableColumn, string ifSingleChildTableColumn_IfListMasterTableColumn, string whereSql) + { + this.Name = ifSingleMasterTableColumn_IfListChildTableColumn; + this.Name2 = ifSingleChildTableColumn_IfListMasterTableColumn; + this.NavigatType = navigatType; + this.WhereSql = whereSql; + //Check.ExceptionEasy(navigatType != NavigateType.OneToOne, "Currently, only one-to-one navigation configuration Sql conditions are supported", "目前导航配置Sql条件只支持一对一"); + } + + public Navigate(Type MappingTableType, string typeAId, string typeBId) + { + this.MappingType = MappingTableType; + this.MappingAId = typeAId; + this.MappingBId = typeBId; + this.NavigatType = NavigateType.ManyToMany; + } + public Navigate(Type MappingTableType, string mappingAId, string mappingBId, string aClassId, string bClassId) + { + this.MappingType = MappingTableType; + this.MappingAId = mappingAId; + this.MappingBId = mappingBId; + this.AClassId = aClassId; + this.BClassId = bClassId; + this.NavigatType = NavigateType.ManyToMany; + } + public Navigate(Type MappingTableType, string typeAiD, string typeBId, string mappingSql) + { + this.MappingType = MappingTableType; + this.MappingAId = typeAiD; + this.MappingBId = typeBId; + this.NavigatType = NavigateType.ManyToMany; + this.WhereSql += mappingSql; + } + } + + + + [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] + public class SugarIndexAttribute : Attribute + { + public string IndexName { get; set; } + public Dictionary IndexFields { get; set; } + public bool IsUnique { get; set; } + public SugarIndexAttribute(string indexName, string fieldName, OrderByType sortType, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName, sortType); + this.IsUnique = isUnique; + + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, string fieldName5, OrderByType sortType5, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + IndexFields.Add(fieldName5, sortType5); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, string fieldName5, OrderByType sortType5, string fieldName6, OrderByType sortType6, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + IndexFields.Add(fieldName5, sortType5); + IndexFields.Add(fieldName6, sortType6); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, string fieldName5, OrderByType sortType5, string fieldName6, OrderByType sortType6, string fieldName7, OrderByType sortType7, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + IndexFields.Add(fieldName5, sortType5); + IndexFields.Add(fieldName6, sortType6); + IndexFields.Add(fieldName7, sortType7); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, string fieldName5, OrderByType sortType5, string fieldName6, OrderByType sortType6, string fieldName7, OrderByType sortType7, string fieldName8, OrderByType sortType8, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + IndexFields.Add(fieldName5, sortType5); + IndexFields.Add(fieldName6, sortType6); + IndexFields.Add(fieldName7, sortType7); + IndexFields.Add(fieldName8, sortType8); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, string fieldName5, OrderByType sortType5, string fieldName6, OrderByType sortType6, string fieldName7, OrderByType sortType7, string fieldName8, OrderByType sortType8, string fieldName9, OrderByType sortType9, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + IndexFields.Add(fieldName5, sortType5); + IndexFields.Add(fieldName6, sortType6); + IndexFields.Add(fieldName7, sortType7); + IndexFields.Add(fieldName8, sortType8); + IndexFields.Add(fieldName9, sortType9); + this.IsUnique = isUnique; + } + public SugarIndexAttribute(string indexName, string fieldName1, OrderByType sortType1, string fieldName2, OrderByType sortType2, string fieldName3, OrderByType sortType3, string fieldName4, OrderByType sortType4, string fieldName5, OrderByType sortType5, string fieldName6, OrderByType sortType6, string fieldName7, OrderByType sortType7, string fieldName8, OrderByType sortType8, string fieldName9, OrderByType sortType9, string fieldName10, OrderByType sortType10, bool isUnique = false) + { + this.IndexName = indexName; + IndexFields = new Dictionary(); + IndexFields.Add(fieldName1, sortType1); + IndexFields.Add(fieldName2, sortType2); + IndexFields.Add(fieldName3, sortType3); + IndexFields.Add(fieldName4, sortType4); + IndexFields.Add(fieldName5, sortType5); + IndexFields.Add(fieldName6, sortType6); + IndexFields.Add(fieldName7, sortType7); + IndexFields.Add(fieldName8, sortType8); + IndexFields.Add(fieldName9, sortType9); + IndexFields.Add(fieldName10, sortType10); + this.IsUnique = isUnique; + } + + public SugarIndexAttribute(string indexName, string[] fieldNames, OrderByType[] sortTypes, bool isUnique = false) + { + if (fieldNames.Length != sortTypes.Length) + { + Check.ExceptionEasy($"SugarIndexAttribute {indexName} fieldNames.Length!=sortTypes.Length 检查索引特性", $"SugarIndexAttribute {indexName} fieldNames.Length!=sortTypes.Length"); + } + this.IndexName = indexName; + IndexFields = new Dictionary(); + for (int i = 0; i < fieldNames.Length; i++) + { + IndexFields.Add(fieldNames[i], sortTypes[i]); + } + this.IsUnique = isUnique; + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ModelContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ModelContext.cs new file mode 100644 index 000000000..616602369 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/ModelContext.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; + +namespace SqlSugar +{ + public class ModelContext + { + [SugarColumn(IsIgnore = true)] + [JsonIgnore] + public SqlSugarProvider Context { get; set; } + public ISugarQueryable CreateMapping() where T : class, new() + { + Check.ArgumentNullException(Context, "Please use Sqlugar.ModelContext"); + using (Context) + { + return Context.Queryable(); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/NavigationInitializer.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/NavigationInitializer.cs new file mode 100644 index 000000000..63b2576c9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/NavigationInitializer.cs @@ -0,0 +1,54 @@ +namespace SqlSugar +{ + internal static class OneToOneGlobalInstanceRegistry + { + private static readonly Dictionary _instances = new Dictionary(); + private static readonly object _lock = new object(); + + public static Dictionary Instances => _instances; + + public static bool IsAny() + { + return _instances?.Count > 0; + } + public static bool IsNavigationInitializerCreated(object instance) + { + if (instance == null) + return false; + + Type type = instance.GetType(); + + lock (_lock) + { + return _instances.ContainsKey(type) && _instances[type] == instance; + } + } + + public static void RegisterInstance(Type type, object instance) + { + lock (_lock) + { + if (!_instances.ContainsKey(type)) + { + _instances[type] = instance; + } + } + } + } + + public class OneToOneInitializer where T : new() + { + public static implicit operator T(OneToOneInitializer initializer) + { + Type type = typeof(T); + + if (!OneToOneGlobalInstanceRegistry.Instances.ContainsKey(type)) + { + T instance = new T(); + OneToOneGlobalInstanceRegistry.RegisterInstance(type, instance); + } + + return (T)OneToOneGlobalInstanceRegistry.Instances[type]; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/PageModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/PageModel.cs new file mode 100644 index 000000000..b6e229fd2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/PageModel.cs @@ -0,0 +1,12 @@ +namespace SqlSugar +{ + public class PageModel + { + public int PageIndex { get; set; } + public int PageSize { get; set; } + /// + /// output + /// + public int TotalCount { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/PropertyMetadata.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/PropertyMetadata.cs new file mode 100644 index 000000000..bde1f3dc3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/PropertyMetadata.cs @@ -0,0 +1,11 @@ +using System.Reflection.Emit; + +namespace SqlSugar +{ + public class PropertyMetadata + { + public string Name { get; set; } + public Type Type { get; set; } + public List CustomAttributes { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/QueueItem.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/QueueItem.cs new file mode 100644 index 000000000..8332deb14 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/QueueItem.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class QueueItem + { + public string Sql { get; set; } + public SugarParameter[] Parameters { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SchemaInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SchemaInfo.cs new file mode 100644 index 000000000..1b0939c4c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SchemaInfo.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class SchemaInfo + { + public string TableName { get; set; } + public string SchemaName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SingleColumnsEntity.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SingleColumnsEntity.cs new file mode 100644 index 000000000..a680b77a4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SingleColumnsEntity.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class SingleColumnEntity + { + public T ColumnName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SlaveConnectionConfig.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SlaveConnectionConfig.cs new file mode 100644 index 000000000..c11e984d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SlaveConnectionConfig.cs @@ -0,0 +1,12 @@ +namespace SqlSugar +{ + public class SlaveConnectionConfig + { + /// + ///Default value is 1 + ///If value is 0 means permanent non execution + /// + public int HitRate = 1; + public string ConnectionString { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlFilter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlFilter.cs new file mode 100644 index 000000000..5b0acdbdd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlFilter.cs @@ -0,0 +1,53 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SqlFilterItem + { + /// + /// Equal to NULL representing global + /// + public string FilterName { get; set; } + public Func FilterValue { get; set; } + /// + /// Is it a multiple table query? + /// + public bool IsJoinQuery { get; set; } + internal Type type { get; set; } + } + + public class TableFilterItem : SqlFilterItem + { + private TableFilterItem() + { + + } + private Expression exp { get; set; } + public TableFilterItem(Expression> expression, bool isJoinOn = false) + { + exp = expression; + type = typeof(T); + base.IsJoinQuery = isJoinOn; + this.IsJoinQuery = isJoinOn; + } + + public TableFilterItem(Type entityType, Expression expression, bool isJoinOn = false) + { + exp = expression; + type = entityType; + base.IsJoinQuery = isJoinOn; + this.IsJoinQuery = isJoinOn; + } + + private new string FilterName { get; set; } + private new Func FilterValue { get; set; } + private new bool IsJoinQuery { get; set; } + } + + + public class SqlFilterResult + { + public string Sql { get; set; } + public object Parameters { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlSguarTransaction.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlSguarTransaction.cs new file mode 100644 index 000000000..a02d138d5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlSguarTransaction.cs @@ -0,0 +1,47 @@ +namespace SqlSugar +{ + public class SqlSugarTransaction : IDisposable + { + private readonly SqlSugarClient context; + + public SqlSugarTransaction(SqlSugarClient client) + { + context = client; + context.BeginTran(); + } + public void CommitTran() + { + context.CommitTran(); + } + public void RollbackTran() + { + context.RollbackTran(); + } + public void Dispose() + { + context.RollbackTran(); + } + } + public class SqlSugarTransactionAdo : IDisposable + { + private readonly ISqlSugarClient context; + + public SqlSugarTransactionAdo(ISqlSugarClient client) + { + context = client; + context.Ado.BeginTran(); + } + public void CommitTran() + { + context.Ado.CommitTran(); + } + public void RollbackTran() + { + context.Ado.RollbackTran(); + } + public void Dispose() + { + context.Ado.RollbackTran(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlWith.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlWith.cs new file mode 100644 index 000000000..35c97cf7f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SqlWith.cs @@ -0,0 +1,15 @@ +namespace SqlSugar +{ + public partial class SqlWith + { + public const string NoLock = "WITH(NOLOCK) "; + public const string HoldLock = "WITH(HOLDLOCK)"; + public const string PagLock = "WITH(PAGLOCK)"; + public const string ReadCommitted = "WITH(READCOMMITTED)"; + public const string TabLockX = "WITH(TABLOCKX)"; + public const string UpdLock = "WITH(UPDLOCK)"; + public const string RowLock = "WITH(ROWLOCK)"; + public const string ReadPast = "WITH(READPAST)"; + public const string Null = "Non"; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/StackTraceInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/StackTraceInfo.cs new file mode 100644 index 000000000..33c6a9399 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/StackTraceInfo.cs @@ -0,0 +1,18 @@ +namespace SqlSugar +{ + public class StackTraceInfo + { + public string FirstFileName { get { return this.MyStackTraceList.First().FileName; } } + public string FirstMethodName { get { return this.MyStackTraceList.First().MethodName; } } + public int FirstLine { get { return this.MyStackTraceList.First().Line; } } + + public List MyStackTraceList { get; set; } + public List SugarStackTraceList { get; set; } + } + public class StackTraceInfoItem + { + public string FileName { get; set; } + public string MethodName { get; set; } + public int Line { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SubInsertTree.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SubInsertTree.cs new file mode 100644 index 000000000..1b7299040 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SubInsertTree.cs @@ -0,0 +1,16 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubInsertTree + { + public object Expression { get; set; } + public List ChildExpression { get; set; } + } + + internal class SubInsertTreeExpression + { + public Expression Expression { get; set; } + public List Childs { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarAbMapping.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarAbMapping.cs new file mode 100644 index 000000000..9f0bbb5d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarAbMapping.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class SugarAbMapping + { + public string Aid { get; set; } + public string Bid { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarConnection.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarConnection.cs new file mode 100644 index 000000000..67b154202 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarConnection.cs @@ -0,0 +1,17 @@ +using System.Data; + +namespace SqlSugar +{ + public class SugarConnection : IDisposable + { + public IDbConnection conn { get; set; } + public bool IsAutoClose { get; set; } + public ISqlSugarClient Context { get; set; } + + public void Dispose() + { + conn.Close(); + this.Context.CurrentConnectionConfig.IsAutoCloseConnection = IsAutoClose; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarDebugger.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarDebugger.cs new file mode 100644 index 000000000..73ddd29db --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarDebugger.cs @@ -0,0 +1,13 @@ +namespace SqlSugar +{ + /// + /// Used for debugging errors or BUG,Used for debugging, which has an impact on Performance + /// + public class SugarDebugger + { + /// + /// If you use the same Db object across threads, you will be prompted + /// + public bool EnableThreadSecurityValidation { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarList.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarList.cs new file mode 100644 index 000000000..4c0528f34 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarList.cs @@ -0,0 +1,66 @@ +namespace SqlSugar +{ + public class MappingTableList : List + { + public void Add(string entityName, string dbTableName) + { + this.RemoveAll(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + this.Add(new MappingTable() { EntityName = entityName, DbTableName = dbTableName }); + } + public void Add(string entityName, string dbTableName, string dbTableShortName) + { + this.RemoveAll(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + this.Add(new MappingTable() { EntityName = entityName, DbTableName = dbTableName, DbShortTaleName = dbTableShortName }); + } + public new void Clear() + { + this.RemoveAll(it => true); + } + } + + public class IgnoreColumnList : List + { + public void Add(string propertyName, string EntityName) + { + this.RemoveAll(it => it.EntityName == EntityName && it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + this.Add(new IgnoreColumn() { PropertyName = propertyName, EntityName = EntityName }); + } + + public new void Clear() + { + this.RemoveAll(it => true); + } + } + + public class MappingColumnList : List + { + public void Add(string propertyName, string dbColumnName, string entityName) + { + this.RemoveAll(it => it.EntityName == entityName && it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + this.Add(new MappingColumn() { PropertyName = propertyName, DbColumnName = dbColumnName, EntityName = entityName }); + } + public new void Clear() + { + this.RemoveAll(it => true); + } + } + + + public class QueueList : List + { + public void Add(string sql, SugarParameter[] parameters) + { + this.Add(new QueueItem() { Sql = sql, Parameters = parameters }); + } + public void Add(string sql, List parameters) + { + if (parameters == null) + parameters = new List(); + this.Add(new QueueItem() { Sql = sql, Parameters = parameters.ToArray() }); + } + public new void Clear() + { + this.RemoveAll(it => true); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarTerant.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarTerant.cs new file mode 100644 index 000000000..2148b8b24 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Entities/SugarTerant.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class SugarTenant + { + public SqlSugarProvider Context { get; set; } + public ConnectionConfig ConnectionConfig { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ApplyType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ApplyType.cs new file mode 100644 index 000000000..a7229f2cd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ApplyType.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public enum ApplyType + { + Cross = 1, + Outer = 2 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ConditionalType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ConditionalType.cs new file mode 100644 index 000000000..0849f277d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ConditionalType.cs @@ -0,0 +1,23 @@ +namespace SqlSugar +{ + public enum ConditionalType + { + Equal = 0, + Like = 1, + GreaterThan = 2, + GreaterThanOrEqual = 3, + LessThan = 4, + LessThanOrEqual = 5, + In = 6, + NotIn = 7, + LikeLeft = 8, + LikeRight = 9, + NoEqual = 10, + IsNullOrEmpty = 11, + IsNot = 12, + NoLike = 13, + EqualNull = 14, + InLike = 15, + Range = 16 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DataFilterType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DataFilterType.cs new file mode 100644 index 000000000..6aafbcd22 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DataFilterType.cs @@ -0,0 +1,64 @@ +using System.Reflection; + +namespace SqlSugar +{ + public enum DataFilterType + { + UpdateByObject = 0, + InsertByObject = 1, + DeleteByObject = 2 + } + public class DataFilterModel + { + public DataFilterType OperationType { get; set; } + public EntityColumnInfo EntityColumnInfo { get; set; } + public object EntityValue { get; set; } + public string PropertyName { get { return EntityColumnInfo.PropertyInfo.Name; } } + public string EntityName { get { return EntityColumnInfo.EntityName; } } + + + public void SetValue(object value) + { + try + { + var type = EntityColumnInfo.PropertyInfo.PropertyType; + if (value != null && value.GetType() != type) + { + value = UtilMethods.ChangeType2(value, type); + } + this.EntityColumnInfo.PropertyInfo.SetValue(EntityValue, value); + } + catch (Exception ex) + { + Check.ExceptionEasy($" SetValue error in DataExecuting {EntityName} . {ex.Message}", $" DataExecuting 中 SetValue出错 {EntityName} 。 {ex.Message}"); + } + } + public bool IsAnyAttribute() where T : Attribute + { + return this.EntityColumnInfo.PropertyInfo.GetCustomAttribute() != null; + } + public T GetAttribute() where T : Attribute + { + return this.EntityColumnInfo.PropertyInfo.GetCustomAttribute(); + } + } + public class DataAfterModel + { + + public List EntityColumnInfos { get; set; } + public object EntityValue { get; set; } + public EntityInfo Entity { get; set; } + public object GetValue(string propertyName) + { + var propety = EntityColumnInfos.FirstOrDefault(it => it.PropertyName == propertyName); + Check.ExceptionEasy(propety == null, $"Aop.DataExecuted error . {Entity.EntityName} no property {propertyName}.", $"Aop.DataExecuted 出错 {Entity.EntityName}不存在属性{propertyName}"); + return propety.PropertyInfo.GetValue(EntityValue); + } + public void SetValue(string propertyName, object value) + { + var propety = EntityColumnInfos.FirstOrDefault(it => it.PropertyName == propertyName); + Check.ExceptionEasy(propety == null, $"Aop.DataExecuted error . {Entity.EntityName} no property {propertyName}.", $"Aop.DataExecuted 出错 {Entity.EntityName}不存在属性{propertyName}"); + propety.PropertyInfo.SetValue(EntityValue, value); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbLockType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbLockType.cs new file mode 100644 index 000000000..ad52e80d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbLockType.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public enum DbLockType + { + Wait = 0, + Error = 1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbObjectType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbObjectType.cs new file mode 100644 index 000000000..bd9f01148 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbObjectType.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public enum DbObjectType + { + Table = 0, + View = 1, + All = 2 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbType.cs new file mode 100644 index 000000000..7d93449a9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/DbType.cs @@ -0,0 +1,40 @@ +namespace SqlSugar +{ + public enum DbType + { + MySql, + SqlServer, + Sqlite, + Oracle, + PostgreSQL, + Dm, + Kdbndp, + Oscar, + MySqlConnector, + Access, + OpenGauss, + QuestDB, + HG, + ClickHouse, + GBase, + Odbc, + OceanBaseForOracle, + TDengine, + GaussDB, + OceanBase, + Tidb, + Vastbase, + PolarDB, + Doris, + Xugu, + GoldenDB, + TDSQLForPGODBC, + TDSQL, + HANA, + DB2, + GaussDBNative, + DuckDB, + MongoDb, + Custom = 900 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/InitKeyType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/InitKeyType.cs new file mode 100644 index 000000000..a94517b0d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/InitKeyType.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public enum InitKeyType + { + /// + /// Init primary key and identity key from the attribute + /// + Attribute = 1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/JoinType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/JoinType.cs new file mode 100644 index 000000000..b454611d2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/JoinType.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + public enum JoinType + { + Inner = 0, + Left = 1, + Right = 2, + Full = 3, + Cross + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/LanguageType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/LanguageType.cs new file mode 100644 index 000000000..621f85a9e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/LanguageType.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public enum LanguageType + { + Default = 0, + Chinese = 1, + English = 2 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/NavigatType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/NavigatType.cs new file mode 100644 index 000000000..a46c01117 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/NavigatType.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + public enum NavigateType + { + OneToOne = 1, + OneToMany = 2, + ManyToOne = 3, + ManyToMany = 4, + Dynamic = 5 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/OrderByType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/OrderByType.cs new file mode 100644 index 000000000..8c18840b1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/OrderByType.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public enum OrderByType + { + Asc = 0, + Desc = 1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ProperyType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ProperyType.cs new file mode 100644 index 000000000..8034eb13d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ProperyType.cs @@ -0,0 +1,27 @@ +namespace SqlSugar +{ + public enum CSharpDataType + { + @int, + @bool, + @string, + @DateTime, + @decimal, + @double, + @Guid, + @byte, + @sbyte, + @enum, + @short, + @long, + @object, + @other, + @byteArray, + @float, + @time, + @DateTimeOffset, + @Single, + @TimeSpan, + @char + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ReportableDateType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ReportableDateType.cs new file mode 100644 index 000000000..9e1f89100 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/ReportableDateType.cs @@ -0,0 +1,12 @@ +namespace SqlSugar +{ + public enum ReportableDateType + { + MonthsInLast1years = 0, + MonthsInLast3years = 1, + MonthsInLast10years = 2, + years1 = 3, + years3 = 4, + years10 = 5 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SampleByUnit.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SampleByUnit.cs new file mode 100644 index 000000000..65f7bda33 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SampleByUnit.cs @@ -0,0 +1,14 @@ +namespace SqlSugar +{ + public enum SampleByUnit + { + Second, + Minute, + Hour, + Day, + Month, + Year, + Millisecond, + Microsecond, + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SugarActionType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SugarActionType.cs new file mode 100644 index 000000000..b7c3826b7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SugarActionType.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + public enum SugarActionType + { + Insert = 0, + Update = 1, + Delete = 2, + Query = 3, + UnKnown = -1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SugarDateTimeFormat.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SugarDateTimeFormat.cs new file mode 100644 index 000000000..71447e8be --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/SugarDateTimeFormat.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public partial class SugarDateTimeFormat + { + public const string Default = "yyyy-MM-dd HH:mm:ss"; + public const string Date = "yyyy-MM-dd HH"; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/WhereType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/WhereType.cs new file mode 100644 index 000000000..61454536c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Enum/WhereType.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public enum WhereType + { + And = 0, + Or = 1, + Null = -1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/CaseWhen/CaseWhen.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/CaseWhen/CaseWhen.cs new file mode 100644 index 000000000..c0cde3176 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/CaseWhen/CaseWhen.cs @@ -0,0 +1,26 @@ +namespace SqlSugar +{ + public class CaseWhen + { + public CaseThen ElseIF(bool condition) + { + return null; + } + public T End(T defaultValue) + { + return default(T); + } + public T End() + { + return default(T); + } + } + public class CaseThen + { + + public CaseWhen Return(T result) + { + return null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/CaseWhen/CaseWhenResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/CaseWhen/CaseWhenResolve.cs new file mode 100644 index 000000000..3e742c2d7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/CaseWhen/CaseWhenResolve.cs @@ -0,0 +1,89 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + + public class CaseWhenResolve + { + List allMethods = new List(); + private ExpressionContext context = null; + public CaseWhenResolve(MethodCallExpression expression, ExpressionContext context, Expression oppsiteExpression) + { + this.context = context; + var currentExpression = expression; + allMethods.Add(currentExpression); + if (context.IsSingle && oppsiteExpression != null && oppsiteExpression is MemberExpression) + { + var childExpression = (oppsiteExpression as MemberExpression).Expression; + if (childExpression is ParameterExpression) + { + this.context.SingleTableNameSubqueryShortName = (childExpression as ParameterExpression).Name; + } + } + else if (context.IsSingle) + { + if (context.Expression is LambdaExpression) + { + this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name; + } + } + while (currentExpression != null) + { + var addItem = currentExpression.Object as MethodCallExpression; + if (addItem != null) + allMethods.Add(addItem); + currentExpression = addItem; + } + } + + public string GetSql() + { + allMethods.Reverse(); + List> sqls = new List>(); + foreach (var methodExp in allMethods) + { + var isFirst = allMethods.First() == methodExp; + var isLast = allMethods.Last() == methodExp; + var isIsNegate = false; + if (methodExp.Arguments.Count == 0) + { + sqls.Add(new KeyValuePair(methodExp.Method.Name, "null")); + } + else + { + var exp = methodExp.Arguments[0]; + if (ExpressionTool.IsNegate(exp)) + { + isIsNegate = true; + exp = (exp as UnaryExpression).Operand; + } + if (methodExp.Method.Name.IsIn("Return", "End") && exp.Type == UtilConstants.BoolType && ExpressionTool.IsEqualOrLtOrGt(exp)) + { + exp = ExpressionTool.GetConditionalExpression(exp); + } + else if (methodExp.Method.Name.IsIn("Return", "End") && exp.Type == UtilConstants.BoolType && ExpressionTool.GetMethodName(exp).IsIn("Contains", "StartsWith", "EndsWith")) + { + exp = ExpressionTool.GetConditionalExpression(exp); + } + var sql = SubTools.GetMethodValue(this.context, exp, this.context.IsSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); + if (methodExp.Method.Name == "IF") + { + var parameter = this.context.Parameters.FirstOrDefault(it => it.ParameterName == sql.Trim()); + if (parameter?.Value is bool) + { + sql = Convert.ToBoolean(parameter.Value) ? " 1=1 " : " 1=2 "; + this.context.Parameters.Remove(parameter); + } + } + if (isIsNegate) + { + sql = " (" + sql + "*-1) "; + } + sqls.Add(new KeyValuePair(methodExp.Method.Name, sql)); + } + } + var result = this.context.DbMehtods.CaseWhen(sqls); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/BinaryExpressionInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/BinaryExpressionInfo.cs new file mode 100644 index 000000000..68782f5cd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/BinaryExpressionInfo.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public class BinaryExpressionInfo + { + public bool IsLeft { get; set; } + public Type ExpressionType { get; set; } + public object Value { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/CommonTempDataType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/CommonTempDataType.cs new file mode 100644 index 000000000..1578d090a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/CommonTempDataType.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public enum CommonTempDataType + { + Default = 0, + Result = 1, + Append = 2, + Simple = 3 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/DateType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/DateType.cs new file mode 100644 index 000000000..e5f37d885 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/DateType.cs @@ -0,0 +1,15 @@ +namespace SqlSugar +{ + public enum DateType + { + Year = 1, + Month = 2, + Day = 3, + Hour = 4, + Second = 5, + Minute = 6, + Millisecond = 7, + Weekday = 8, + Quarter = 9 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ErrorMessage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ErrorMessage.cs new file mode 100644 index 000000000..68d9a0840 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ErrorMessage.cs @@ -0,0 +1,51 @@ +namespace SqlSugar +{ + internal static partial class ErrorMessage + { + internal static string OperatorError + { + get + { + return ErrorMessage.GetThrowMessage("Lambda parsing error: {0} does not support the operator to find!", "拉姆达解析出错:不支持{0}此种运算符查找!"); + } + } + internal static string ExpFileldError + { + get + { + return ErrorMessage.GetThrowMessage("Expression format error, correct format: it=>it.fieldName", "表达式格式错误,正确格式: it=>it.fieldName"); + } + } + + internal static string MethodError + { + get + { + return ErrorMessage.GetThrowMessage("Expression parsing does not support the current function {0}. There are many functions available in the SqlFunc class, for example, it=>SqlFunc.HasValue(it.Id)", "拉姆达解析不支持当前函数{0},SqlFunc这个类里面有大量函数可用,也许有你想要的,例如: it=>SqlFunc.HasValue(it.Id)"); + } + } + + public static string ConnnectionOpen + { + get + { + return ErrorMessage.GetThrowMessage("Connection open error . {0} ", " 连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:{0}."); + } + } + public static string ExpressionCheck + { + get + { + return ErrorMessage.GetThrowMessage("Join {0} needs to be the same as {1} {2}", "多表查询存在别名不一致,请把{1}中的{2}改成{0}就可以了,特殊需求可以使用.Select((x,y)=>new{{ id=x.id,name=y.name}}).MergeTable().Orderby(xxx=>xxx.Id)功能将Select中的多表结果集变成单表,这样就可以不限制别名一样"); + } + } + + public static string WhereIFCheck + { + get + { + return ErrorMessage.GetThrowMessage("Subquery.WhereIF.IsWhere {0} not supported", "Subquery.WhereIF 第一个参数不支持表达式中的变量,只支持外部变量"); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpResolveAccessory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpResolveAccessory.cs new file mode 100644 index 000000000..703747702 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpResolveAccessory.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class ExpResolveAccessory + { + protected List _Parameters; + protected ExpressionResult _Result; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionConst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionConst.cs new file mode 100644 index 000000000..e6e7e28c6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionConst.cs @@ -0,0 +1,14 @@ +namespace SqlSugar +{ + internal static class ExpressionConst + { + public const string Const = "Const"; + public const string FormatSymbol = "{0}"; + public const string RightParenthesis = ")"; + public const string LeftParenthesis = "("; + public const string MethodConst = "MethodConst"; + public const string SqlFuncFullName = "SqlSugar.SqlFunc"; + public const string BinaryFormatString = " ( {0} {1} {2} ) "; + public const string ExpressionReplace = "46450BDC-77B7-4025-B2A6-3F048CA85AD0"; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionContextCase.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionContextCase.cs new file mode 100644 index 000000000..0307b525f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionContextCase.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class ExpressionContextCase + { + public bool IsDateString { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionItems.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionItems.cs new file mode 100644 index 000000000..23d10bb50 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionItems.cs @@ -0,0 +1,29 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class ExpressionItems + { + /// + /// 1 memeber, 2 class ,3 method + /// + public int Type { get; set; } + public EntityInfo ParentEntityInfo { get; set; } + public EntityInfo ThisEntityInfo { get; set; } + public Expression Expression { get; set; } + public Navigate Nav + { + get + { + if (Expression is MemberExpression) + { + var name = (Expression as MemberExpression).Member.Name; + var navColumn = ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == name); + return navColumn == null ? null : navColumn.Navigat; + } + return null; + } + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionOutParameter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionOutParameter.cs new file mode 100644 index 000000000..7e5cb748e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionOutParameter.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class ExpressionOutParameter + { + public SqlSugarProvider Context { get; set; } + public QueryBuilder QueryBuilder { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionParameter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionParameter.cs new file mode 100644 index 000000000..503cda9b1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionParameter.cs @@ -0,0 +1,42 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class ExpressionParameter + { + public ExpressionContext Context { get; set; } + public ExpressionParameter BaseParameter { get; set; } + public Expression BaseExpression { get; set; } + public Expression ChildExpression { get; set; } + public Expression LeftExpression { get; set; } + public Expression RightExpression { get; set; } + public Expression CurrentExpression { get; set; } + public string OperatorValue { get; set; } + public bool? IsLeft { get; set; } + public int Index { get; set; } + public bool ValueIsNull { get; set; } + public object CommonTempData { get; set; } + public ExpressionResultAppendType AppendType { get; set; } + public void IsAppendResult() + { + this.AppendType = ExpressionResultAppendType.AppendResult; + } + public void IsAppendTempDate() + { + this.AppendType = ExpressionResultAppendType.AppendTempDate; + } + public Expression OppsiteExpression + { + get + { + return this.IsLeft == true ? this.BaseParameter.RightExpression : this.BaseParameter.LeftExpression; + } + } + public bool IsSetTempData + { + get + { + return BaseParameter.CommonTempData.HasValue() && BaseParameter.CommonTempData.Equals(CommonTempDataType.Result); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionResult.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionResult.cs new file mode 100644 index 000000000..246d530c0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionResult.cs @@ -0,0 +1,191 @@ +using System.Text; +namespace SqlSugar +{ + public class ExpressionResult + { + public bool IsLockCurrentParameter { get; set; } + public bool IsUpper { get; set; } + public bool IsNavicate { get; set; } + private ExpressionParameter _CurrentParameter; + public ExpressionParameter CurrentParameter + { + get + { + return this._CurrentParameter; + } + set + { + Check.Exception(value != null && IsLockCurrentParameter, "CurrentParameter is locked."); + this._CurrentParameter = value; + this.IsLockCurrentParameter = false; + } + } + #region constructor + private ExpressionResult() + { + } + public ExpressionResult(ResolveExpressType resolveExpressType) + { + this._ResolveExpressType = resolveExpressType; + } + #endregion + + #region Fields + private ResolveExpressType _ResolveExpressType; + private StringBuilder _Result; + #endregion + + #region properties + private StringBuilder Result + { + get + { + if (_Result == null) _Result = new StringBuilder(); + return _Result; + } + + set + { + _Result = value; + } + } + public bool LastCharIsSpace + { + get + { + if (_Result == null || _Result.Length == 0) return true; + return _Result.ToString().Last() == UtilConstants.SpaceChar; + } + } + #endregion + public string GetString() + { + if (_Result == null) return null; + if (IsUpper) + return _Result.ToString().ToUpper().Replace(UtilConstants.ReplaceCommaKey, ",").TrimEnd(','); + else + return _Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ",").TrimEnd(','); + } + #region functions + public string[] GetResultArray() + { + if (this._Result == null) return null; + var reslut = new List(); + + if (IsUpper) + reslut = this.Result.ToString().ToUpper().TrimEnd(',').Split(',').ToList(); + else + reslut = this.Result.ToString().TrimEnd(',').Split(',').ToList(); + + if (this.Result.ToString().Contains(UtilConstants.ReplaceCommaKey)) + { + for (int i = 0; i < reslut.Count; i++) + { + reslut[i] = reslut[i].Replace(UtilConstants.ReplaceCommaKey, ","); + } + } + return reslut.ToArray(); + } + + public string GetResultString() + { + if (this._Result == null) return null; + if (this._ResolveExpressType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle)) + { + return this.Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ",").TrimEnd(','); + } + if (IsUpper) + return this.Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ",").ToUpper(); + else + return this.Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ","); + } + + public void TrimEnd() + { + if (this._Result == null) return; + this.Result = this.Result.Remove(this.Result.Length - 1, 1); + } + + public bool Contains(string value) + { + if (this.Result.Equals(value)) return true; + return (Result.ToString().Contains(value?.ToLower(), StringComparison.CurrentCultureIgnoreCase)); + } + + internal void Insert(int index, string value) + { + if (this.Result == null) this.Result.Append(value); + this.Result.Insert(index, value); + } + + public void Append(object parameter) + { + if (this.CurrentParameter.HasValue() && this.CurrentParameter.AppendType.IsIn(ExpressionResultAppendType.AppendTempDate)) + { + this.CurrentParameter.CommonTempData = parameter; + return; + } + switch (this._ResolveExpressType) + { + case ResolveExpressType.ArraySingle: + case ResolveExpressType.ArrayMultiple: + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + parameter = parameter + ","; + break; + case ResolveExpressType.WhereSingle: + break; + case ResolveExpressType.WhereMultiple: + break; + case ResolveExpressType.FieldSingle: + break; + case ResolveExpressType.FieldMultiple: + break; + default: + break; + } + if (this.Result.Length > 0 && this.Result[this.Result.Length - 1] == ',') + { + if (parameter?.ToString()?.StartsWith(" AS ") == true && parameter?.ToString()?.EndsWith(" ,") == true) + { + this.Result.Length--; // 直接删掉最后一个字符 + } + } + this.Result.Append(parameter); + } + + public void AppendFormat(string parameter, params object[] orgs) + { + if (this.CurrentParameter.HasValue() && this.CurrentParameter.AppendType.IsIn(ExpressionResultAppendType.AppendTempDate)) + { + this.CurrentParameter.CommonTempData = new KeyValuePair(parameter, orgs); + return; + } + switch (this._ResolveExpressType) + { + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + parameter = parameter + ","; + break; + case ResolveExpressType.WhereSingle: + break; + case ResolveExpressType.WhereMultiple: + break; + case ResolveExpressType.FieldSingle: + break; + case ResolveExpressType.FieldMultiple: + break; + default: + break; + } + this.Result.AppendFormat(parameter, orgs); + } + + public void Replace(string parameter, string newValue) + { + this.Result.Replace(parameter, newValue); + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionResultAcceptType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionResultAcceptType.cs new file mode 100644 index 000000000..f372f0d8b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionResultAcceptType.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public enum ExpressionResultAppendType + { + AppendResult = 0, + AppendTempDate = 1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionTool.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionTool.cs new file mode 100644 index 000000000..52db6f3d9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ExpressionTool.cs @@ -0,0 +1,1100 @@ +using System.Collections.ObjectModel; +using System.Linq.Expressions; +using System.Reflection; +namespace SqlSugar +{ + public static class ExpressionTool + { + public static bool ContainsTwoLevelAccess(Expression exp) + { + var result = false; + + if (exp is LambdaExpression lambda && + lambda.Body is MemberInitExpression initExpr) + { + var param = lambda.Parameters[0]; + + foreach (var binding in initExpr.Bindings) + { + if (binding is MemberAssignment assign) + { + if (assign.Expression is MemberExpression outer && + outer.Expression is MemberExpression inner && + inner.Expression == param) + { + result = true; + break; // 已经找到了,就退出循环 + } + } + } + } + + return result; + } + + public static string GetMemberNameByMethod(Expression expression, string name) + { + if (expression is LambdaExpression lambda) + { + if (lambda.Body is MethodCallExpression method) + { + if (method.Method.Name == "ToList") + { + var arg = method.Arguments.FirstOrDefault(); + if (arg != null) + { + if (arg is MemberExpression member) + { + name = member.Member.Name; + } + } + } + } + } + + return name; + } + + internal static string ResolveMemberValue(ExpressionContext context, Expression item, string value) + { + if (item is MemberExpression member) + { + if (member.Expression is ParameterExpression parameterExpression) + { + if (value?.Contains('(') == true && !value.Contains(' ')) + { + var guid = Guid.NewGuid() + ""; + var guid2 = Guid.NewGuid() + ""; + value = value.Replace("(", guid).Replace(")", guid2); + value = context.GetTranslationColumnName(value); + value = value.Replace(guid, "(").Replace(guid2, ")"); + } + } + } + return value; + } + internal static Expression GetConditionalExpression(Expression item) + { + ConstantExpression trueConstant = Expression.Constant(true, typeof(bool)); + ConstantExpression falseConstant = Expression.Constant(false, typeof(bool)); + + // 创建条件表达式:item ? true : false + Expression conditionalExpression = Expression.Condition( + test: item, + ifTrue: trueConstant, + ifFalse: falseConstant + ); + return conditionalExpression; + } + internal static bool IsOwnsOne(ExpressionContext context, Expression member) + { + var isOwnsOne = false; + if (context?.SugarContext?.Context == null) + { + return false; + } + if (member is MemberExpression memberExp) + { + var name = memberExp?.Member?.Name; + if (memberExp?.Expression is MemberExpression parentMemberExp) + { + if (name != null && parentMemberExp?.Expression is ParameterExpression rootExp) + { + var entityInfo = context?.SugarContext?.Context?.EntityMaintenance?.GetEntityInfo(rootExp.Type); + var navColumn = entityInfo?.Columns?.FirstOrDefault(it => it.PropertyName == name); + isOwnsOne = navColumn?.ForOwnsOnePropertyInfo != null; + } + } + } + return isOwnsOne; + } + internal static EntityColumnInfo GetOwnsOneColumnInfo(ExpressionContext context, Expression member) + { + EntityColumnInfo entityColumnInfo = new EntityColumnInfo(); + if (member is MemberExpression memberExp) + { + var name = memberExp?.Member?.Name; + if (memberExp.Expression is MemberExpression parentMemberExp) + { + if (name != null && parentMemberExp.Expression is ParameterExpression) + { + var rootExp = (parentMemberExp.Expression as ParameterExpression); + var entityInfo = context?.SugarContext?.Context?.EntityMaintenance?.GetEntityInfo(rootExp.Type); + var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == name); + entityColumnInfo = navColumn; + } + } + } + return entityColumnInfo; + } + + internal static bool IsNavMember(ExpressionContext context, Expression member) + { + var isNav = false; + if (member is MemberExpression && (member as MemberExpression)?.Type?.IsClass() == true) + { + var memberExp = (member as MemberExpression); + var name = memberExp?.Member?.Name; + var type = memberExp?.Type; + if (name != null && type != null && memberExp.Expression is ParameterExpression) + { + var rootExp = (memberExp.Expression as ParameterExpression); + var entityInfo = context?.SugarContext?.Context?.EntityMaintenance?.GetEntityInfo(rootExp.Type); + var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == name); + isNav = navColumn?.Navigat != null; + } + } + return isNav; + } + internal static bool IsNavMember(ISqlSugarClient context, Expression member) + { + var isNav = false; + if (member is MemberExpression && (member as MemberExpression)?.Type?.IsClass() == true) + { + var memberExp = (member as MemberExpression); + var name = memberExp?.Member?.Name; + var type = memberExp?.Type; + if (name != null && type != null && memberExp.Expression is ParameterExpression) + { + var rootExp = (memberExp.Expression as ParameterExpression); + var entityInfo = context?.EntityMaintenance?.GetEntityInfo(rootExp.Type); + var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == name); + isNav = navColumn?.Navigat != null; + } + else if (name != null && type != null && memberExp.Expression is MemberExpression) + { + var rootExp = (memberExp.Expression as MemberExpression); + if (rootExp.Type.IsClass() && type.IsArray == false && type.FullName.IsCollectionsList() == false) + { + var entityInfo = context?.EntityMaintenance?.GetEntityInfo(rootExp.Type); + var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == name); + isNav = navColumn?.Navigat != null; + } + } + } + return isNav; + } + + internal static bool IsSqlParameterDbType(ExpressionContext context, Expression member) + { + var isNav = false; + if (context?.SugarContext != null && member is MemberExpression && (member as MemberExpression)?.Expression is ParameterExpression expression) + { + if (expression != null) + { + var typeEntity = context?.SugarContext.Context.EntityMaintenance.GetEntityInfo(expression.Type); + var columnInfo = typeEntity.Columns.FirstOrDefault(it => it.PropertyName == ExpressionTool.GetMemberName(member)); + if (columnInfo?.SqlParameterDbType is Type) + { + return true; + } + if (columnInfo?.SqlParameterDbType is System.Data.DbType) + { + return true; + } + } + } + return isNav; + } + internal static SugarParameter GetParameterBySqlParameterDbType(int index, object value, ExpressionContext context, Expression member) + { + var expression = (member as MemberExpression)?.Expression; + var typeEntity = context?.SugarContext.Context.EntityMaintenance.GetEntityInfo(expression.Type); + var columnInfo = typeEntity.Columns.FirstOrDefault(it => it.PropertyName == ExpressionTool.GetMemberName(member)); + var columnDbType = columnInfo.SqlParameterDbType as Type; + if (columnDbType != null) + { + var ParameterConverter = columnDbType.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(columnDbType); + var p = ParameterConverter.Invoke(obj, new object[] { value, index }) as SugarParameter; + return p; + } + else + { + var paramter = new SugarParameter("@Common" + index, value) + { + DbType = (System.Data.DbType)columnInfo.SqlParameterDbType + }; + if (columnInfo.SqlParameterSize?.ObjToInt() > 0) + { + paramter.Size = columnInfo.SqlParameterSize.ObjToInt(); + } + return paramter; + } + } + public static List ExtractMemberNames(Expression expression) + { + var memberNames = new List(); + var currentExpression = (expression as LambdaExpression).Body; + + while (currentExpression != null && currentExpression.NodeType == ExpressionType.MemberAccess) + { + var memberExpression = (MemberExpression)currentExpression; + memberNames.Add(memberExpression.Member.Name); + currentExpression = memberExpression.Expression; + } + + memberNames.Reverse(); // Reverse the list to get the correct order of member names + return memberNames; + } + public static Expression> ChangeLambdaExpression(Expression> exp, string replaceParameterName, string newParameterName) + { + var parameter = Expression.Parameter(typeof(T), newParameterName); + + // 替换Lambda表达式中指定参数名 + var visitor = new ParameterReplacer(replaceParameterName, parameter); + var newBody = visitor.Visit(exp); + + return (Expression>)newBody; + } + public static Expression ChangeLambdaExpression(Expression exp, Type targetType, string replaceParameterName, string newParameterName) + { + var parameter = Expression.Parameter(targetType, newParameterName); + + // 替换Lambda表达式中指定参数名 + var visitor = new ParameterReplacer(replaceParameterName, parameter); + var newBody = visitor.Visit(exp); + + return newBody; + } + + public static List GetNewArrayMembers(NewArrayExpression newArrayExpression) + { + List strings = new List(); + // 获取数组元素的 MemberExpression,并输出属性名 + foreach (var expression in newArrayExpression.Expressions) + { + var memberExpression = expression as MemberExpression; + if (memberExpression != null) + { + strings.Add(memberExpression.Member.Name); + } + else if (expression is ConstantExpression) + { + strings.Add((expression as ConstantExpression).Value + ""); + } + } + return strings; + } + public static List GetTopLevelMethodCalls(Expression expression) + { + var methodCalls = new List(); + GetTopLevelMethodCalls(expression, methodCalls); + return methodCalls; + } + + public static void GetTopLevelMethodCalls(Expression expression, List methodCalls) + { + if (expression is MethodCallExpression methodCallExpression) + { + methodCalls.Add(methodCallExpression.Method.Name); + if (methodCallExpression.Object is MethodCallExpression parentMethodCallExpression) + { + GetTopLevelMethodCalls(parentMethodCallExpression, methodCalls); + } + } + else if (expression is LambdaExpression lambdaExpression) + { + GetTopLevelMethodCalls(lambdaExpression.Body, methodCalls); + } + } + + public static Dictionary GetNewExpressionItemList(Expression lamExp) + { + var caseExp = GetLambdaExpressionBody(lamExp); + if (caseExp is MemberInitExpression) + { + return GetMemberBindingItemList((caseExp as MemberInitExpression).Bindings); + } + var exp = caseExp as NewExpression; + if (exp == null) + { + Check.ExceptionEasy("Use Select(it=>new class(){})", "导航查询请使用Select(it=>new class(){})"); + } + var dict = new Dictionary(); + + for (int i = 0; i < exp.Arguments.Count; i++) + { + var arg = exp.Arguments[i]; + var parameterInfo = exp.Constructor.GetParameters()[i]; + + dict.Add(parameterInfo.Name, arg); + } + + return dict; + } + public static Dictionary GetMemberBindingItemList(ReadOnlyCollection exp) + { + Dictionary dict = new Dictionary(); + // 获取MemberInitExpression中的每一个MemberBinding + foreach (var binding in exp) + { + // 判断是MemberAssignment还是MemberListBinding + if (binding is MemberAssignment assignment) + { + // 获取属性名和属性值 + string propertyName = assignment.Member.Name; + dict.Add(assignment.Member.Name, assignment.Expression); + } + + } + return dict; + } + public static bool ContainsMethodName(BinaryExpression expression, string name) + { + var visitor = new MethodCallExpressionVisitor(name); + var hasMethodCallWithName = visitor.HasMethodCallWithName(expression); + return hasMethodCallWithName; + } + public static bool IsVariable(Expression expr) + { + var ps = new ParameterExpressionVisitor(); + ps.Visit(expr); + return ps.Parameters.Count == 0; + } + public static List GetParameters(Expression expr) + { + var ps = new ParameterExpressionVisitor(); + ps.Visit(expr); + return ps.Parameters; + } + public static bool IsComparisonOperatorBool(BinaryExpression binaryExp) + { + return binaryExp.NodeType.IsIn(ExpressionType.Equal, + ExpressionType.GreaterThan, ExpressionType.GreaterThanOrEqual, + ExpressionType.LessThan, ExpressionType.LessThanOrEqual); + } + + public static string GetOperator(ExpressionType expressiontype) + { + switch (expressiontype) + { + case ExpressionType.And: + return "&"; + case ExpressionType.AndAlso: + return "AND"; + case ExpressionType.Equal: + return "="; + case ExpressionType.GreaterThan: + return ">"; + case ExpressionType.GreaterThanOrEqual: + return ">="; + case ExpressionType.LessThan: + return "<"; + case ExpressionType.LessThanOrEqual: + return "<="; + case ExpressionType.NotEqual: + return "<>"; + case ExpressionType.Or: + return "|"; + case ExpressionType.OrElse: + return "OR"; + case ExpressionType.Add: + case ExpressionType.AddChecked: + return "+"; + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + return "-"; + case ExpressionType.Divide: + return "/"; + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + return "*"; + case ExpressionType.Modulo: + return "%"; + case ExpressionType.Coalesce: + throw new Exception("Expression no support ?? ,Use SqlFunc.IsNull"); + default: +#pragma warning disable CA1863 // 使用 "CompositeFormat" + Check.ThrowNotSupportedException(string.Format(ErrorMessage.OperatorError, expressiontype.ToString())); +#pragma warning restore CA1863 // 使用 "CompositeFormat" + return null; + } + } + + + public static void GetOneToOneInfo(SqlSugarProvider context, Expression> LeftObject, out MemberExpression memberExpression, out string navObjectName, out EntityColumnInfo navColumn, out EntityInfo navEntityInfo, out EntityColumnInfo navPkColumn) + { + memberExpression = ((LeftObject as LambdaExpression).Body as MemberExpression); + var listItemType = typeof(T); + var listItemEntity = context.EntityMaintenance.GetEntityInfo(listItemType); + var listPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault(); + navObjectName = memberExpression.Member.Name; + var navObjectName2 = navObjectName; + var navObjectNamePropety = listItemType.GetProperty(navObjectName); + var navObjectNameColumnInfo = listItemEntity.Columns.First(it => it.PropertyName == navObjectName2); + Check.ExceptionEasy(navObjectNameColumnInfo.Navigat == null, $"{navObjectName} not [Navigat(..)] ", $"{navObjectName} 没有导航特性 [Navigat(..)] "); + Check.ExceptionEasy(navObjectNameColumnInfo.Navigat.NavigatType != NavigateType.OneToOne, $"IncludeLeftJoin can only be one-on-one ", $"IncludeLeftJoin 只能是一对一 "); + navColumn = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name); + Check.ExceptionEasy(navColumn == null, "OneToOne navigation configuration error", $"OneToOne导航配置错误: 实体{listItemEntity.EntityName} 不存在{navObjectNameColumnInfo.Navigat.Name}"); + var navType = navObjectNamePropety.PropertyType; + navEntityInfo = context.EntityMaintenance.GetEntityInfo(navType); + context.InitMappingInfo(navEntityInfo.Type); + navPkColumn = navEntityInfo.Columns.Where(it => it.IsPrimarykey).FirstOrDefault(); + Check.ExceptionEasy(navPkColumn == null && navObjectNameColumnInfo.Navigat.Name2 == null, navEntityInfo.EntityName + "need primarykey", navEntityInfo.EntityName + " 需要主键"); + if (navObjectNameColumnInfo.Navigat.Name2.HasValue()) + { + navPkColumn = navEntityInfo.Columns.Where(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name2).FirstOrDefault(); + } + } + + + public static List ExpressionParameters(Expression expression) + { + List parameters = null; + if (expression is LambdaExpression) + { + if ((expression as LambdaExpression).Parameters != null) + { + parameters = (expression as LambdaExpression).Parameters.ToList(); + } + } + return parameters; + } + + public static object GetValue(object value, ExpressionContext context) + { + if (value == null) return value; + var type = value.GetType(); + if (type.IsEnum() && type != typeof(DateType) && type != typeof(JoinType) && type != typeof(OrderByType)) + { + if (context.TableEnumIsString == true) + { + return value.ToString(); + } + else + { + return Convert.ToInt64(value); + } + } + else + return value; + } + + public static Expression GetLambdaExpressionBody(Expression expression) + { + Expression newExp = expression; + if (newExp is LambdaExpression) + { + newExp = (newExp as LambdaExpression).Body; + } + + return newExp; + } + + + public static string GetFirstTypeNameFromExpression(Expression expression) + { + if (expression is LambdaExpression lambda) + { + return GetFirstTypeNameFromExpression(lambda.Body); + } + else if (expression is MemberExpression member) + { + return member.Member.Name; + } + else if (expression is NewExpression newExpr) + { + return newExpr.Type.Name; + } + else if (expression is MethodCallExpression methodCall) + { + return GetFirstTypeNameFromExpression(methodCall.Arguments.FirstOrDefault()); + } + return ""; + } + + public static string GetMethodName(Expression expression) + { + if (expression is MethodCallExpression) + { + return (expression as MethodCallExpression).Method.Name; + } + return null; + } + + public static Type GetMemberInfoType(MemberInfo member) + { + switch (member.MemberType) + { + case MemberTypes.Event: + return ((EventInfo)member).EventHandlerType; + case MemberTypes.Field: + return ((FieldInfo)member).FieldType; + case MemberTypes.Method: + return ((MethodInfo)member).ReturnType; + case MemberTypes.Property: + return ((PropertyInfo)member).PropertyType; + default: + return null; + } + } + public static bool IsLogicOperator(string operatorValue) + { + return operatorValue == "&&" || operatorValue == "||" || operatorValue == "AND" || operatorValue == "OR"; + } + + public static bool IsLogicOperator(Expression expression) + { + return expression.NodeType == ExpressionType.And || + expression.NodeType == ExpressionType.AndAlso || + expression.NodeType == ExpressionType.Or || + expression.NodeType == ExpressionType.OrElse; + } + public static bool IsComparisonOperator(Expression expression) + { + return expression.NodeType != ExpressionType.And && + expression.NodeType != ExpressionType.AndAlso && + expression.NodeType != ExpressionType.Or && + expression.NodeType != ExpressionType.OrElse; + } + public static bool IsEqualOrLtOrGt(Expression expression) + { + return expression.NodeType == ExpressionType.Equal || + expression.NodeType == ExpressionType.GreaterThan || + expression.NodeType == ExpressionType.LessThan || + expression.NodeType == ExpressionType.LessThanOrEqual || + expression.NodeType == ExpressionType.GreaterThanOrEqual + ; + } + public static object GetMemberValue(MemberInfo member, Expression expression) + { + var rootExpression = expression as MemberExpression; + var memberInfos = new Stack(); + var fieldInfo = member as System.Reflection.FieldInfo; + object reval = null; + MemberExpression memberExpr = null; + while (expression is MemberExpression) + { + memberExpr = expression as MemberExpression; + memberInfos.Push(memberExpr.Member); + if (memberExpr.Expression == null) + { + var isProperty = memberExpr.Member.MemberType == MemberTypes.Property; + var isField = memberExpr.Member.MemberType == MemberTypes.Field; + if (isProperty) + { + try + { + reval = GetPropertyValue(memberExpr); + } + catch + { + reval = null; + } + } + else if (isField) + { + reval = GetFiledValue(memberExpr); + } + } + if (memberExpr.Expression == null) + { + + } + expression = memberExpr.Expression; + } + // fetch the root object reference: + var constExpr = expression as ConstantExpression; + if (constExpr == null) + { + return DynamicInvoke(rootExpression); + } + object objReference = constExpr.Value; + // "ascend" back whence we came from and resolve object references along the way: + while (memberInfos.Count > 0) // or some other break condition + { + var mi = memberInfos.Pop(); + if (mi.MemberType == MemberTypes.Property) + { + if (objReference == null) + { + Check.ExceptionEasy($"Expression error {rootExpression?.ToString()} expression, An empty reference appears in the expression to check if the parameter is null ", $"表达式错误 {rootExpression?.ToString()} 表达式中出现了空引用 检查参数是否为null "); + } + var objProp = objReference.GetType().GetProperties().Where(it => it.Name == mi.Name).FirstOrDefault(); + if (objProp == null) + { + objReference = DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression); + } + else + { + objReference = objProp.GetValue(objReference, null); + } + } + else if (mi.MemberType == MemberTypes.Field) + { + var objField = objReference.GetType().GetField(mi.Name); + if (objField == null) + { + objReference = DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression); + } + else + { + objReference = objField.GetValue(objReference); + } + } + } + reval = objReference; + return reval; + } + + internal static Expression RemoveConvert(Expression item) + { + for (int i = 0; i < 10; i++) + { + if ((item is UnaryExpression) && (item as UnaryExpression).NodeType == ExpressionType.Convert) + { + item = (item as UnaryExpression).Operand; + } + else + { + break; + } + } + return item; + } + internal static Expression RemoveConvertThanOne(Expression item) + { + for (int i = 0; i < 10; i++) + { + if ((item is UnaryExpression) + && (item as UnaryExpression).NodeType == ExpressionType.Convert + && (item as UnaryExpression).Operand is UnaryExpression) + { + item = (item as UnaryExpression).Operand; + } + else + { + break; + } + } + return item; + } + public static string GetMemberName(Expression expression) + { + if (expression is LambdaExpression) + { + expression = (expression as LambdaExpression).Body; + } + if (expression is UnaryExpression) + { + expression = ((UnaryExpression)expression).Operand; + } + var member = (expression as MemberExpression)?.Member?.Name; + return member; + } + internal static object GetExpressionValue(Expression expression) + { + try + { + if (expression is ConstantExpression) + { + return (expression as ConstantExpression).Value; + } + else if (expression is MethodCallExpression) + { + return LambdaExpression.Lambda(expression).Compile().DynamicInvoke(); + } + else + { + return GetMemberValue((expression as MemberExpression).Member, expression); + } + } + catch + { + return LambdaExpression.Lambda(expression).Compile().DynamicInvoke(); + } + } + + public static object GetFiledValue(MemberExpression memberExpr) + { + if (!(memberExpr.Member is FieldInfo)) + { + return DynamicInvoke(memberExpr); + } + object reval = null; + FieldInfo field = (FieldInfo)memberExpr.Member; + Check.Exception(field.IsPrivate, string.Format(" Field \"{0}\" can't be private ", field.Name)); + reval = field.GetValue(memberExpr.Member); + if (reval?.GetType().IsClass() == true && reval.GetType() != UtilConstants.StringType) + { + var fieldName = memberExpr.Member.Name; + var proInfo = reval.GetType().GetProperty(fieldName); + if (proInfo != null) + { + reval = proInfo.GetValue(reval, null); + } + var fieInfo = reval.GetType().GetField(fieldName); + if (fieInfo != null) + { + reval = fieInfo.GetValue(reval); + } + if (fieInfo == null && proInfo == null) + { + Check.Exception(field.IsPrivate, string.Format(" Field \"{0}\" can't be private ", field.Name)); + } + } + return reval; + } + + + public static bool IsConstExpression(MemberExpression memberExpr) + { + var result = false; + while (memberExpr?.Expression != null) + { + var isConst = memberExpr.Expression is ConstantExpression; + if (isConst) + { + result = true; + break; + } + else if (memberExpr.Expression is BinaryExpression && (memberExpr.Expression as BinaryExpression).NodeType == ExpressionType.ArrayIndex) + { + result = true; + break; + } + memberExpr = memberExpr.Expression as MemberExpression; + } + return result; + } + + public static object GetPropertyValue(MemberExpression memberExpr) + { + if (!(memberExpr.Member is PropertyInfo)) + { + return DynamicInvoke(memberExpr); + } + object reval = null; + PropertyInfo pro = (PropertyInfo)memberExpr.Member; + reval = pro.GetValue(memberExpr.Member, null); + if (reval?.GetType().IsClass() == true && reval.GetType() != UtilConstants.StringType) + { + var fieldName = memberExpr.Member.Name; + var proInfo = reval.GetType().GetProperty(fieldName); + if (proInfo != null) + { + reval = proInfo.GetValue(reval, null); + } + var fieInfo = reval.GetType().GetField(fieldName); + if (fieInfo != null) + { + reval = fieInfo.GetValue(reval); + } + if (fieInfo == null && proInfo == null && !reval.GetType().FullName.IsCollectionsList()) + { + Check.Exception(true, string.Format(" Property \"{0}\" can't be private ", pro.Name)); + } + } + return reval; + } + + public static object DynamicInvoke(Expression expression, MemberExpression memberExpression = null) + { + try + { + object value = Expression.Lambda(expression).Compile().DynamicInvoke(); + if (value?.GetType().IsClass() == true && value.GetType() != UtilConstants.StringType && memberExpression != null) + { + value = Expression.Lambda(memberExpression).Compile().DynamicInvoke(); + } + + return value; + } + catch (InvalidOperationException ex) + { + return new MapperExpressionResolve(expression, ex).GetSql(); ; + } + catch (Exception ex) + { + throw new Exception("No support " + expression.ToString() + " " + ex.Message); + } + } + + public static Type GetPropertyOrFieldType(MemberInfo propertyOrField) + { + if (propertyOrField.MemberType == MemberTypes.Property) + return ((PropertyInfo)propertyOrField).PropertyType; + if (propertyOrField.MemberType == MemberTypes.Field) + return ((FieldInfo)propertyOrField).FieldType; + throw new NotSupportedException(); + } + + public static bool IsEntity(Type type) + { + return type.IsClass() && type != UtilConstants.StringType; + } + + public static bool IsValueType(Type type) + { + return !IsEntity(type); + } + + public static bool IsUnConvertExpress(Expression item) + { + return item is UnaryExpression && item.NodeType == ExpressionType.Convert; + } + + internal static List GetNewexpressionInfos(Expression item, ExpressionContext context, BaseResolve baseResolve) + { + List result = new List(); + foreach (MemberBinding binding in ((MemberInitExpression)item).Bindings) + { + if (binding.BindingType != MemberBindingType.Assignment) + { + throw new NotSupportedException(); + } + MemberAssignment memberAssignment = (MemberAssignment)binding; + NewExpressionInfo additem = new NewExpressionInfo(); + if (memberAssignment.Expression is MemberExpression) + { + additem.LeftNameName = memberAssignment.Member.Name; + var member = (memberAssignment.Expression as MemberExpression).Expression; + additem.ShortName = member + ""; + additem.RightName = (memberAssignment.Expression as MemberExpression).Member.Name; + additem.RightDbName = context.GetDbColumnName(member.Type.Name, additem.RightName); + if (ExpressionTool.IsNavMember(context, member)) + { + additem.RightDbName = additem.RightName = baseResolve.GetNewExpressionValue(memberAssignment.Expression); + } + result.Add(additem); + } + else if (memberAssignment.Expression is ConstantExpression) + { + var value = ((ConstantExpression)memberAssignment.Expression).Value; + //var leftInfo = keys[i]; + additem.Type = nameof(ConstantExpression); + additem.RightName = memberAssignment.Member.Name; + additem.ShortName = memberAssignment.Member.Name; + additem.RightName = memberAssignment.Member.Name; + additem.LeftNameName = memberAssignment.Member.Name; + additem.RightDbName = UtilMethods.GetSqlValue(value); + //additem.Value = ""; + result.Add(additem); + } + else if (memberAssignment.Expression is MemberInitExpression || memberAssignment.Expression is NewExpression) + { + + var dic = ExpressionTool.GetNewExpressionItemList(memberAssignment.Expression); + foreach (var kv in dic) + { + additem = new NewExpressionInfo(); + //var leftInfo = keys[i]; + additem.Type = nameof(NewExpression); + additem.RightName = kv.Key; + additem.ShortName = ExpressionTool.GetParameters(kv.Value).First().Name; + additem.RightName = kv.Key; + additem.LeftNameName = memberAssignment.Member.Name + "." + kv.Key; + additem.RightDbName = kv.Key; + //additem.Value = ""; + result.Add(additem); + } + } + else + { + var value = baseResolve.GetNewExpressionValue(memberAssignment.Expression); + //var leftInfo = keys[i]; + additem.Type = nameof(ConstantExpression); + additem.RightName = memberAssignment.Member.Name; + additem.ShortName = memberAssignment.Member.Name; + additem.RightName = memberAssignment.Member.Name; + additem.LeftNameName = memberAssignment.Member.Name; + additem.RightDbName = value; + //additem.Value = ""; + result.Add(additem); + } + + } + return result; + } + internal static List GetNewDynamicexpressionInfos(Expression item, ExpressionContext context, BaseResolve baseResolve) + { + List result = new List(); + int i = 0; + foreach (var binding in ((NewExpression)item).Arguments) + { + NewExpressionInfo additem = new NewExpressionInfo(); + var keys = ((NewExpression)item).Members; + if (binding is MemberExpression) + { + var member = (MemberExpression)binding; + var entityName = member.Expression?.Type?.Name; + //var memberAssignment = binding; + //NewExpressionInfo additem = new NewExpressionInfo(); + additem.RightName = member.Member.Name; + additem.ShortName = member.Expression + ""; + additem.RightName = member.Member.Name; + additem.RightDbName = context.GetDbColumnName(entityName, additem.RightName); + var isNavMember = member.Expression != null + && ExpressionTool.IsNavMember(context, member.Expression); + additem.LeftNameName = member.Member.Name; + if (isNavMember && (context?.SugarContext?.QueryBuilder?.JoinQueryInfos?.Count ?? 0) == 0) + { + var exp = context.GetCopyContextWithMapping(); + exp.Resolve(member, ResolveExpressType.FieldSingle); + var sql = exp.Result.GetResultString(); + if (context.IsSingle && context.CurrentShortName.IsNullOrEmpty()) + { + context.SingleTableNameSubqueryShortName = ExpressionTool.GetParameters(member)?.FirstOrDefault()?.Name; + } + additem.RightDbName = sql; + } + else if (isNavMember && context?.SugarContext?.QueryBuilder?.JoinQueryInfos?.Any(it => it.ShortName?.StartsWith("pnv_" + ExpressionTool.GetMemberName(member.Expression)) == true) == true) + { + additem.ShortName = "pnv_" + ExpressionTool.GetMemberName(member.Expression); + } + //additem.Value = ""; + result.Add(additem); + } + else if (binding is ConstantExpression) + { + var value = ((ConstantExpression)binding).Value; + var leftInfo = keys[i]; + additem.Type = nameof(ConstantExpression); + additem.RightName = leftInfo.Name; + additem.ShortName = leftInfo.Name; + additem.RightName = leftInfo.Name; + additem.LeftNameName = leftInfo.Name; + additem.RightDbName = UtilMethods.GetSqlValue(value); + //additem.Value = ""; + result.Add(additem); + } + else if (binding is MemberInitExpression || binding is NewExpression) + { + + var dic = ExpressionTool.GetNewExpressionItemList(binding); + foreach (var kv in dic) + { + additem = new NewExpressionInfo(); + //var leftInfo = keys[i]; + additem.Type = nameof(NewExpression); + additem.RightName = kv.Key; + additem.ShortName = ExpressionTool.GetParameters(kv.Value).First().Name; + additem.RightName = kv.Key; + additem.LeftNameName = keys[i].Name + "." + kv.Key; + additem.RightDbName = kv.Key; + //additem.Value = ""; + result.Add(additem); + } + } + else + { + var value = baseResolve.GetNewExpressionValue(binding); + var leftInfo = keys[i]; + additem.Type = nameof(ConstantExpression); + additem.RightName = leftInfo.Name; + additem.ShortName = leftInfo.Name; + additem.RightName = leftInfo.Name; + additem.LeftNameName = leftInfo.Name; + additem.RightDbName = value; + //additem.Value = ""; + result.Add(additem); + } + i++; + } + return result; + } + + internal static bool IsSubQuery(Expression it) + { + if (it is MethodCallExpression) + { + var method = (MethodCallExpression)it; + if (method.Object?.Type.Name.StartsWith("Subquery") == true) + { + return true; + } + } + return false; + } + + internal static bool IsIsNullSubQuery(Expression it) + { + if (it is MethodCallExpression) + { + var method = (MethodCallExpression)it; + if (method.Method.Name == "IsNull") + { + if (method.Arguments.Count == 2 && IsSubQuery(method.Arguments[0])) + { + return true; + } + } + } + return false; + } + + internal static bool IsMemberInit(object selectValue) + { + var result = false; + if (selectValue is Expression) + { + if (selectValue is MemberInitExpression) + { + result = true; + } + else if (selectValue is LambdaExpression) + { + var lambda = (LambdaExpression)selectValue; + if (lambda.Body is MemberInitExpression) + { + result = true; + } + } + } + return result; + } + + internal static MemberInitExpression GetMemberInit(object selectValue) + { + MemberInitExpression result = null; + if (selectValue is Expression) + { + if (selectValue is MemberInitExpression) + { + result = (MemberInitExpression)selectValue; + } + else if (selectValue is LambdaExpression) + { + var lambda = (LambdaExpression)selectValue; + if (lambda.Body is MemberInitExpression) + { + result = (MemberInitExpression)lambda.Body; + } + } + } + return result; + } + + + public static bool IsNegate(Expression exp) + { + return exp is UnaryExpression && exp.NodeType == ExpressionType.Negate; + } + + public static bool GetIsLength(Expression item) + { + var isLength = (item is MemberExpression) && ((item as MemberExpression).Member.Name == "Length"); + if (isLength) + { + var exp = (item as MemberExpression).Expression; + if (exp == null) + { + return false; + } + else if (exp.Type == UtilConstants.StringType && item.Type == UtilConstants.IntType) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ListAnyParameter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ListAnyParameter.cs new file mode 100644 index 000000000..e8c835898 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ListAnyParameter.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + internal class ListAnyParameter + { + public string Name { get; internal set; } + public string Sql { get; internal set; } + public List Columns { get; internal set; } + public Func ConvetColumnFunc { get; internal set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MapperExpression.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MapperExpression.cs new file mode 100644 index 000000000..aeaea82d6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MapperExpression.cs @@ -0,0 +1,21 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class MapperExpression + { + public MapperExpressionType Type { get; set; } + public Expression FillExpression { get; set; } + public Expression MappingField1Expression { get; set; } + public Expression MappingField2Expression { get; set; } + public SqlSugarProvider Context { get; set; } + public QueryBuilder QueryBuilder { get; set; } + public ISqlBuilder SqlBuilder { get; set; } + } + + public enum MapperExpressionType + { + oneToOne = 1, + oneToN = 2 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MapperSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MapperSql.cs new file mode 100644 index 000000000..79ce5c093 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MapperSql.cs @@ -0,0 +1,15 @@ +namespace SqlSugar +{ + public class MapperSql + { + public string Sql { get; set; } + } + + public class MapperExpressionInfo + { + public Type Type { get; set; } + public EntityInfo EntityInfo { get; set; } + public string FieldName { get; set; } + public string FieldString { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MethodCallExpressionModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MethodCallExpressionModel.cs new file mode 100644 index 000000000..0b4f13b9a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/MethodCallExpressionModel.cs @@ -0,0 +1,23 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class MethodCallExpressionModel + { + public List Args { get; set; } + public string Name { get; set; } + public dynamic Data { get; set; } + public object DataObject { get; set; } + public Expression Expression { get; set; } + public Expression BaseExpression { get; set; } + public List Parameters { get; set; } + public ExpressionContext Conext { get; set; } + } + + public class MethodCallExpressionArgs + { + public bool IsMember { get; set; } + public object MemberName { get; set; } + public object MemberValue { get; set; } + public Type Type { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/NewExpressionInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/NewExpressionInfo.cs new file mode 100644 index 000000000..cbeaa0d65 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/NewExpressionInfo.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + internal class NewExpressionInfo + { + public string LeftNameName { get; set; } + public string RightName { get; set; } + public string RightDbName { get; set; } + public string ShortName { get; set; } + public string Type { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ParameterExpressionVisitor.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ParameterExpressionVisitor.cs new file mode 100644 index 000000000..99e8f205b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ParameterExpressionVisitor.cs @@ -0,0 +1,84 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class ParameterExpressionVisitor : ExpressionVisitor + { + public List Parameters { get; } = new List(); + + protected override Expression VisitParameter(ParameterExpression node) + { + Parameters.Add(node); + return base.VisitParameter(node); + } + } + internal class MethodCallExpressionVisitor : ExpressionVisitor + { + private readonly string _methodName; + private bool _hasMethodCallWithName; + + public MethodCallExpressionVisitor(string methodName) + { + _methodName = methodName; + } + + public bool HasMethodCallWithName(Expression expression) + { + Visit(expression); + return _hasMethodCallWithName; + } + + protected override Expression VisitMethodCall(MethodCallExpression node) + { + if (node.Method.Name.Contains(_methodName)) + { + _hasMethodCallWithName = true; + return node; + } + + return base.VisitMethodCall(node); + } + } + + internal class ExpressionTreeVisitor : ExpressionVisitor + { + private readonly List _nodes = new List(); + //protected override Expression VisitBinary(BinaryExpression node) + //{ + // // 解析二元操作符表达式 + // _nodes.Add(node); + // Visit(node.Left); + // Visit(node.Right); + // return node; + //} + //protected override Expression VisitConstant(ConstantExpression node) + //{ + // // 解析常量表达式 + // _nodes.Add(node); + // return node; + //} + protected override Expression VisitMember(MemberExpression node) + { + // 解析成员访问表达式 + _nodes.Add(node); + return node; + } + protected override Expression VisitMethodCall(MethodCallExpression node) + { + // 解析方法调用表达式 + _nodes.Add(node); + if (node.Arguments.Count != 0) + { + Visit(node.Arguments.First()); + } + return node; + } + public List GetExpressions(Expression expression) + { + Visit(expression); + _nodes.Reverse(); + return _nodes; + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ParameterReplacer.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ParameterReplacer.cs new file mode 100644 index 000000000..7b7674360 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ParameterReplacer.cs @@ -0,0 +1,21 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class ParameterReplacer : ExpressionVisitor + { + private readonly string _oldParameterName; + private readonly ParameterExpression _newParameter; + + public ParameterReplacer(string oldParameterName, ParameterExpression newParameter) + { + _oldParameterName = oldParameterName; + _newParameter = newParameter; + } + + protected override Expression VisitParameter(ParameterExpression node) + { + return node.Name == _oldParameterName ? _newParameter : base.VisitParameter(node); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ResolveExpressType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ResolveExpressType.cs new file mode 100644 index 000000000..0ee028cb7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/ResolveExpressType.cs @@ -0,0 +1,18 @@ +namespace SqlSugar +{ + public enum ResolveExpressType + { + None = 0, + WhereSingle = 1, + WhereMultiple = 2, + SelectSingle = 3, + SelectMultiple = 4, + FieldSingle = 5, + FieldMultiple = 7, + Join = 8, + ArraySingle = 9, + ArrayMultiple = 10, + Update = 11 + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/SugarParameter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/SugarParameter.cs new file mode 100644 index 000000000..4f828a813 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Common/SugarParameter.cs @@ -0,0 +1,292 @@ +using System.Data; +using System.Data.Common; +namespace SqlSugar +{ + public class SugarParameter : DbParameter + { + public bool IsRefCursor { get; set; } + public bool IsClob { get; set; } + public bool IsNClob { get; set; } + public bool IsNvarchar2 { get; set; } + public SugarParameter(string name, object value) + { + this.Value = value; + this.ParameterName = name; + if (value != null) + { + SettingDataType(value.GetType()); + } + } + public SugarParameter(string name, object value, Type type) + { + this.Value = value; + this.ParameterName = name; + SettingDataType(type); + } + public SugarParameter(string name, object value, Type type, ParameterDirection direction) + { + this.Value = value; + this.ParameterName = name; + this.Direction = direction; + SettingDataType(type); + } + public SugarParameter(string name, object value, Type type, ParameterDirection direction, int size) + { + this.Value = value; + this.ParameterName = name; + this.Direction = direction; + this.Size = size; + SettingDataType(type); + } + + + public SugarParameter(string name, object value, System.Data.DbType type) + { + this.Value = value; + this.ParameterName = name; + this.DbType = type; + } + public SugarParameter(string name, DataTable value, string SqlServerTypeName) + { + this.Value = value; + this.ParameterName = name; + this.TypeName = SqlServerTypeName; + } + public SugarParameter(string name, object value, System.Data.DbType type, ParameterDirection direction) + { + this.Value = value; + this.ParameterName = name; + this.Direction = direction; + this.DbType = type; + } + public SugarParameter(string name, object value, System.Data.DbType type, ParameterDirection direction, int size) + { + this.Value = value; + this.ParameterName = name; + this.Direction = direction; + this.Size = size; + this.DbType = type; + } + + private void SettingDataType(Type type) + { + if (type == UtilConstants.ByteArrayType) + { + this.DbType = System.Data.DbType.Binary; + } + else if (type == UtilConstants.GuidType) + { + this.DbType = System.Data.DbType.Guid; + } + else if (type == UtilConstants.IntType) + { + this.DbType = System.Data.DbType.Int32; + } + else if (type == UtilConstants.ShortType) + { + this.DbType = System.Data.DbType.Int16; + } + else if (type == UtilConstants.LongType) + { + this.DbType = System.Data.DbType.Int64; + } + else if (type == UtilConstants.DateType) + { + this.DbType = System.Data.DbType.DateTime; + } + else if (type == UtilConstants.DobType) + { + this.DbType = System.Data.DbType.Double; + } + else if (type == UtilConstants.DecType) + { + this.DbType = System.Data.DbType.Decimal; + } + else if (type == UtilConstants.ByteType) + { + this.DbType = System.Data.DbType.Byte; + } + else if (type == UtilConstants.SByteType) + { + this.DbType = System.Data.DbType.SByte; + } + else if (type == UtilConstants.FloatType) + { + this.DbType = System.Data.DbType.Single; + } + else if (type == UtilConstants.BoolType) + { + this.DbType = System.Data.DbType.Boolean; + } + else if (type == UtilConstants.StringType) + { + this.DbType = System.Data.DbType.String; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + this.DbType = System.Data.DbType.DateTimeOffset; + } + else if (type == UtilConstants.TimeSpanType) + { + this.DbType = System.Data.DbType.Time; + } + else if (type?.Name == "Geometry") + { + this.DbType = System.Data.DbType.Object; + } + else if (type?.Namespace == "Kdbndp.LegacyPostgis") + { + this.DbType = System.Data.DbType.Object; + } + else if (type?.Namespace == "NetTopologySuite.Geometries") + { + this.DbType = System.Data.DbType.Object; + } + else if (type?.IsEnum() == true) + { + this.DbType = System.Data.DbType.Int64; + if (Value != null) + { + this.Value = Convert.ToInt64(Value); + } + } + else if (type == UtilConstants.UIntType) + { + this.DbType = System.Data.DbType.UInt32; + } + else if (type == UtilConstants.ULongType) + { + this.DbType = System.Data.DbType.UInt64; + } + else if (type == UtilConstants.UShortType) + { + this.DbType = System.Data.DbType.UInt16; + } + else if (type == UtilConstants.ShortType) + { + this.DbType = System.Data.DbType.UInt16; + } + else if (type?.Name == "TimeOnly") + { + this.DbType = System.Data.DbType.Time; + this.Value = UtilMethods.TimeOnlyToTimeSpan(this.Value); + } + else if (type?.Name == "DateOnly") + { + this.DbType = System.Data.DbType.Date; + this.Value = Convert.ToDateTime(UtilMethods.DateOnlyToDateTime(this.Value)); + } + else if (type?.FullName == "Newtonsoft.Json.Linq.JObject" || type?.FullName == "Newtonsoft.Json.Linq.JArray" || type?.FullName == "Newtonsoft.Json.Linq.JValue") + { + this.Value = this.Value == null ? default(string) : this.Value.ObjToString(); + } + + } + public SugarParameter(string name, object value, bool isOutput) + { + this.Value = value; + this.ParameterName = name; + if (isOutput) + { + this.Direction = ParameterDirection.Output; + } + } + public override System.Data.DbType DbType + { + get; set; + } + + public override ParameterDirection Direction + { + get; set; + } + + public override bool IsNullable + { + get; set; + } + + public override string ParameterName + { + get; set; + } + + public override byte Scale + { + get; set; + } + + public int _Size; + + public override int Size + { + get + { + if (_Size == 0 && Value != null) + { + var isByteArray = Value.GetType() == UtilConstants.ByteArrayType; + if (isByteArray) + _Size = -1; + else + { + var length = Value.ToString().Length; + _Size = length < 4000 ? 4000 : -1; + + } + } + if (_Size == 0) + _Size = 4000; + return _Size; + } + set + { + _Size = value; + } + } + + public override string SourceColumn + { + get; set; + } + + public override bool SourceColumnNullMapping + { + get; set; + } + public string UdtTypeName + { + get; + set; + } + + public override object Value + { + get; set; + } + + public Dictionary TempDate + { + get; set; + } + + /// + /// 如果类库是.NET 4.5请删除该属性 + /// If the SqlSugar library is.NET 4.5, delete the property + /// + public override DataRowVersion SourceVersion + { + get; set; + } + + public override void ResetDbType() + { + this.DbType = System.Data.DbType.String; + } + + + public string TypeName { get; set; } + public bool IsJson { get; set; } + public bool IsArray { get; set; } + public object CustomDbType { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs new file mode 100644 index 000000000..3ff030e7b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs @@ -0,0 +1,1403 @@ +using System.Collections; +using System.Text; +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public partial class DefaultDbMethod : IDbMethods + { + public virtual string ParameterKeyWord { get; set; } = "@"; + public virtual string RowNumber(MethodCallExpressionModel model) + { + if (model.Args.Count == 1) + { + return $"row_number() over(order by {model.Args[0].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + else + { + return $"row_number() over( partition by {model.Args[1].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')} order by {model.Args[0].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + } + public virtual string RowCount(MethodCallExpressionModel model) + { + if (model.Args.Count > 1) + { + return $"COUNT({model.Args[0].MemberName}) over( partition by {model.Args[2].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')} order by {model.Args[1].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + return "COUNT(1) over()"; + } + public string RowSum(MethodCallExpressionModel model) + { + if (model.Args.Count > 1) + { + return $"SUM({model.Args[0].MemberName}) over( partition by {model.Args[2].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')} order by {model.Args[1].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + return "SUM(" + model.Args[0].MemberName + ") over()"; + } + public string RowAvg(MethodCallExpressionModel model) + { + if (model.Args.Count > 1) + { + return $"AVG({model.Args[0].MemberName}) over( partition by {model.Args[2].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')} order by {model.Args[1].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + return "AVG(" + model.Args[0].MemberName + ") over()"; + } + public string RowMin(MethodCallExpressionModel model) + { + if (model.Args.Count > 1) + { + return $"Min({model.Args[0].MemberName}) over( partition by {model.Args[2].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')} order by {model.Args[1].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + return "Min(" + model.Args[0].MemberName + ") over()"; + } + public string RowMax(MethodCallExpressionModel model) + { + if (model.Args.Count > 1) + { + return $"Max({model.Args[0].MemberName}) over( partition by {model.Args[2].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')} order by {model.Args[1].MemberName.ObjToString().TrimEnd('\'').TrimStart('\'')})"; + } + return "Max(" + model.Args[0].MemberName + ") over()"; + } + public virtual string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + var ifTrue = parameter2.MemberName.ObjToString(); + var ifFalse = parameter3.MemberName.ObjToString(); + if (ifTrue == ifFalse) + { + return $" {parameter2.MemberName} "; + } + if (model.Parameters != null + && model.Conext != null + && ifTrue.StartsWith(model.Conext?.SqlParameterKeyWord) + && ifFalse.StartsWith(model.Conext?.SqlParameterKeyWord)) + { + var p2 = model.Parameters.Where(it => it.ParameterName != null).FirstOrDefault(it => it.ParameterName.Equals(ifTrue)); + var p3 = model.Parameters.Where(it => it.ParameterName != null).FirstOrDefault(it => it.ParameterName.Equals(ifFalse)); + if (p2 != null && p3 != null) + { + if (p2.Value?.Equals(p3.Value) == true) + { + model.Parameters.Remove(p3); + return $" {parameter2.MemberName} "; + } + } + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + + public virtual string IsNullOrEmpty(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NULL OR {0}='')", parameter.MemberName); + } + + public virtual string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("({0} IS NOT NULL )", parameter.MemberName); + } + + public virtual string HasNumber(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0}>0 AND {0} IS NOT NULL )", parameter.MemberName); + } + + + public virtual string ToUpper(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" (UPPER({0})) ", parameter.MemberName); + } + + public virtual string ToLower(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" (LOWER({0})) ", parameter.MemberName); + } + + public virtual string Trim(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" (rtrim(ltrim({0}))) ", parameter.MemberName); + } + + public virtual 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 virtual string ContainsArray(MethodCallExpressionModel model) + { + var inValueIEnumerable = (IEnumerable)model.Args[0].MemberValue; + List inValues = new List(); + if (inValueIEnumerable != null) + { + foreach (var item in inValueIEnumerable) + { + if (item?.GetType().IsEnum() == true) + { + inValues.Add(Convert.ToInt64(item)); + } + else if (item != null && item.GetType() == UtilConstants.DateType) + { + var inStr = Convert.ToDateTime(item).ToString("yyyy-MM-dd HH:mm:ss.fff"); + inValues.Add(inStr); + } + else if (item?.GetType().FullName == "System.DateOnly") + { + var inStr = UtilMethods.DateOnlyToDateTime(item).ObjToDate().ToString("yyyy-MM-dd"); + inValues.Add(inStr); + } + else if (item != null && item.GetType() == UtilConstants.ByteArrayType) + { + var inStr = Convert.ToHexString((byte[])item); + inValues.Add(inStr); + } + else + { + if (item is string && item.HasValue() && model?.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.DbType == DbType.MySql) + { + var newValue = item.ToString().Replace("\\", "\\\\"); + inValues.Add(newValue); + } + else + { + inValues.Add(item); + } + } + } + } + var value = model.Args[1].MemberName; + string inValueString = null; + var isNvarchar = model.Args.Count == 3; + if (inValues?.Count > 0) + { + if (isNvarchar && model.Args[2].MemberValue.Equals(true)) + { + inValueString = inValues.ToArray().ToJoinSqlInValsN(); + } + else if (inValues.Count != 0 && inValues.FirstOrDefault() is bool && inValues.All(it => it is bool)) + { + inValueString = string.Join(",", inValues.Select(it => Convert.ToBoolean(it) ? 1 : 0)); + } + else + { + inValueString = inValues.ToArray().ToJoinSqlInVals(); + } + } + if (inValueString.IsNullOrEmpty()) + { + return " (1=2) "; + } + else + { + return string.Format(" ({0} IN ({1})) ", value, inValueString); + } + } + + public virtual string ContainsArrayUseSqlParameters(MethodCallExpressionModel model) + { + var inValueIEnumerable = (IEnumerable)model.Args[0].MemberValue; + List inValues = new List(); + if (inValueIEnumerable != null) + { + foreach (var item in inValueIEnumerable) + { + if (item?.GetType().IsEnum() == true) + { + inValues.Add(Convert.ToInt64(item)); + } + else + { + inValues.Add(item); + } + } + } + var value = model.Args[1].MemberName; + string inValueString = null; + if (inValues?.Count > 0) + { + for (int i = 0; i < inValues.Count; i++) + { + inValueString += model.Data + "_" + i + ","; + } + } + if (inValueString.IsNullOrEmpty()) + { + return " (1=2) "; + } + else + { + inValueString = inValueString.TrimEnd(','); + return string.Format(" ({0} IN ({1})) ", value, inValueString); + } + } + + public virtual string Equals(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} = {1}) ", parameter.MemberName, parameter2.MemberName); ; + } + + public virtual string EqualsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + if (parameter2.MemberValue == null) + { + return string.Format(" ({0} is null) ", parameter.MemberName, parameter2.MemberName); + } + else + { + return string.Format(" ({0} = {1}) ", parameter.MemberName, parameter2.MemberName); + } + } + public virtual string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" (DATEDIFF(day,{0},{1})=0) ", parameter.MemberName, parameter2.MemberName); ; + } + + public virtual string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" (DATEDIFF({2},{0},{1})=0) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + + public virtual string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" (DATEADD({2},{1},{0})) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + + public virtual string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" (DATEADD(day,{1},{0})) ", parameter.MemberName, parameter2.MemberName); + } + + public virtual string Between(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + var parameter2 = model.Args[2]; + return string.Format(" ({0} BETWEEN {1} AND {2}) ", parameter.MemberName, parameter1.MemberName, parameter2.MemberName); + } + + public virtual 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 virtual 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 virtual string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + if (parameter.MemberName != null && parameter.MemberName is DateTime) + { + return string.Format(" DateName({0},'{1}') ", parameter2.MemberValue, parameter.MemberName); + } + else + { + return string.Format(" DateName({0},{1}) ", parameter2.MemberValue, parameter.MemberName); + } + } + + public virtual string GetStringJoinSelector(string result, string separator) + { + return $"string_agg(({result})::text,'{separator}') "; + } + + public virtual string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT)", parameter.MemberName); + } + + public virtual string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS BIGINT)", parameter.MemberName); + } + + public virtual string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS NVARCHAR(MAX))", parameter.MemberName); + } + + public virtual string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS UNIQUEIDENTIFIER)", parameter.MemberName); + } + + public virtual string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS FLOAT)", parameter.MemberName); + } + + public virtual string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS BIT)", parameter.MemberName); + } + + public virtual string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DATETIME)", parameter.MemberName); + } + + public virtual string ToDateShort(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DATE)", parameter.MemberName); + } + + public virtual string ToTime(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS TIME)", parameter.MemberName); + } + + public virtual string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS MONEY)", parameter.MemberName); + } + public virtual string Substring(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format("SUBSTRING({0},1 + {1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + + public virtual string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("LEN({0})", parameter.MemberName); + } + + public virtual string Replace(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format("REPLACE({0},{1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + + public virtual string AggregateSum(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("SUM({0})", parameter.MemberName); + } + + public virtual string AggregateAvg(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("AVG({0})", parameter.MemberName); + } + + public virtual string AggregateMin(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("MIN({0})", parameter.MemberName); + } + + public virtual string AggregateMax(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("MAX({0})", parameter.MemberName); + } + + public virtual string AggregateCount(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("COUNT({0})", parameter.MemberName); + } + + public virtual string AggregateDistinctCount(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("COUNT(DISTINCT {0} )", parameter.MemberName); + } + public virtual string AggregateDistinctSum(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("SUM(DISTINCT {0} )", parameter.MemberName); + } + + public virtual string MappingColumn(MethodCallExpressionModel model) + { + if (model.Args.Count == 1) + { + return string.Format("{0}", model.Args[0].MemberValue); + } + else + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("{0}", parameter1.MemberValue); + } + } + + public virtual string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("ISNULL({0},{1})", parameter.MemberName, parameter1.MemberName); + } + + public virtual string True() + { + return "( 1 = 1 ) "; + } + + public virtual string False() + { + return "( 1 = 2 ) "; + } + public virtual string TrueValue() + { + return "1 "; + } + + public virtual string FalseValue() + { + return "0"; + } + + public string GuidNew() + { + return "'" + Guid.NewGuid() + "' "; + } + + public string GetSelfAndAutoFill(string shortName, bool isSingle) + { + if (isSingle) return "*"; + else + return string.Format("{0}.*", shortName); + } + + public virtual string MergeString(params string[] strings) + { + return string.Join("+", strings); + } + + public virtual string Pack(string sql) + { + return "(" + sql + ")"; + } + + public virtual string EqualTrue(string fieldName) + { + return "( " + fieldName + "=1 )"; + } + + public virtual string Null() + { + return "NULL"; + } + + public virtual string GetDate() + { + return "GETDATE()"; + } + + public virtual string GetRandom() + { + return "NEWID()"; + } + + public virtual string CaseWhen(List> sqls) + { + StringBuilder reslut = new StringBuilder(); + foreach (var item in sqls) + { + if (item.Key == "IF") + { + reslut.AppendFormat(" ( CASE WHEN {0} ", item.Value); + } + else if (item.Key == "End") + { + reslut.AppendFormat("ELSE {0} END )", item.Value); + } + else if (item.Key == "Return") + { + reslut.AppendFormat(" THEN {0} ", item.Value); + } + else + { + reslut.AppendFormat(" WHEN {0} ", item.Value); + } + } + return reslut.ToString(); + } + public virtual string CharIndex(MethodCallExpressionModel model) + { + return string.Format("CHARINDEX ({0},{1})", model.Args[0].MemberName, model.Args[1].MemberName); + } + public virtual string CharIndexNew(MethodCallExpressionModel model) + { + return CharIndex(model); + } + + public virtual string ToVarchar(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR(MAX))", parameter.MemberName); + } + public virtual string BitwiseAnd(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} & {1}) ", parameter.MemberName, parameter2.MemberName); ; + } + public virtual string BitwiseInclusiveOR(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} | {1}) ", parameter.MemberName, parameter2.MemberName); ; + } + + public string Oracle_ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" to_date({0},{1}) ", parameter.MemberName, parameter2.MemberName); ; + } + public string Oracle_ToChar(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format("to_char({0},{1}) ", parameter.MemberName, parameter2.MemberName); ; + } + public string SqlServer_DateDiff(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" DATEDIFF({0},{1},{2}) ", parameter.MemberValue?.ToString().ToSqlFilter(), parameter2.MemberName, parameter3.MemberName); ; + } + + public virtual string FormatRowNumber(MethodCallExpressionModel model) + { + var str = model.Args[0].MemberValue.ObjToString(); + var array = model.Args.Skip(1).Select(it => it.IsMember ? it.MemberName : it.MemberValue).ToArray(); + if (array.Length == 1 && array[0] is string[]) + { + return string.Format("'" + str + "'", array[0] as string[]); ; + } + else + { + return string.Format("'" + str + "'", array); + } + } + public virtual string Format(MethodCallExpressionModel model) + { + + var str = "'" + model.Args[0].MemberValue.ObjToString() + "'"; + if (model.Args[0].MemberValue.ObjToString().StartsWith('\'') && model.Args[0].MemberValue.ObjToString().EndsWith('\'')) + { + str = model.Args[0].MemberValue.ObjToString(); + } + var revalue = MergeString("'", "$1", "'"); + if (revalue.Contains("concat(")) + { + return FormatConcat(model); + } + if (model.Args.Count == 2 && model.Args[1].MemberValue is string[]) + { + List args = GetStringFormatArgs(str, model.Args[1].MemberValue as string[]); + return Format(new MethodCallExpressionModel() + { + Args = args + }); ; + } + str = Regex.Replace(str, @"(\{\d+?\})", revalue); + var array = model.Args.Skip(1).Select(it => it.IsMember ? it.MemberName : (it.MemberValue == null ? "''" : it.MemberValue.ToSqlValue())) + .Select(it => ToString(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=it } + } + })).ToArray(); + return string.Format("" + str + "", array); + } + private string FormatConcat(MethodCallExpressionModel model) + { + + var str = "concat('" + model.Args[0].MemberValue.ObjToString() + "')"; + if (model.Args.Count == 2 && model.Args[1].MemberValue is string[]) + { + List args = GetStringFormatArgs(str, model.Args[1].MemberValue as string[]); + return Format(new MethodCallExpressionModel() + { + Args = args + }); ; + } + str = Regex.Replace(str, @"(\{\d+?\})", "',$1,'"); + var array = model.Args.Skip(1).Select(it => it.IsMember ? it.MemberName : (it.MemberValue == null ? "''" : it.MemberValue.ToSqlValue())) + .Select(it => ToString(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=it } + } + })).ToArray(); + return string.Format("" + str + "", array); + } + + public virtual string Abs(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" ABS({0}) ", parameter.MemberName); + } + + public virtual string Round(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ROUND({0},{1}) ", parameter.MemberName, parameter2.MemberName); + } + + public virtual string DateDiff(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" DATEDIFF({0},{1},{2}) ", parameter.MemberValue?.ToString().ToSqlFilter(), parameter2.MemberName, parameter3.MemberName); + } + public virtual string GreaterThan(MethodCallExpressionModel model) + { + //> + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} > {1}) ", parameter.MemberName, parameter2.MemberName); + } + public virtual string GreaterThanOrEqual(MethodCallExpressionModel model) + { + //>= + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} >= {1}) ", parameter.MemberName, parameter2.MemberName); + } + public virtual string LessThan(MethodCallExpressionModel model) + { + //< + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} < {1}) ", parameter.MemberName, parameter2.MemberName); + } + public virtual string LessThanOrEqual(MethodCallExpressionModel model) + { + //<= + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} <= {1}) ", parameter.MemberName, parameter2.MemberName); + } + + public virtual string Asc(MethodCallExpressionModel model) + { + return model.Args[0].MemberName + " ASC "; + } + public virtual string Desc(MethodCallExpressionModel model) + { + return model.Args[0].MemberName + " DESC "; + } + public virtual string Stuff(MethodCallExpressionModel model) + { + var parameter1 = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + var parameter4 = model.Args[3]; + return $" STUFF ({parameter1.MemberName}, {parameter2.MemberName}, {parameter3.MemberName}, {parameter4.MemberName}) "; + } + public virtual string Exists(MethodCallExpressionModel model) + { + var parameter1 = model.Args[0]; + if (model.Args.Count > 1) + { + var parameter2 = model.Args[1]; + if (UtilMethods.IsParentheses(parameter1.MemberName)) + { + parameter1.MemberName = $" {parameter1.MemberName.ObjToString().Trim().TrimEnd(')')} AND {parameter2.MemberName}) "; + } + else + { + parameter1.MemberName = $" {parameter1.MemberName} AND {parameter2.MemberName} "; + } + } + if (UtilMethods.IsParentheses(parameter1.MemberName)) + { + return $" Exists{parameter1.MemberName} "; + } + else + { + return $" Exists({parameter1.MemberName}) "; + } + } + + public virtual string GetDateString(string dateValue, string format) + { + return null; + } + public virtual string GetForXmlPath() + { + return null; + } + public virtual string JsonIndex(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"({parameter.MemberName}::json ->> {parameter1.MemberValue})"; + } + + + public virtual string JsonField(MethodCallExpressionModel model) + { + throw new NotImplementedException("Current database no support"); + } + + public virtual string JsonContainsFieldName(MethodCallExpressionModel model) + { + throw new NotImplementedException("Current database no support"); + } + + public virtual string JsonArrayLength(MethodCallExpressionModel model) + { + throw new NotImplementedException("Current database no support"); + } + + public virtual string JsonParse(MethodCallExpressionModel model) + { + throw new NotImplementedException("Current database no support"); + } + public virtual string JsonLike(MethodCallExpressionModel model) + { + model.Args[0].MemberName = ToString(model); + return Contains(model); + } + public virtual string Collate(MethodCallExpressionModel model) + { + var name = model.Args[0].MemberName; + return $" {name} collate Chinese_PRC_CS_AS "; + } + public virtual string AggregateSumNoNull(MethodCallExpressionModel model) + { + model.Args.Add(new MethodCallExpressionArgs() { MemberValue = 0, MemberName = 0 }); + var name = IsNull(model); + model.Args[0].MemberName = name; + return AggregateSum(model); + } + public virtual string AggregateAvgNoNull(MethodCallExpressionModel model) + { + model.Args.Add(new MethodCallExpressionArgs() { MemberValue = 0, MemberName = 0 }); + var name = IsNull(model); + model.Args[0].MemberName = name; + return AggregateAvg(model); + } + public virtual string JsonListObjectAny(MethodCallExpressionModel model) + { + throw new NotImplementedException("Current database no support"); + } + public virtual string JsonArrayAny(MethodCallExpressionModel model) + { + throw new NotImplementedException("Current database no support"); + } + public virtual string CompareTo(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + var parameterNameB = model.Args[1].MemberName; + return $"(case when {parameterNameA}>{parameterNameB} then 1 when {parameterNameA}={parameterNameB} then 0 else -1 end)"; + } + public virtual string SplitIn(MethodCallExpressionModel model) + { + var fullString = model.Args[0].MemberName + ""; + var value = model.Args[1].MemberName + ""; + var value1 = MergeString(value, "','"); + var value2 = MergeString("','", value); + var value3 = MergeString("','", value, "','"); + if (model.Args.Count == 3) + { + value1 = value1.Replace("','", model.Args[2].MemberName + ""); + value2 = value2.Replace("','", model.Args[2].MemberName + ""); + value3 = value3.Replace("','", model.Args[2].MemberName + ""); + } + var likeString1 = + StartsWith(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=fullString }, + new MethodCallExpressionArgs(){ IsMember=true, MemberName=value1 } + } + }); + var likeString2 = + EndsWith(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=fullString }, + new MethodCallExpressionArgs(){ IsMember=true, MemberName=value2 } + } + }); + var likeString3 = + Contains(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=fullString }, + new MethodCallExpressionArgs(){ IsMember=true, MemberName=value3 } + } + }); + return $" ({likeString1} or {likeString2} or {likeString3} or {fullString}={value} ) "; + } + + public string Like(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } + public string ToSingle(MethodCallExpressionModel model) + { + return ToDecimal(model); + } + public string ListAny(MethodCallExpressionModel model) + { + if (IsArrayAnyParameter(model)) + { + return ListArrayAny(model); + } + StringBuilder sb = new StringBuilder(); + if (model.Args[0].MemberValue != null && (model.Args[0].MemberValue as IList).Count > 0) + { + sb.Append(" ( "); + var listPar = model.Args[1].MemberValue as ListAnyParameter; + foreach (var item in (model.Args[0].MemberValue as IList)) + { + var sql = listPar.Sql; + if (sb.Length > 3) + { + sb.Append("OR"); + } + foreach (var columnInfo in listPar.Columns) + { + var replace = listPar.ConvetColumnFunc($"{listPar.Name}.{columnInfo.DbColumnName}"); + if (sql.Contains(replace)) + { + var value = columnInfo.PropertyInfo.GetValue(item); + var newValue = "null"; + if (value != null) + { + if (UtilMethods.IsNumber(columnInfo.UnderType.Name)) + { + newValue = value.ToString(); + } + else if (value is Enum) + { + newValue = Convert.ToInt64(value) + ""; + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.GuidType) + { + newValue = ToGuid(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=value.ToSqlValue(), + MemberName=value.ToSqlValue() + } + } + }); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.DateType) + { + newValue = ToDate(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=UtilMethods.GetConvertValue( value).ToSqlValue(), + MemberName=UtilMethods.GetConvertValue( value).ToSqlValue() + } + } + }); + } + else + { + newValue = value.ToSqlValue(); + } + } + if (columnInfo.UnderType == UtilConstants.StringType && model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.DbType == DbType.SqlServer) + { + if (model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DisableNvarchar != true) + { + if (columnInfo.SqlParameterDbType is System.Data.DbType type && type == System.Data.DbType.AnsiString) + { + + } + else + { + newValue = "N" + newValue; + } + } + } + sql = sql.Replace(replace, newValue); + } + } + sb.Append(sql); + } + sb.Append(" ) "); + } + var result = sb.ToString(); + if (result.IsNullOrEmpty()) + { + return " 1=2 "; + } + else + { + return result; + } + } + public string ListAll(MethodCallExpressionModel model) + { + if (IsArrayAnyParameter(model)) + { + return ListArrayAll(model); + } + StringBuilder sb = new StringBuilder(); + if (model.Args[0].MemberValue != null && (model.Args[0].MemberValue as IList).Count > 0) + { + sb.Append(" ( "); + var listPar = model.Args[1].MemberValue as ListAnyParameter; + foreach (var item in (model.Args[0].MemberValue as IList)) + { + var sql = listPar.Sql; + if (sb.Length > 3) + { + sb.Append("AND"); + } + foreach (var columnInfo in listPar.Columns) + { + var replace = listPar.ConvetColumnFunc($"{listPar.Name}.{columnInfo.DbColumnName}"); + if (sql.Contains(replace)) + { + var value = columnInfo.PropertyInfo.GetValue(item); + var newValue = "null"; + if (value != null) + { + if (UtilMethods.IsNumber(columnInfo.UnderType.Name)) + { + newValue = value.ToString(); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.GuidType) + { + newValue = ToGuid(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=value.ToSqlValue(), + MemberName=value.ToSqlValue() + } + } + }); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.DateType) + { + newValue = ToDate(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=UtilMethods.GetConvertValue( value).ToSqlValue(), + MemberName=UtilMethods.GetConvertValue( value).ToSqlValue() + } + } + }); + } + else + { + newValue = value.ToSqlValue(); + } + } + sql = sql.Replace(replace, newValue); + } + } + sb.Append(sql); + } + sb.Append(" ) "); + } + var result = sb.ToString(); + if (result.IsNullOrEmpty()) + { + return " 1=2 "; + } + else + { + return result; + } + } + public virtual string GetTableWithDataBase(string dataBaseName, string tableName) + { + return $"{dataBaseName}.{tableName}"; + } + + public virtual string Modulo(MethodCallExpressionModel model) + { + return "(" + model.Args[0].MemberName + " % " + model.Args[1].MemberName + ")"; + } + + private static bool IsArrayAnyParameter(MethodCallExpressionModel model) + { + var memberValue = model?.Args?.FirstOrDefault()?.MemberValue; + return UtilMethods.IsValueTypeArray(memberValue); + } + + private string ListArrayAny(MethodCallExpressionModel model) + { + StringBuilder sb = new StringBuilder(); + if (model.Args[0].MemberValue != null && (model.Args[0].MemberValue as IList).Count > 0) + { + sb.Append(" ( "); + var listPar = model.Args[1].MemberValue as ListAnyParameter; + foreach (var item in (model.Args[0].MemberValue as IList)) + { + var sql = listPar.Sql; + if (sb.Length > 3) + { + sb.Append("OR"); + } + foreach (var columnInfo in listPar.Columns) + { + var value = item; + var newValue = "null"; + if (value != null) + { + if (columnInfo.DbTableName != "String" && UtilMethods.IsNumber(columnInfo.UnderType.Name)) + { + newValue = value.ToString(); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.GuidType) + { + newValue = ToGuid(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=value.ToSqlValue(), + MemberName=value.ToSqlValue() + } + } + }); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.DateType) + { + newValue = ToDate(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=UtilMethods.GetConvertValue( value).ToSqlValue(), + MemberName=UtilMethods.GetConvertValue( value).ToSqlValue() + } + } + }); + } + else + { + newValue = value.ToSqlValue(); + if (columnInfo.EntityName == "String" && model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.DbType == DbType.SqlServer) + { + if (model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DisableNvarchar != true) + { + if (model.DataObject is EntityColumnInfo dc && dc.SqlParameterDbType is System.Data.DbType type && type == System.Data.DbType.AnsiString) + { + + } + else + { + newValue = "N" + newValue; + } + } + } + } + } + //Regex regex = new Regex("\@"); + if (!sql.Contains(ParameterKeyWord)) + { + sql = sql.Replace(" =)", $" = {newValue})"); + if (!sql.Contains(newValue)) + { + sql = sql.Replace(" )", $" = {newValue})"); + } + } + else + { + Regex reg = new Regex(ParameterKeyWord + @"MethodConst\d+"); + sql = reg.Replace(sql, it => + { + return " " + newValue + " "; + }); + } + + } + sb.Append(sql); + } + sb.Append(" ) "); + } + var result = sb.ToString(); + result = result.Replace(" = null)", " is null)"); + if (result.IsNullOrEmpty()) + { + return " 1=2 "; + } + else + { + return result; + } + } + + private string ListArrayAll(MethodCallExpressionModel model) + { + StringBuilder sb = new StringBuilder(); + if (model.Args[0].MemberValue != null && (model.Args[0].MemberValue as IList).Count > 0) + { + sb.Append(" ( "); + var listPar = model.Args[1].MemberValue as ListAnyParameter; + foreach (var item in (model.Args[0].MemberValue as IList)) + { + var sql = listPar.Sql; + if (sb.Length > 3) + { + sb.Append("AND"); + } + foreach (var columnInfo in listPar.Columns) + { + var value = item; + var newValue = "null"; + if (value != null) + { + if (columnInfo.DbTableName != "String" && UtilMethods.IsNumber(columnInfo.UnderType.Name)) + { + newValue = value.ToString(); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.GuidType) + { + newValue = ToGuid(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=value.ToSqlValue(), + MemberName=value.ToSqlValue() + } + } + }); + } + else if (columnInfo.UnderType == SqlSugar.UtilConstants.DateType) + { + newValue = ToDate(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ + MemberValue=UtilMethods.GetConvertValue( value).ToSqlValue(), + MemberName=UtilMethods.GetConvertValue( value).ToSqlValue() + } + } + }); + } + else + { + newValue = value.ToSqlValue(); + } + } + //Regex regex = new Regex("\@"); + if (!sql.Contains(ParameterKeyWord)) + { + sql = sql.Replace(" =)", $" = {newValue})"); + if (!sql.Contains(newValue)) + { + sql = sql.Replace(" )", $" = {newValue})"); + } + } + else + { + Regex reg = new Regex(ParameterKeyWord + @"MethodConst\d+"); + sql = reg.Replace(sql, it => + { + return " " + newValue + " "; + }); + } + + } + sb.Append(sql); + } + sb.Append(" ) "); + } + var result = sb.ToString(); + result = result.Replace(" = null)", " is null)"); + if (result.IsNullOrEmpty()) + { + return " 1=2 "; + } + else + { + return result; + } + } + + + private static List GetStringFormatArgs(string str, object array) + { + var args = new List() + { + new MethodCallExpressionArgs(){ + MemberName=str, + MemberValue=str + } + }; + args.AddRange((array as string[]).Select(it => new MethodCallExpressionArgs() + { + MemberValue = it, + MemberName = it, + IsMember = (it?.StartsWith('[') == true || it?.StartsWith('`') == true || it?.StartsWith('\"') == true) + && + (it?.EndsWith(']') == true || it?.EndsWith('`') == true || it?.EndsWith('\"') == true) + })); + return args; + } + + public virtual string WeekOfYear(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" DATE_PART('week', {parameterNameA})+1 "; + } + + public virtual string TrimEnd(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" CASE WHEN RIGHT({parameterNameA}, 1) = {parameterNameB} THEN LEFT({parameterNameA}, LENGTH({parameterNameA}) - 1) ELSE {parameterNameA} END "; + } + public virtual string TrimStart(MethodCallExpressionModel mode) + { + + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" CASE WHEN LEFT({parameterNameA}, 1) = {parameterNameB} THEN RIGHT({parameterNameA}, LEN({parameterNameA}) - 1) ELSE {parameterNameA} END "; + } + + public virtual string Left(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" LEFT({parameterNameA},{parameterNameB}) "; + } + public virtual string Right(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" RIGHT({parameterNameA},{parameterNameB}) "; + } + public virtual string PadLeft(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + var parameterNameC = mode.Args[2].MemberName; + return $" LPAD({parameterNameA},{parameterNameB},{parameterNameC}) "; + } + + public virtual string Floor(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" FLOOR({parameterNameA})"; + } + public virtual string Ceil(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" CEILING({parameterNameA}) "; + } + public virtual string NewUid(MethodCallExpressionModel mode) + { + return $" uuid_generate_v4() "; + } + public virtual string Coalesce(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" COALESCE({parameterNameA},{parameterNameB}) "; + } + public virtual string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = string.Join("|| ' ' ||", mode.Args[0].MemberValue as List); + } + var searchWord = mode.Args[1].MemberName; + return $"to_tsvector('chinese', {columns}) @@ to_tsquery('chinese', {searchWord})"; + } + + public virtual string PgsqlArrayContains(MethodCallExpressionModel model) + { + // 如果model.Args[1]是一个复杂类型,你可能需要将其转换为字符串或适当的格式 + // 在这里,我们假设它是一个可以直接转换为字符串的值 + string valueToFind = model.Args[1].MemberValue.ToString(); // 或者使用适当的转换方法 + var type = "text"; + if (model.Args[1].MemberValue is int) + { + type = "int4"; + } + else if (model.Args[1].MemberValue is long) + { + type = "int8"; + } + else if (model.Args[1].MemberValue is short) + { + type = "int2"; + } + if (!UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name)) + { + valueToFind = $"'{valueToFind}'"; + } + // PostgreSQL查询字符串 + string queryCondition = $"{model.Args[0].MemberName}::{type}[] @> ARRAY[{valueToFind}]"; + + // 如果需要处理NULL值或其他复杂情况,请在这里添加逻辑 + + return queryCondition; + } + public virtual string SelectFields(MethodCallExpressionModel model) + { + return string.Join(",", model.Args.Select(it => it.MemberName)); + } + public virtual string UNIX_TIMESTAMP(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + return $" UNIX_TIMESTAMP({parameterNameA}) "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/IDbMethods.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/IDbMethods.cs new file mode 100644 index 000000000..02274b9dd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/IDbMethods.cs @@ -0,0 +1,127 @@ +namespace SqlSugar +{ + public interface IDbMethods + { + string IIF(MethodCallExpressionModel model); + string HasNumber(MethodCallExpressionModel model); + string HasValue(MethodCallExpressionModel model); + string IsNullOrEmpty(MethodCallExpressionModel model); + string ToLower(MethodCallExpressionModel model); + string ToUpper(MethodCallExpressionModel model); + string Trim(MethodCallExpressionModel model); + string Contains(MethodCallExpressionModel model); + string ContainsArray(MethodCallExpressionModel model); + string ContainsArrayUseSqlParameters(MethodCallExpressionModel model); + string Equals(MethodCallExpressionModel model); + string EqualsNull(MethodCallExpressionModel model); + string DateIsSameDay(MethodCallExpressionModel model); + string DateIsSameByType(MethodCallExpressionModel model); + string DateAddByType(MethodCallExpressionModel model); + + string DateValue(MethodCallExpressionModel model); + string DateAddDay(MethodCallExpressionModel model); + string Between(MethodCallExpressionModel model); + string StartsWith(MethodCallExpressionModel model); + string EndsWith(MethodCallExpressionModel model); + string ToInt32(MethodCallExpressionModel model); + string GetStringJoinSelector(string result, string separator); + string ToInt64(MethodCallExpressionModel model); + string ToString(MethodCallExpressionModel model); + string ToVarchar(MethodCallExpressionModel model); + string ToGuid(MethodCallExpressionModel model); + string ToDouble(MethodCallExpressionModel model); + string ToBool(MethodCallExpressionModel model); + string CaseWhen(List> sqls); + string Substring(MethodCallExpressionModel model); + string ToDate(MethodCallExpressionModel model); + string ToDateShort(MethodCallExpressionModel model); + string ToTime(MethodCallExpressionModel model); + string ToDecimal(MethodCallExpressionModel model); + string Length(MethodCallExpressionModel model); + string Replace(MethodCallExpressionModel model); + string AggregateSum(MethodCallExpressionModel model); + string AggregateAvg(MethodCallExpressionModel model); + string AggregateMin(MethodCallExpressionModel model); + string AggregateMax(MethodCallExpressionModel model); + string AggregateCount(MethodCallExpressionModel model); + string AggregateDistinctCount(MethodCallExpressionModel model); + string AggregateDistinctSum(MethodCallExpressionModel model); + string MappingColumn(MethodCallExpressionModel model); + string IsNull(MethodCallExpressionModel model); + string GetSelfAndAutoFill(string shortName, bool isSingle); + string True(); + string False(); + string TrueValue(); + string FalseValue(); + string GuidNew(); + string MergeString(params string[] strings); + string EqualTrue(string value); + string Pack(string sql); + string Null(); + string GetDate(); + string GetRandom(); + string CharIndex(MethodCallExpressionModel model); + string CharIndexNew(MethodCallExpressionModel model); + string BitwiseAnd(MethodCallExpressionModel model); + string BitwiseInclusiveOR(MethodCallExpressionModel model); + + string Oracle_ToDate(MethodCallExpressionModel model); + string Oracle_ToChar(MethodCallExpressionModel model); + string SqlServer_DateDiff(MethodCallExpressionModel model); + string Format(MethodCallExpressionModel model); + string FormatRowNumber(MethodCallExpressionModel model); + string Abs(MethodCallExpressionModel model); + string Round(MethodCallExpressionModel model); + + string DateDiff(MethodCallExpressionModel model); + string GreaterThan(MethodCallExpressionModel model); + string GreaterThanOrEqual(MethodCallExpressionModel model); + string LessThan(MethodCallExpressionModel model); + string LessThanOrEqual(MethodCallExpressionModel model); + string Asc(MethodCallExpressionModel model); + string Desc(MethodCallExpressionModel model); + string Stuff(MethodCallExpressionModel model); + string RowNumber(MethodCallExpressionModel model); + string RowCount(MethodCallExpressionModel model); + string RowSum(MethodCallExpressionModel model); + string RowMin(MethodCallExpressionModel model); + string RowMax(MethodCallExpressionModel model); + string RowAvg(MethodCallExpressionModel model); + string Exists(MethodCallExpressionModel model); + string GetDateString(string dateValue, string format); + string GetForXmlPath(); + string JsonIndex(MethodCallExpressionModel model); + string JsonField(MethodCallExpressionModel model); + string JsonContainsFieldName(MethodCallExpressionModel model); + string JsonArrayLength(MethodCallExpressionModel model); + string JsonParse(MethodCallExpressionModel model); + string JsonLike(MethodCallExpressionModel model); + string Collate(MethodCallExpressionModel model); + string AggregateSumNoNull(MethodCallExpressionModel model); + string AggregateAvgNoNull(MethodCallExpressionModel model); + string JsonListObjectAny(MethodCallExpressionModel model); + string JsonArrayAny(MethodCallExpressionModel model); + string CompareTo(MethodCallExpressionModel model); + string SplitIn(MethodCallExpressionModel model); + string ListAny(MethodCallExpressionModel model); + string ListAll(MethodCallExpressionModel model); + string GetTableWithDataBase(string databaseName, string tableName); + string Modulo(MethodCallExpressionModel mode); + string Like(MethodCallExpressionModel mode); + string ToSingle(MethodCallExpressionModel mode); + string WeekOfYear(MethodCallExpressionModel mode); + string TrimEnd(MethodCallExpressionModel mode); + string TrimStart(MethodCallExpressionModel mode); + string Left(MethodCallExpressionModel mode); + string Right(MethodCallExpressionModel mode); + string PadLeft(MethodCallExpressionModel mode); + string Floor(MethodCallExpressionModel mode); + string Ceil(MethodCallExpressionModel mode); + string NewUid(MethodCallExpressionModel mode); + string FullTextContains(MethodCallExpressionModel mode); + string PgsqlArrayContains(MethodCallExpressionModel model); + string SelectFields(MethodCallExpressionModel model); + string Coalesce(MethodCallExpressionModel model); + string UNIX_TIMESTAMP(MethodCallExpressionModel model); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFunc.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFunc.cs new file mode 100644 index 000000000..3d241362d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFunc.cs @@ -0,0 +1,459 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public partial class SqlFunc + { + public static long UNIX_TIMESTAMP(DateTime dateTime) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static T Coalesce(T value1, T value2) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool FullTextContains(string[] columnNames, string keyword) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool FullTextContains(string columnName, string keyword) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int Floor(object value) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int Ceil(object value) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int WeekOfYear(DateTime fieldName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string Left(string value, int number) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string Right(string value, int number) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string PadLeft(string value, int number, char padChar) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool Like(string fieldName, string likeValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int Modulo(decimal numA, decimal numB) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int CompareTo(decimal numA, decimal numB) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int CompareTo(int numA, int numB) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int CompareTo(string strA, string strB) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int RowNumber(object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int RowNumber(object orderByField) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static int Rank(object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int Rank(object orderByField) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int DenseRank(object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int DenseRank(object orderByField) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static int RowCount(object countFiledName, object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int RowCount() + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowSum(TRestult filedName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowSum(TRestult filedName, object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowMax(TRestult filedName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowMax(TRestult filedNameobject, object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowMin(TRestult filedName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowMin(TRestult filedName, object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowAvg(TRestult filedName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static TRestult RowAvg(TRestult filedName, object orderByField, object partitionBy) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string JsonField(object json, string fieldName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string JsonIndex(object json, int jsonIndex) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string JsonField(object json, string fieldName, string includeFieldName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static string JsonField(object json, string fieldName, string includeFieldName, string ThenIncludeFieldName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string JsonField(object json, string fieldName, string includeFieldName, string ThenIncludeFieldName, string ThenIncludeFieldName2) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string JsonField(object json, string fieldName, string includeFieldName, string ThenIncludeFieldName, string ThenIncludeFieldName2, string ThenIncludeFieldName3) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool JsonContainsFieldName(object json, string fieldName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static int JsonArrayLength(object json) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static string JsonParse(object json) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static bool JsonLike(object json, string likeStr) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static T Desc(T value) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static T Asc(T value) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static int DateDiff(DateType dateType, DateTime littleTime, DateTime bigTime) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool GreaterThan(object thisValue, object gtValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static string Stuff(string sourceString, int start, int length, string AddString) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static bool GreaterThanOrEqual(object thisValue, object gtValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool GreaterThan_LinqDynamicCore(object thisValue, object ltValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool LessThan(object thisValue, object ltValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static bool LessThan_LinqDynamicCore(object thisValue, object ltValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool LessThanOrEqual(object thisValue, object ltValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool HasNumber(object thisValue) + { + return thisValue.ObjToInt() > 0; + } + public static bool HasValue(object thisValue) + { + return thisValue.HasValue(); + } + public static bool IsNullOrEmpty(object thisValue) + { + return thisValue.IsNullOrEmpty(); + } + public static string ToLower(object thisValue) + { + return thisValue == null ? null : thisValue.ToString().ToLower(); + } + public static string ToUpper(object thisValue) + { + return thisValue == null ? null : thisValue.ToString().ToUpper(); + } + public static string Trim(object thisValue) + { + return thisValue == null ? null : thisValue.ToString().Trim(); + } + public static string TrimEnd(object thisValue, string trimChar) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string TrimStart(object thisValue, string trimChar) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool Contains(string thisValue, string parameterValue) + { + return thisValue.Contains(parameterValue); + } + public static bool ContainsArray(T[] thisValue, object InField) + { + return thisValue.Contains((T)InField); + } + public static bool ContainsArray(List thisValue, object InField) + { + return thisValue.Contains((T)InField); + } + public static bool ContainsArrayUseSqlParameters(List thisValue, object InField) + { + return thisValue.Contains((T)InField); + } + public static bool ContainsArrayUseSqlParameters(T[] thisValue, object InField) + { + return thisValue.Contains((T)InField); + } + public static bool StartsWith(string thisValue, string parameterValue) + { + return thisValue.StartsWith(parameterValue); + } + public static bool EndsWith(string thisValue, string parameterValue) + { + return thisValue.EndsWith(parameterValue); + } + public new static bool Equals(object thisValue, object parameterValue) + { + return thisValue.Equals(parameterValue); + } + public static bool EqualsNull(object thisValue, object parameterValue) + { + return thisValue.Equals(parameterValue); + } + + public static bool Exists(string subQueryableName_Or_OneToOnePropertyName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool Exists(valueType subQueryableName_Or_OneToOnePropertyName) where valueType : struct + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool Exists(string subQueryableName_Or_OneToOnePropertyName, List conditionalModels) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool Exists(valueType subQueryableName_Or_OneToOnePropertyName, List conditionalModels) where valueType : struct + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool DateIsSame(DateTime date1, DateTime date2) + { + return date1.ToString("yyyy-MM-dd") == date2.ToString("yyyy-MM-dd"); + } + public static bool DateIsSame(DateTime? date1, DateTime? date2) + { + return ((DateTime)date1).ToString("yyyy-MM-dd") == ((DateTime)date2).ToString("yyyy-MM-dd"); + } + public static bool DateIsSame(DateTime date1, DateTime date2, DateType dataType) { throw new NotSupportedException("Can only be used in expressions"); } + public static DateTime DateAdd(DateTime date, int addValue, DateType dataType) { throw new NotSupportedException("Can only be used in expressions"); } + public static DateTimeOffset DateAdd(DateTimeOffset date, int addValue, DateType dataType) { throw new NotSupportedException("Can only be used in expressions"); } + public static DateTime DateAdd(DateTime date, int addValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static DateTimeOffset DateAdd(DateTimeOffset date, int addValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int DateValue(DateTime date, DateType dataType) { throw new NotSupportedException("Can only be used in expressions"); } + public static int DateValue(DateTimeOffset date, DateTimeOffset dataType) { throw new NotSupportedException("Can only be used in expressions"); } + public static bool Between(object value, object start, object end) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult IIF(bool isTrue, TResult thenValue, TResult elseValue) { return isTrue ? thenValue : elseValue; } + public static TResult IsNull(TResult thisValue, TResult ifNullValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static string MergeString(string value1, string value2) { throw new NotSupportedException("Can only be used in expressions"); } + public static string MergeString(string value1, string value2, string value3) { throw new NotSupportedException("Can only be used in expressions"); } + public static string MergeString(string value1, string value2, string value3, string value4) { throw new NotSupportedException("Can only be used in expressions"); } + public static string MergeString(string value1, string value2, string value3, string value4, string value5) { throw new NotSupportedException("Can only be used in expressions"); } + public static string MergeString(string value1, string value2, string value3, string value4, string value5, string value6) { throw new NotSupportedException("Can only be used in expressions"); } + public static string MergeString(string value1, string value2, string value3, string value4, string value5, string value6, string value7) { throw new NotSupportedException("Can only be used in expressions"); } + public static int ToInt32(object value) { return value.ObjToInt(); } + public static float ToSingle(object value) { return Convert.ToSingle(value); } + public static long ToInt64(object value) { return Convert.ToInt64(value); } + /// + /// yyyy-MM-dd HH:mm:ss.fff + /// + /// + /// + public static DateTime ToDate(object value) { return value.ObjToDate(); } + public static DateTime ToDateShort(object value) { return value.ObjToDate(); } + /// + ///HH:mm:ss + /// + /// + /// + public static TimeSpan ToTime(object value) { throw new NotSupportedException("Can only be used in expressions"); } + public static string ToString(object value) { return value.ObjToString(); } + public static string ToVarchar(object value) { return value.ObjToString(); } + public static decimal ToDecimal(object value) { return value.ObjToDecimal(); } + public static Guid ToGuid(object value) { return Guid.Parse(value.ObjToString()); } + public static Guid NewUid() { throw new NotSupportedException("Can only be used in expressions"); } + public static double ToDouble(object value) { return value.ObjToMoney(); } + public static bool ToBool(object value) { return value.ObjToBool(); } + public static string Substring(object value, int index, int length) { return value.ObjToString().Substring(index, length); } + public static string Replace(object value, string oldChar, string newChar) { return value.ObjToString().Replace(oldChar, newChar); } + public static int Length(object value) { return value.ObjToString().Length; } + public static TResult AggregateSum(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult AggregateSumNoNull(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static string Collate(string thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult AggregateAvg(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult AggregateAvgNoNull(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult AggregateMin(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult AggregateMax(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int AggregateCount(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int AggregateDistinctCount(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int AggregateDistinctSum(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult MappingColumn(TResult type, string newColumnName) { throw new NotSupportedException("Can only be used in expressions"); } + public static TResult MappingColumn(string newColumnName) { throw new NotSupportedException("Can only be used in expressions"); } + /// + ///Example: new NewT(){name=SqlFunc.GetSelfAndAutoFill(it)} Generated SQL it.* + /// + /// + /// + /// + public static TResult GetSelfAndAutoFill(TResult value) { throw new NotSupportedException("Can only be used in expressions"); } + public static DateTime GetDate() { throw new NotSupportedException("Can only be used in expressions"); } + public static string GetRandom() { throw new NotSupportedException("Can only be used in expressions"); } + + + public static T Abs(T value) { throw new NotSupportedException("Can only be used in expressions"); } + public static T Round(T value, int precision) { throw new NotSupportedException("Can only be used in expressions"); } + + /// + /// Subquery + /// + /// + /// + public static Subqueryable Subqueryable() where T : class, new() { throw new NotSupportedException("Can only be used in expressions"); } + public static CaseThen IF(bool condition) { throw new NotSupportedException("Can only be used in expressions"); } + [Obsolete("多库下参数顺序不一至,为了保证多库下更好体验请使用 SqlFunc.CharIndexNew")] + public static int CharIndex(string findChar, string searchValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int CharIndexNew(string stringValue, string charValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int BitwiseAnd(int left, int right) { throw new NotSupportedException("Can only be used in expressions"); } + public static int BitwiseInclusiveOR(int left, int right) { throw new NotSupportedException("Can only be used in expressions"); } + public static int BitwiseAnd(long left, long right) { throw new NotSupportedException("Can only be used in expressions"); } + public static int BitwiseInclusiveOR(long left, long right) { throw new NotSupportedException("Can only be used in expressions"); } + public static DateTime Oracle_ToDate(string date, string format) { throw new NotSupportedException("Can only be used in expressions"); } + public static string Oracle_ToChar(DateTime date, string format) { throw new NotSupportedException("Can only be used in expressions"); } + public static string Oracle_ToChar(object objValue, string format) { throw new NotSupportedException("Can only be used in expressions"); } + public static int SqlServer_DateDiff(string dateType, DateTime date1, DateTime date2) { throw new NotSupportedException("Can only be used in expressions"); } + + public static bool JsonListObjectAny(object jsonListObject, string fieldName, object value) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool PgsqlArrayContains(object jsonArray, object arrayValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool JsonArrayAny(object jsonArray, object arrayValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static bool SplitIn(string CommaSegmentationString, string inValue) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static bool SplitIn(string CommaSegmentationString, string inValue, char splitChar) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static bool ListAny(List listConstant, Expression> expression) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static bool ListAll(List listConstant, Expression> expression) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static string OnlyInSelectConvertToString(string stringValue, MethodInfo methodInfo) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static void SelectFields(string fieldName1) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static void SelectFields(string fieldName1, string fieldName2) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static void SelectFields(string fieldName1, string fieldName2, string fieldName3) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static void SelectFields(string fieldName1, string fieldName2, string fieldName3, string fieldName4) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static void SelectFields(string fieldName1, string fieldName2, string fieldName3, string fieldName4, string fieldName5) + { + throw new NotSupportedException("Can only be used in expressions"); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs new file mode 100644 index 000000000..85f8c3a63 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs @@ -0,0 +1,24 @@ +namespace SqlSugar +{ + public static class SqlFuncExtendsion + { + internal static List TableInfos = new List(); + public static string GetConfigValue(this object field) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string GetConfigValue(this object field, string uniqueCode) + { + throw new NotSupportedException("Can only be used in expressions"); + } + + public static FieldType SelectAll(this FieldType field) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static FieldType SelectAll(this FieldType field, string singleTableQueryShortName) + { + throw new NotSupportedException("Can only be used in expressions"); + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFuncExternal.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFuncExternal.cs new file mode 100644 index 000000000..59b73f514 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/DbMethods/SqlFuncExternal.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class SqlFuncExternal + { + public string UniqueMethodName { get; set; } + public Func MethodValue { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ExpressionContext.cs new file mode 100644 index 000000000..737040363 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ExpressionContext.cs @@ -0,0 +1,266 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class ExpressionContext : ExpResolveAccessory + { + #region Fields + private bool _IsSingle = true; + private IDbMethods _DbMehtods { get; set; } + #endregion + + #region Properties + public virtual ExpressionContextCase Case { get; set; } + public ExpressionOutParameter SugarContext { get; set; } + public IDbMethods DbMehtods + { + get + { + if (_DbMehtods == null) + { + _DbMehtods = new DefaultDbMethod(); + } + return _DbMehtods; + } + set + { + _DbMehtods = value; + } + } + public int SubQueryIndex { get; set; } + public int JoinIndex { get; set; } + public bool IsAsAttr { get; set; } + public int Index { get; set; } + public int ParameterIndex { get; set; } + public string SingleTableNameSubqueryShortName { get; set; } + public string CurrentShortName { get; set; } + public MappingColumnList MappingColumns { get; set; } + public MappingTableList MappingTables { get; set; } + public IgnoreColumnList IgnoreComumnList { get; set; } + public bool PgSqlIsAutoToLower { get; set; } + public bool? TableEnumIsString { get; set; } + public List SqlFuncServices { get; set; } + public Expression RootExpression { get; set; } + public bool IsSingle + { + get + { + return _IsSingle; + } + set + { + _IsSingle = value; + } + } + public bool IsJoin + { + get + { + return !IsSingle; + } + } + public List JoinQueryInfos { get; set; } + public ResolveExpressType ResolveType { get; set; } + public Expression Expression { get; set; } + public ExpressionResult Result + { + get + { + if (base._Result == null) + { + this.Result = new ExpressionResult(this.ResolveType); + } + return base._Result; + } + set + { + this._Result = value; + } + } + public List Parameters + { + get + { + if (base._Parameters == null) + base._Parameters = new List(); + return base._Parameters; + } + set + { + base._Parameters = value; + } + } + public virtual string SqlParameterKeyWord + { + get + { + return "@"; + } + } + public virtual string SqlTranslationLeft { get { return "["; } } + public virtual string SqlTranslationRight { get { return "]"; } } + public virtual Action InitMappingInfo { get; set; } + public virtual Action RefreshMapping { get; set; } + public virtual Type SubTableType { get; set; } + public string MethodName { get; set; } + #endregion + + #region Core methods + public void Resolve(Expression expression, ResolveExpressType resolveType) + { + this.ResolveType = resolveType; + this.Expression = expression; + BaseResolve resolve = new BaseResolve(new ExpressionParameter() { CurrentExpression = this.Expression, Context = this }); + resolve.Start(); + } + public void Clear() + { + base._Result = null; + base._Parameters = new List(); + } + public ExpressionContext GetCopyContext() + { + ExpressionContext copyContext = (ExpressionContext)Activator.CreateInstance(this.GetType(), true); + copyContext.Index = this.Index; + copyContext.InitMappingInfo = this.InitMappingInfo; + copyContext.RefreshMapping = this.RefreshMapping; + copyContext.ParameterIndex = this.ParameterIndex; + copyContext.PgSqlIsAutoToLower = this.PgSqlIsAutoToLower; + copyContext.IsSingle = this.IsSingle; + copyContext.RootExpression = this.RootExpression; + copyContext.TableEnumIsString = this.TableEnumIsString; + copyContext.SugarContext = this.SugarContext; + return copyContext; + } + public ExpressionContext GetCopyContextWithMapping() + { + ExpressionContext copyContext = (ExpressionContext)Activator.CreateInstance(this.GetType(), true); + copyContext.Index = this.Index; + copyContext.ParameterIndex = this.ParameterIndex; + copyContext.MappingColumns = this.MappingColumns; + copyContext.MappingTables = this.MappingTables; + copyContext.IgnoreComumnList = this.IgnoreComumnList; + copyContext.SqlFuncServices = this.SqlFuncServices; + copyContext.InitMappingInfo = this.InitMappingInfo; + copyContext.RefreshMapping = this.RefreshMapping; + copyContext.PgSqlIsAutoToLower = this.PgSqlIsAutoToLower; + copyContext.TableEnumIsString = this.TableEnumIsString; + copyContext.IsSingle = this.IsSingle; + copyContext.RootExpression = this.RootExpression; + copyContext.SugarContext = this.SugarContext; + return copyContext; + } + #endregion + + #region Override methods + public virtual string GetLimit() { return null; } + public virtual string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + var name = (mappingInfo == null ? entityName : mappingInfo.DbTableName); + if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else if (name.Contains('.')) + { + return string.Join(".", name.Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else + { + return SqlTranslationLeft + name + SqlTranslationRight; + } + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public virtual string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord || columnName.Substring(0, 1) == "@") + { + return columnName; + } + if (this.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) + { + if (IsTranslationText(columnName.Replace(" ", ""))) return columnName; + else + return GetTranslationText(columnName); + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public virtual string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return mappingInfo == null ? propertyName : mappingInfo.DbColumnName; + } + else + { + return propertyName; + } + } + public virtual bool IsTranslationText(string name) + { + var result = name.IsContainsIn(SqlTranslationLeft, SqlTranslationRight, UtilConstants.Space, ExpressionConst.LeftParenthesis, ExpressionConst.RightParenthesis); + return result; + } + public virtual string GetTranslationText(string name) + { + return SqlTranslationLeft + name + SqlTranslationRight; + } + public virtual string GetAsString(string asName, string fieldValue) + { + if (fieldValue.Contains(".*") || fieldValue == "*") return fieldValue; + return string.Format(" {0} {1} {2} ", GetTranslationColumnName(fieldValue), "AS", GetTranslationColumnName(asName)); + } + + public virtual string GetAsString2(string asName, string fieldValue) + { + if (fieldValue.Contains(".*") || fieldValue == "*") return fieldValue; + return string.Format(" {0} {1} {2} ", fieldValue, "AS", GetTranslationColumnName(asName)); + } + + public virtual string GetEqString(string eqName, string fieldValue) + { + return string.Format(" {0} {1} {2} ", GetTranslationColumnName(eqName), "=", GetTranslationColumnName(fieldValue)); + } + + public virtual string GetAsString(string asName, string fieldValue, string fieldShortName) + { + if (fieldValue.Contains(".*") || fieldValue == "*") return fieldValue; + return string.Format(" {0} {1} {2} ", GetTranslationColumnName(fieldShortName + "." + fieldValue), "AS", GetTranslationColumnName(asName)); + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve.cs new file mode 100644 index 000000000..8cdb73c1f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve.cs @@ -0,0 +1,97 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + /// + /// BaseResolve-Append + /// + public partial class BaseResolve + { + + private BaseResolve() + { + + } + public BaseResolve(ExpressionParameter parameter) + { + this.Expression = parameter.CurrentExpression; + this.Context = parameter.Context; + this.BaseParameter = parameter; + } + + public BaseResolve Start() + { + Expression expression; + ExpressionParameter parameter; + SetParameter(out expression, out parameter); + if (expression is LambdaExpression) + { + return new LambdaExpressionResolve(parameter); + } + else if (expression is BinaryExpression && expression.NodeType == ExpressionType.Coalesce) + { + return new CoalesceResolveItems(parameter); + } + else if (expression is BinaryExpression) + { + return new BinaryExpressionResolve(parameter); + } + else if (expression is BlockExpression) + { + Check.ThrowNotSupportedException("BlockExpression"); + } + else if (expression is ConditionalExpression) + { + return new ConditionalExpressionResolve(parameter); + } + else if (expression is MethodCallExpression) + { + return new MethodCallExpressionResolve(parameter); + } + else if (expression is MemberExpression && ((MemberExpression)expression).Expression == null) + { + return new MemberNoExpressionResolve(parameter); + } + else if (expression is MemberExpression && ((MemberExpression)expression).Expression.NodeType == ExpressionType.Constant) + { + return new MemberConstExpressionResolve(parameter); + } + else if (expression is MemberExpression && ((MemberExpression)expression).Expression.NodeType == ExpressionType.New) + { + return new MemberNewExpressionResolve(parameter); + } + else if (expression is ConstantExpression) + { + return new ConstantExpressionResolve(parameter); + } + else if (expression is MemberExpression) + { + return new MemberExpressionResolve(parameter); + } + else if (expression is UnaryExpression) + { + return new UnaryExpressionResolve(parameter); + } + else if (expression is MemberInitExpression) + { + return new MemberInitExpressionResolve(parameter); + } + else if (expression is NewExpression) + { + return new NewExpressionResolve(parameter); + } + else if (expression is NewArrayExpression) + { + return new NewArrayExpessionResolve(parameter); + } + else if (expression is ParameterExpression) + { + return new TypeParameterExpressionReolve(parameter); + } + else if (expression?.NodeType.IsIn(ExpressionType.NewArrayBounds) == true) + { + Check.ThrowNotSupportedException("ExpressionType.NewArrayBounds"); + } + return null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Append.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Append.cs new file mode 100644 index 000000000..2bd080fd8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Append.cs @@ -0,0 +1,296 @@ +using System.Linq.Expressions; +using System.Reflection; +namespace SqlSugar +{ + /// + /// BaseResolve-Append + /// + public partial class BaseResolve + { + protected void AppendMember(ExpressionParameter parameter, bool? isLeft, object appendValue) + { + + Context.ParameterIndex++; + if (isLeft == true) + { + appendValue += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index; + } + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, appendValue.ObjToString()); + } + else + { + this.Context.Result.Append(appendValue); + } + } + protected void AppendValue(ExpressionParameter parameter, bool? isLeft, object value) + { + if (parameter.BaseExpression is BinaryExpression || parameter.BaseExpression == null) + { + var oppoSiteExpression = isLeft == true ? parameter.BaseParameter.RightExpression : parameter.BaseParameter.LeftExpression; + + if (value is MapperSql) + { + ApppendMapperSql(parameter, isLeft, value); + } + else if (parameter.CurrentExpression is MethodCallExpression || parameter.CurrentExpression is ConditionalExpression || parameter.CurrentExpression.NodeType == ExpressionType.Coalesce) + { + AppendMethod(parameter, isLeft, value); + } + else if (oppoSiteExpression is MemberExpression) + { + AppendMember(parameter, isLeft, value, oppoSiteExpression); + } + else if (ExpressionTool.RemoveConvert(oppoSiteExpression) is MemberExpression) + { + AppendMember(parameter, isLeft, value, ExpressionTool.RemoveConvert(oppoSiteExpression)); + } + else if ((oppoSiteExpression is UnaryExpression && (oppoSiteExpression as UnaryExpression).Operand is MemberExpression)) + { + value = AppendUnaryExp(parameter, isLeft, value, oppoSiteExpression); + } + else + { + value = AppendOther(parameter, isLeft, value); + } + } + } + private object AppendOther(ExpressionParameter parameter, bool? isLeft, object value) + { + var appendValue = this.Context.SqlParameterKeyWord + ExpressionConst.Const + Context.ParameterIndex; + Context.ParameterIndex++; + if (value?.GetType().IsEnum() == true) + { + if (this.Context.TableEnumIsString == true) + { + value = value.ToString(); + } + else + { + value = Convert.ToInt64(value); + } + } + this.Context.Parameters.Add(new SugarParameter(appendValue, value)); + appendValue = string.Format(" {0} ", appendValue); + if (isLeft == true) + { + appendValue += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index; + } + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, appendValue); + } + else + { + this.Context.Result.Append(appendValue); + } + + return value; + } + private object AppendUnaryExp(ExpressionParameter parameter, bool? isLeft, object value, Expression oppoSiteExpression) + { + string appendValue = Context.SqlParameterKeyWord + + ((MemberExpression)(oppoSiteExpression as UnaryExpression).Operand).Member.Name + + Context.ParameterIndex; + if (value.ObjToString() != "NULL" && !parameter.ValueIsNull) + { + value = this.Context.TableEnumIsString == true ? value.ToString() : value; + this.Context.Parameters.Add(new SugarParameter(appendValue, value)); + } + else + { + appendValue = value.ObjToString(); + } + Context.ParameterIndex++; + appendValue = string.Format(" {0} ", appendValue); + if (isLeft == true) + { + appendValue += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index; + } + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, appendValue); + } + else + { + this.Context.Result.Append(appendValue); + } + + return value; + } + private void AppendMember(ExpressionParameter parameter, bool? isLeft, object value, Expression oppoSiteExpression) + { + string appendValue = Context.SqlParameterKeyWord + + ((MemberExpression)oppoSiteExpression).Member.Name + + Context.ParameterIndex; + if (IsNullValue(parameter, value)) + { + appendValue = $" NULL "; + parameter.BaseParameter.ValueIsNull = true; + } + else if (value.ObjToString() != "NULL" && !parameter.ValueIsNull) + { + EntityColumnInfo columnInfo = GetColumnInfo(oppoSiteExpression); + if (columnInfo?.SqlParameterDbType != null && columnInfo.SqlParameterDbType is System.Data.DbType) + { + var p = new SugarParameter(appendValue, value, (System.Data.DbType)columnInfo.SqlParameterDbType); + if (columnInfo.SqlParameterSize != null) + { + p.Size = columnInfo.SqlParameterSize.ObjToInt(); + } + this.Context.Parameters.Add(p); + } + else if (UtilMethods.IsParameterConverter(columnInfo)) + { + SugarParameter p = UtilMethods.GetParameterConverter(this.Context.ParameterIndex, this.Context.SugarContext.Context, value, oppoSiteExpression, columnInfo); + appendValue = p.ParameterName; + this.Context.Parameters.Add(p); + } + else if (parameter?.BaseParameter?.CommonTempData.ObjToString() == "IsJson=true") + { + this.Context.Parameters.Add(new SugarParameter(appendValue, new SerializeService().SerializeObject(value)) { IsJson = true }); + } + else if (parameter?.BaseParameter?.CommonTempData.ObjToString() == "IsArray=true") + { + this.Context.Parameters.Add(new SugarParameter(appendValue, value) { IsArray = true }); + } + else if (value != null && (value is Enum) && this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString == true) + { + this.Context.Parameters.Add(new SugarParameter(appendValue, Convert.ToString(value))); + } + else if (this.Context + ?.SugarContext + ?.Context + ?.CurrentConnectionConfig + ?.MoreSettings + ?.IsCorrectErrorSqlParameterName == true + && columnInfo?.PropertyName != null + && !columnInfo.PropertyName.IsRegexWNoContainsChinese()) + { + appendValue = (Context.SqlParameterKeyWord + "p" + appendValue.GetHashCode() + "no" + Context.ParameterIndex) + .Replace("-", ""); + this.Context.Parameters.Add(new SugarParameter(appendValue, value)); + } + else + { + var p = new SugarParameter(appendValue, value); + if (p.DbType == System.Data.DbType.String && this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DisableNvarchar == true) + { + p.DbType = System.Data.DbType.AnsiString; + } + this.Context.Parameters.Add(p); + } + } + else + { + appendValue = value.ObjToString(); + } + Context.ParameterIndex++; + appendValue = string.Format(" {0} ", appendValue); + if (isLeft == true) + { + appendValue += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index; + } + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, appendValue); + } + else + { + this.Context.Result.Append(appendValue); + } + } + private void AppendMethod(ExpressionParameter parameter, bool? isLeft, object value) + { + var appendValue = value; + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, appendValue.ObjToString()); + } + else + { + this.Context.Result.Append(appendValue); + } + this.AppendOpreator(parameter, isLeft); + } + private void ApppendMapperSql(ExpressionParameter parameter, bool? isLeft, object value) + { + var sql = ((MapperSql)value).Sql; + if (isLeft == true) + { + sql += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index; + } + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, sql); + } + else + { + this.Context.Result.Append(sql); + } + } + protected void AppendOpreator(ExpressionParameter parameter, bool? isLeft) + { + if (isLeft == true) + { + this.Context.Result.Append(" " + ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index); + } + } + protected string AppendParameter(object paramterValue) + { + string parameterName = this.Context.SqlParameterKeyWord + "constant" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; ; + this.Context.Parameters.Add(new SugarParameter(parameterName, paramterValue)); + return parameterName; + } + protected string AppendParameter(SugarParameter p) + { + p.ParameterName = p.ParameterName + this.Context.ParameterIndex; + this.Context.ParameterIndex++; ; + this.Context.Parameters.Add(p); + return p.ParameterName; + } + protected void AppendNot(object Value) + { + var isAppend = !this.Context.Result.Contains(ExpressionConst.FormatSymbol); + var lastCharIsSpace = this.Context.Result.LastCharIsSpace; + if (isAppend) + { + this.Context.Result.Append(lastCharIsSpace ? "NOT" : " NOT"); + } + else + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, "NOT"); + } + } + protected void AppendNegate(object Value) + { + var isAppend = !this.Context.Result.Contains(ExpressionConst.FormatSymbol); + var lastCharIsSpace = this.Context.Result.LastCharIsSpace; + if (isAppend) + { + this.Context.Result.Append(lastCharIsSpace ? "-" : " -"); + } + else + { + this.Context.Result.Replace(ExpressionConst.FormatSymbol, "-"); + } + } + private void AppendOnlyInSelectConvertToString(ExpressionParameter parameter, Expression item, string asName) + { + var name = GetNewExpressionValue((item as MethodCallExpression)?.Arguments[0]); + var methodInfo = ExpressionTool.DynamicInvoke(((item as MethodCallExpression)?.Arguments[1])); + if (this.Context.SugarContext.QueryBuilder.QueryableFormats == null) + this.Context.SugarContext.QueryBuilder.QueryableFormats = new List(); + this.Context.SugarContext.QueryBuilder.QueryableFormats.Add(new QueryableFormat() + { + Format = "", + PropertyName = asName, + MethodName = "OnlyInSelectConvertToString", + MethodInfo = (MethodInfo)methodInfo + }); + parameter.Context.Result.Append(this.Context.GetAsString2(asName, name)); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Helper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Helper.cs new file mode 100644 index 000000000..1d280804c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Helper.cs @@ -0,0 +1,207 @@ +using System.Linq.Expressions; +using System.Reflection; +namespace SqlSugar +{ + /// + /// BaseResolve-Helper + /// + public partial class BaseResolve + { + #region Set Method + protected void SetNavigateResult() + { + if (this.Context != null) + { + if (this.Context.Result != null) + { + this.Context.Result.IsNavicate = true; + } + } + } + private void SetParameter(out Expression expression, out ExpressionParameter parameter) + { + Context.Index++; + expression = this.Expression; + parameter = new ExpressionParameter() + { + Context = this.Context, + CurrentExpression = expression, + IsLeft = this.IsLeft, + BaseExpression = this.ExactExpression, + BaseParameter = this.BaseParameter, + Index = Context.Index + }; + } + + #endregion + + #region Get Mehtod + protected object GetMemberValue(object value, Expression exp) + { + if (exp is MemberExpression) + { + var member = (exp as MemberExpression); + var memberParent = member.Expression; + if (memberParent != null && this.Context?.SugarContext?.Context != null) + { + var entity = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(memberParent.Type); + var columnInfo = entity.Columns.FirstOrDefault(it => it.PropertyName == member.Member.Name); + if (columnInfo?.SqlParameterDbType is Type) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + this.Context.ParameterIndex }) as SugarParameter; + value = p.Value; + } + } + } + + return value; + } + private string GetAsName(Expression item, object shortName, PropertyInfo property) + { + string asName; + var propertyName = property.Name; + var dbColumnName = propertyName; + var mappingInfo = this.Context.MappingColumns.FirstOrDefault(it => it.EntityName == item.Type.Name && it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo.HasValue()) + { + dbColumnName = mappingInfo.DbColumnName; + } + asName = this.Context.GetTranslationText(item.Type.Name + "." + propertyName); + if (Context.IsJoin) + { + this.Context.Result.Append(Context.GetAsString(asName, dbColumnName, shortName.ObjToString())); + } + else + { + this.Context.Result.Append(Context.GetAsString(asName, dbColumnName)); + } + + return asName; + } + private string GetAsNameAndShortName(Expression item, object shortName, PropertyInfo property) + { + string asName; + var propertyName = property.Name; + var dbColumnName = propertyName; + var mappingInfo = this.Context.MappingColumns.FirstOrDefault(it => it.EntityName == item.Type.Name && it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo.HasValue()) + { + dbColumnName = mappingInfo.DbColumnName; + } + if (shortName?.ObjToString().Contains(this.Context.SqlTranslationLeft) == true && this.Context.IsSingle) + { + asName = this.Context.GetTranslationText(item.Type.Name + "." + propertyName); + } + else + { + asName = this.Context.GetTranslationText(shortName + "." + item.Type.Name + "." + propertyName); + } + if (Context.IsJoin) + { + this.Context.Result.Append(Context.GetAsString(asName, dbColumnName, shortName.ObjToString())); + } + else + { + this.Context.Result.Append(Context.GetAsString(asName, dbColumnName)); + } + + return asName; + } + private EntityColumnInfo GetColumnInfo(Expression oppoSiteExpression) + { + var oppsite = (oppoSiteExpression as MemberExpression); + if (oppsite == null) return null; + if (this.Context.SugarContext == null) return null; + if (this.Context.SugarContext.Context == null) return null; + if (oppsite.Expression == null) return null; + var columnInfo = this.Context.SugarContext.Context.EntityMaintenance + .GetEntityInfo(oppsite.Expression.Type).Columns.FirstOrDefault(it => it.PropertyName == oppsite.Member.Name); + return columnInfo; + } + protected MethodCallExpressionArgs GetMethodCallArgs(ExpressionParameter parameter, Expression item, string name = null) + { + var newContext = this.Context.GetCopyContext(); + newContext.MappingColumns = this.Context.MappingColumns; + newContext.MappingTables = this.Context.MappingTables; + newContext.IgnoreComumnList = this.Context.IgnoreComumnList; + newContext.IsSingle = this.Context.IsSingle; + newContext.SqlFuncServices = this.Context.SqlFuncServices; + newContext.MethodName = name; + newContext.Resolve(item, this.Context.IsJoin ? ResolveExpressType.WhereMultiple : ResolveExpressType.WhereSingle); + this.Context.Index = newContext.Index; + this.Context.ParameterIndex = newContext.ParameterIndex; + if (newContext.Parameters.HasValue()) + { + this.Context.Parameters.AddRange(newContext.Parameters); + } + if (newContext.SingleTableNameSubqueryShortName.HasValue()) + { + this.Context.SingleTableNameSubqueryShortName = newContext.SingleTableNameSubqueryShortName; + } + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = true, + MemberName = newContext.Result.GetResultString() + }; + return methodCallExpressionArgs; + } + private string GetAsNameResolveAnObject(ExpressionParameter parameter, Expression item, string asName, bool isSameType) + { + this.Start(); + var shortName = parameter.CommonTempData; + var listProperties = item.Type.GetProperties().Cast().ToList(); + foreach (var property in listProperties) + { + var hasIgnore = this.Context.IgnoreComumnList?.Any(it => it.EntityName.Equals(item.Type.Name, StringComparison.CurrentCultureIgnoreCase) && it.PropertyName.Equals(property.Name, StringComparison.CurrentCultureIgnoreCase)) == true; + if (hasIgnore) + { + continue; + } + if (property.PropertyType.IsClass()) + { + var comumnInfo = property.GetCustomAttribute(); + if (comumnInfo?.IsJson == true && isSameType) + { + asName = GetAsNameAndShortName(item, shortName, property); + } + else if (comumnInfo?.IsJson == true) + { + asName = GetAsName(item, shortName, property); + } + else if (comumnInfo != null && this.Context.SugarContext?.Context != null) + { + var entityInfo = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(item.Type); + var entityColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == property.Name); + if (entityColumn?.IsJson == true) + { + asName = GetAsName(item, shortName, property); + } + } + } + else if (isSameType) + { + asName = GetAsNameAndShortName(item, shortName, property); + } + else + { + asName = GetAsName(item, shortName, property); + } + } + + return asName; + } + public object GetAsNamePackIfElse(object methodValue) + { + methodValue = this.Context.DbMehtods.CaseWhen(new List>() { + new KeyValuePair("IF",methodValue.ObjToString()), + new KeyValuePair("Return","1"), + new KeyValuePair("End","0") + }); + return methodValue; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Item.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Item.cs new file mode 100644 index 000000000..f88443126 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Item.cs @@ -0,0 +1,471 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + /// + ///BaseResolve New Expression + /// + public partial class BaseResolve + { + private void ResloveOtherMUC(ExpressionParameter parameter, Expression item, string asName) + { + if (ExpressionTool.GetMethodName(item) == "NewGuid") + { + parameter.Context.Result.Append(this.Context.GetAsString2(asName, this.Context.DbMehtods.NewUid(null))); + return; + } + else if (ExpressionTool.GetMethodName(item) == "OnlyInSelectConvertToString") + { + AppendOnlyInSelectConvertToString(parameter, item, asName); + return; + } + else if (ExpressionTool.GetMethodName(item) == "ToString" + && (item as MethodCallExpression)?.Arguments?.Count == 1 + && (item as MethodCallExpression)?.Object?.Type != UtilConstants.DateType + && this.Context?.SugarContext?.QueryBuilder != null + && (item as MethodCallExpression)?.Method?.ReflectedType?.Name != "SqlFunc" + && (item as MethodCallExpression)?.Method?.ReflectedType?.Name != "Convert" + ) + { + var format = ExpressionTool.GetExpressionValue((item as MethodCallExpression)?.Arguments[0]); + var childExpression = (item as MethodCallExpression)?.Object; + var type = childExpression.Type; + if (this.Context.SugarContext.QueryBuilder.QueryableFormats == null) + { + this.Context.SugarContext.QueryBuilder.QueryableFormats = new List(); + } + this.Context.SugarContext.QueryBuilder.QueryableFormats.Add(new QueryableFormat() + { + Format = format + "", + PropertyName = asName, + Type = type, + TypeString = type.FullName, + MethodName = "ToString" + }); + parameter.Context.Result.Append(this.Context.GetAsString2(asName, GetNewExpressionValue(childExpression))); + return; + } + else if (ExpressionTool.GetMethodName(item) == "ToString" + && (item as MethodCallExpression)?.Arguments?.Count == 0 + && (item as MethodCallExpression)?.Object?.Type?.IsEnum == true + && this.Context?.SugarContext?.QueryBuilder != null) + { + var childExpression = (item as MethodCallExpression)?.Object; + var type = childExpression.Type; + if (this.Context.SugarContext.QueryBuilder.QueryableFormats == null) + { + this.Context.SugarContext.QueryBuilder.QueryableFormats = new List(); + } + this.Context.SugarContext.QueryBuilder.QueryableFormats.Add(new QueryableFormat() + { + PropertyName = asName, + Type = type, + TypeString = "Enum", + MethodName = "ToString" + }); + parameter.Context.Result.Append(this.Context.GetAsString2(asName, GetNewExpressionValue(childExpression))); + return; + } + else if (ExpressionTool.GetMethodName(item) == "IsNull" + && this.Context.SingleTableNameSubqueryShortName == null + && this.BaseParameter?.CurrentExpression is NewExpression + && (item as MethodCallExpression)?.Arguments?.FirstOrDefault() is MethodCallExpression + && item?.ToString()?.Contains("Join") == true + && ExpressionTool.GetParameters(this.BaseParameter?.CurrentExpression).Count > 1) + { + var ps = ExpressionTool.GetParameters(this.BaseParameter?.CurrentExpression); + this.Expression = item; + this.Start(); + parameter.Context.Result.Append(this.Context.GetAsString2(asName, parameter.CommonTempData.ObjToString())); + this.Context.SingleTableNameSubqueryShortName = ps.FirstOrDefault().Name; + return; + } + else if (item is MethodCallExpression && ExpressionTool.IsVariable(item)) + { + var p = GetNewExpressionValue(item); + parameter.Context.Result.Append(this.Context.GetAsString2(asName, p)); + return; + } + else if (item is ConditionalExpression && ExpressionTool.GetParameters(item).Count > 0) + { + var p = GetNewExpressionValue(item); + parameter.Context.Result.Append(this.Context.GetAsString2(asName, p)); + return; + } + this.Expression = item; + var negateString = string.Empty; + if (item.NodeType == ExpressionType.Negate) + { + negateString = " -1*"; + this.Expression = (this.Expression as UnaryExpression).Operand; + } + this.Start(); + if (ExpressionTool.GetMethodName(item) == "MappingColumn") + { + parameter.Context.Result.Append(negateString + this.Context.GetAsString2(asName, parameter.CommonTempData.ObjToString())); + } + else if (parameter.CommonTempData?.Equals(CommonTempDataType.Append) == true) + { + if (item.NodeType == ExpressionType.Negate) + { + negateString = "*-1 "; + } + else + { + negateString = null; + } + parameter.Context.Result.TrimEnd(); + parameter.Context.Result.Append(negateString + " AS " + this.Context.GetTranslationColumnName(asName)); + } + else + { + parameter.Context.Result.Append(negateString + this.Context.GetAsString2(asName, parameter.CommonTempData.ObjToString())); + } + } + + private void ResloveCountAny(ExpressionParameter parameter, Expression item, string asName) + { + if (this.Context.IsSingle && this.Context.SingleTableNameSubqueryShortName == null) + { + this.Context.SingleTableNameSubqueryShortName = item.ToString().Split('.').First(); + } + parameter.Context.Result.Append(this.Context.GetAsString(asName, GetNewExpressionValue(item))); + } + + private void ResloveNot(ExpressionParameter parameter, Expression item, string asName) + { + var asValue = GetAsNamePackIfElse(GetNewExpressionValue(item)).ObjToString(); + parameter.Context.Result.Append(this.Context.GetAsString(asName, asValue)); + } + + private void ResloveBoolMethod(ExpressionParameter parameter, Expression item, string asName) + { + this.Expression = item; + if (ExpressionTool.GetMethodName(item) == "Any" && !ExpressionTool.GetTopLevelMethodCalls(item).Contains("Subqueryable")) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else if (ExpressionTool.GetMethodName(item) == "All" && !ExpressionTool.GetTopLevelMethodCalls(item).Contains("Subqueryable")) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else + { + this.Start(); + } + var sql = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs() { + IsMember=true, + MemberName=parameter.CommonTempData.ObjToString() + }, + new MethodCallExpressionArgs() { + IsMember=true, + MemberName=1 + }, + new MethodCallExpressionArgs() { + IsMember=true, + MemberName=0 + } + } + }); + parameter.Context.Result.Append(this.Context.GetAsString(asName, sql)); + } + + private string ResolveClass(ExpressionParameter parameter, Expression item, string asName) + { + var mappingKeys = GetMappingColumns(parameter.CurrentExpression); + var isSameType = mappingKeys.Keys.Count > 0; + this.Context.SugarContext.QueryBuilder.MappingKeys = mappingKeys; + this.Expression = item; + if (this.Context.IsJoin && (item is MemberInitExpression || item is NewExpression)) + { + List newExpressionInfos = new List(); + if (item is MemberInitExpression) + { + newExpressionInfos = ExpressionTool.GetNewexpressionInfos(item, this.Context, this); + var ignorePropertyNames = item.Type.GetProperties().Where(it => it.PropertyType.IsClass() && !it.PropertyType.Name.StartsWith("System.")) + .Select(it => it.PropertyType.Name).ToList(); + if (ignorePropertyNames.Count > 0) + { + var names = new List() { }; + foreach (MemberBinding binding in ((MemberInitExpression)item).Bindings) + { + names.Add(binding.Member.Name); + } + ignorePropertyNames = ignorePropertyNames.Where(it => !names.Contains(it)).ToList(); + var q = this.Context?.SugarContext?.QueryBuilder; + if (q != null) + { + foreach (var ignorePropertyName in ignorePropertyNames) + { + if (q.SelectNewIgnoreColumns == null) + { + q.SelectNewIgnoreColumns = new List>(); + } + var addItem = new KeyValuePair(ignorePropertyName, item.Type.Name); + q.SelectNewIgnoreColumns.Add(addItem); + } + } + } + } + else + { + newExpressionInfos = ExpressionTool.GetNewDynamicexpressionInfos(item, this.Context, this); + } + foreach (NewExpressionInfo newExpressionInfo in newExpressionInfos) + { + //var property=item.Type.GetProperties().Where(it => it.Name == newExpressionInfo.l).First(); + //asName = GetAsName(item, newExpressionInfo.ShortName, property); + if (newExpressionInfo.Type == nameof(ConstantExpression)) + { + parameter.Context.Result.Append( + newExpressionInfo.RightDbName + " AS " + + this.Context.SqlTranslationLeft + asName + "." + newExpressionInfo.LeftNameName + this.Context.SqlTranslationRight + + ); + } + else + { + parameter.Context.Result.Append(this.Context.GetAsString( + this.Context.SqlTranslationLeft + asName + "." + newExpressionInfo.LeftNameName + this.Context.SqlTranslationRight, + newExpressionInfo.ShortName + "." + newExpressionInfo.RightDbName + )); + } + } + } + else if (!this.Context.IsJoin && (item is MemberInitExpression || item is NewExpression)) + { + List newExpressionInfos = new List(); + if (item is MemberInitExpression) + { + newExpressionInfos = ExpressionTool.GetNewexpressionInfos(item, this.Context, this); + } + else + { + newExpressionInfos = ExpressionTool.GetNewDynamicexpressionInfos(item, this.Context, this); + } + //mappingKeys = new Dictionary(); + foreach (NewExpressionInfo newExpressionInfo in newExpressionInfos) + { + //var property=item.Type.GetProperties().Where(it => it.Name == newExpressionInfo.l).First(); + //asName = GetAsName(item, newExpressionInfo.ShortName, property); + mappingKeys.Add("Single_" + newExpressionInfo.LeftNameName, asName + "." + newExpressionInfo.LeftNameName); + if (newExpressionInfo.Type == nameof(ConstantExpression)) + { + this.Context.SugarContext.QueryBuilder.MappingKeys = mappingKeys; + parameter.Context.Result.Append($" {newExpressionInfo.RightDbName} AS {this.Context.SqlTranslationLeft}{asName}.{newExpressionInfo.LeftNameName}{this.Context.SqlTranslationRight} "); + } + else + { + this.Context.SugarContext.QueryBuilder.MappingKeys = mappingKeys; + parameter.Context.Result.Append(this.Context.GetAsString( + this.Context.SqlTranslationLeft + asName + "." + newExpressionInfo.LeftNameName + this.Context.SqlTranslationRight, + newExpressionInfo.RightDbName + )); + } + } + } + else if (IsExtSqlFuncObj(item)) + { + var value = GetNewExpressionValue(item); + parameter.Context.Result.Append($" {value} AS {asName} "); + } + else if (IsSubToList(item)) + { + var value = GetNewExpressionValue(item); + if (this.Context.SugarContext.QueryBuilder.SubToListParameters == null) + this.Context.SugarContext.QueryBuilder.SubToListParameters = new Dictionary(); + if (!this.Context.SugarContext.QueryBuilder.SubToListParameters.ContainsKey(asName)) + { + this.Context.SugarContext.QueryBuilder.SubToListParameters.Add(asName, value); + } + //throw new Exception("子查询ToList开发中.."); + } + else if (ExpressionTool.GetMethodName(item) == nameof(SqlFunc.MappingColumn)) + { + var value = GetNewExpressionValue(item); + parameter.Context.Result.Append($" {value} AS {asName} "); + } + else if (item is ConditionalExpression) + { + var value = GetNewExpressionValue(item); + parameter.Context.Result.Append($" {value} AS {asName} "); + } + else if (ExpressionTool.GetMethodName(item) == nameof(SqlFunc.IIF)) + { + var value = GetNewExpressionValue(item); + parameter.Context.Result.Append($" {value} AS {asName} "); + } + else + { + asName = GetAsNameResolveAnObject(parameter, item, asName, isSameType); + } + + return asName; + } + + private void ResolveBinary(Expression item, string asName) + { + if (this.Context.Result.IsLockCurrentParameter == false) + { + var newContext = this.Context.GetCopyContextWithMapping(); + var resolveExpressType = this.Context.IsSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple; + if (resolveExpressType == ResolveExpressType.WhereSingle && item is BinaryExpression) + { + var binaryExp = (item as BinaryExpression); + if (ExpressionTool.ContainsMethodName(binaryExp, "Subquery")) + { + resolveExpressType = ResolveExpressType.WhereMultiple; + } + if (this.Context.Expression != null && this.Context.SingleTableNameSubqueryShortName.IsNullOrEmpty()) + { + this.Context.SingleTableNameSubqueryShortName = (this.Context.Expression as LambdaExpression)?.Parameters?.FirstOrDefault()?.Name; + } + } + newContext.Resolve(item, resolveExpressType); + this.Context.Index = newContext.Index; + this.Context.ParameterIndex = newContext.ParameterIndex; + if (newContext.Parameters.HasValue()) + { + this.Context.Parameters.AddRange(newContext.Parameters); + } + if (ExpressionTool.IsEqualOrLtOrGt(item)) + { + var sql = newContext.Result.GetString(); + var pTrue = AppendParameter(true); + var pFalse = AppendParameter(false); + sql = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() + { + Args = new List() + { + new MethodCallExpressionArgs(){ MemberName=sql,MemberValue=sql,IsMember=true } , + new MethodCallExpressionArgs(){ MemberName=pTrue,MemberValue=pTrue,IsMember=true }, + new MethodCallExpressionArgs(){ MemberName=pFalse,MemberValue=pFalse,IsMember=true } + } + }); + this.Context.Result.Append(this.Context.GetAsString(asName, sql)); + } + else + { + this.Context.Result.Append(this.Context.GetAsString(asName, newContext.Result.GetString())); + } + this.Context.Result.CurrentParameter = null; + if (this.Context.SingleTableNameSubqueryShortName.IsNullOrEmpty() && newContext.SingleTableNameSubqueryShortName.HasValue()) + { + this.Context.SingleTableNameSubqueryShortName = newContext.SingleTableNameSubqueryShortName; + } + } + } + + private void ResolveUnaryExpConst(ExpressionParameter parameter, Expression item, string asName) + { + if (this.Context.Result.IsLockCurrentParameter == false) + { + this.Expression = ((UnaryExpression)item).Operand; + this.Start(); + string parameterName = this.Context.SqlParameterKeyWord + "constant" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + parameter.Context.Result.Append(this.Context.GetAsString(asName, parameterName)); + this.Context.Parameters.Add(new SugarParameter(parameterName, parameter.CommonTempData)); + } + } + + private void ResolveUnaryExpMem(ExpressionParameter parameter, Expression item, string asName) + { + if (this.Context.Result.IsLockCurrentParameter == false) + { + var expression = ((UnaryExpression)item).Operand as MemberExpression; + var negateString = string.Empty; + if (item.NodeType == ExpressionType.Negate) + { + negateString = " -1*"; + } + var isDateTimeNow = ((UnaryExpression)item).Operand.ToString() == "DateTime.Now"; + if (expression.Expression == null && !isDateTimeNow) + { + this.Context.Result.CurrentParameter = parameter; + this.Context.Result.IsLockCurrentParameter = true; + parameter.IsAppendTempDate(); + this.Expression = item; + this.Start(); + parameter.IsAppendResult(); + this.Context.Result.Append(negateString + this.Context.GetAsString(asName, parameter.CommonTempData.ObjToString())); + this.Context.Result.CurrentParameter = null; + } + else if (expression.Expression is ConstantExpression || isDateTimeNow) + { + string parameterName = this.Context.SqlParameterKeyWord + "constant" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + parameter.Context.Result.Append(negateString + this.Context.GetAsString(asName, parameterName)); + this.Context.Parameters.Add(new SugarParameter(parameterName, ExpressionTool.GetMemberValue(expression.Member, expression))); + } + else + { + this.Context.Result.CurrentParameter = parameter; + this.Context.Result.IsLockCurrentParameter = true; + parameter.IsAppendTempDate(); + this.Expression = expression; + this.Start(); + parameter.IsAppendResult(); + this.Context.Result.Append(negateString + this.Context.GetAsString(asName, parameter.CommonTempData.ObjToString())); + this.Context.Result.CurrentParameter = null; + } + } + } + + private void ResolveMemberOther(ExpressionParameter parameter, Expression item, string asName) + { + if (this.Context.Result.IsLockCurrentParameter == false) + { + this.Context.Result.CurrentParameter = parameter; + this.Context.Result.IsLockCurrentParameter = true; + parameter.IsAppendTempDate(); + this.Expression = item; + if (IsBoolValue(item)) + { + this.Expression = (item as MemberExpression).Expression; + } + this.Start(); + parameter.IsAppendResult(); + var value = parameter.CommonTempData.ObjToString(); + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) + { + value = ExpressionTool.ResolveMemberValue(this.Context, item, value); + } + this.Context.Result.Append(this.Context.GetAsString2(asName, value)); + this.Context.Result.CurrentParameter = null; + } + } + + private void ResolveMemberConst(ExpressionParameter parameter, Expression item, string asName) + { + this.Expression = item; + this.Start(); + string parameterName = this.Context.SqlParameterKeyWord + "constant" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + parameter.Context.Result.Append(this.Context.GetAsString(asName, parameterName)); + this.Context.Parameters.Add(new SugarParameter(parameterName, parameter.CommonTempData)); + } + + private void ResolveMember(ExpressionParameter parameter, Expression item, string asName) + { + var paramterValue = ExpressionTool.GetPropertyValue(item as MemberExpression); + string parameterName = this.Context.SqlParameterKeyWord + "constant" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + parameter.Context.Result.Append(this.Context.GetAsString(asName, parameterName)); + this.Context.Parameters.Add(new SugarParameter(parameterName, paramterValue)); + } + + private void ResolveConst(ExpressionParameter parameter, Expression item, string asName) + { + this.Expression = item; + this.Start(); + string parameterName = this.Context.SqlParameterKeyWord + "constant" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + parameter.Context.Result.Append(this.Context.GetAsString(asName, parameterName)); + this.Context.Parameters.Add(new SugarParameter(parameterName, parameter.CommonTempData)); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_NewExp.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_NewExp.cs new file mode 100644 index 000000000..be1a6d272 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_NewExp.cs @@ -0,0 +1,110 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + /// + ///BaseResolve New Expression + /// + public partial class BaseResolve + { + public string GetNewExpressionValue(Expression item) + { + var newContext = this.Context.GetCopyContextWithMapping(); + newContext.SugarContext = this.Context.SugarContext; + newContext.Resolve(item, this.Context.IsJoin ? ResolveExpressType.WhereMultiple : ResolveExpressType.WhereSingle); + this.Context.Index = newContext.Index; + this.Context.ParameterIndex = newContext.ParameterIndex; + if (newContext.Parameters.HasValue()) + { + foreach (var p in newContext.Parameters) + { + if (!this.Context.Parameters.Any(it => it.ParameterName == p.ParameterName)) + { + this.Context.Parameters.Add(p); + } + } + } + if (this.Context.SingleTableNameSubqueryShortName == "Subqueryable()") + { + this.Context.SingleTableNameSubqueryShortName = newContext.SingleTableNameSubqueryShortName; + } + else if (newContext.SingleTableNameSubqueryShortName != null && newContext.Result?.Contains(this.Context.SqlTranslationLeft + newContext.SingleTableNameSubqueryShortName + this.Context.SqlTranslationRight) == true) + { + this.Context.SingleTableNameSubqueryShortName = newContext.SingleTableNameSubqueryShortName; + } + return newContext.Result.GetResultString(); + } + + public string GetNewExpressionValue(Expression item, ResolveExpressType type) + { + var newContext = this.Context.GetCopyContextWithMapping(); + newContext.SugarContext = this.Context.SugarContext; + newContext.Resolve(item, type); + this.Context.Index = newContext.Index; + this.Context.ParameterIndex = newContext.ParameterIndex; + if (newContext.Parameters.HasValue()) + { + this.Context.Parameters.AddRange(newContext.Parameters); + } + return newContext.Result.GetResultString(); + } + + protected void ResolveNewExpressions(ExpressionParameter parameter, Expression item, string asName) + { + if (item is ConstantExpression) + { + ResolveConst(parameter, item, asName); + } + else if ((item is MemberExpression) && ((MemberExpression)item).Expression == null) + { + ResolveMember(parameter, item, asName); + } + else if ((item is MemberExpression) && ((MemberExpression)item).Expression.NodeType == ExpressionType.Constant) + { + ResolveMemberConst(parameter, item, asName); + } + else if (item is MemberExpression) + { + ResolveMemberOther(parameter, item, asName); + } + else if (item is UnaryExpression && ((UnaryExpression)item).Operand is MemberExpression) + { + ResolveUnaryExpMem(parameter, item, asName); + } + else if (item is UnaryExpression && ((UnaryExpression)item).Operand is ConstantExpression) + { + ResolveUnaryExpConst(parameter, item, asName); + } + else if (ExpressionTool.RemoveConvert(item) is BinaryExpression) + { + ResolveBinary(item, asName); + } + else if (item.Type.IsClass()) + { + asName = ResolveClass(parameter, item, asName); + } + else if (item.Type == UtilConstants.BoolType && item is MethodCallExpression && IsNotCaseExpression(item)) + { + ResloveBoolMethod(parameter, item, asName); + } + else if (item.NodeType == ExpressionType.Not + && (item as UnaryExpression).Operand is MethodCallExpression + && ((item as UnaryExpression).Operand as MethodCallExpression).Method.Name.IsIn("IsNullOrEmpty", "IsNullOrWhiteSpace")) + { + ResloveNot(parameter, item, asName); + } + else if (item is MethodCallExpression && (item as MethodCallExpression).Method.Name.IsIn("Count", "Any") && !item.ToString().StartsWith("Subqueryable")) + { + ResloveCountAny(parameter, item, asName); + } + else if (item is MethodCallExpression || item is UnaryExpression || item is ConditionalExpression || item.NodeType == ExpressionType.Coalesce) + { + ResloveOtherMUC(parameter, item, asName); + } + else + { + Check.ThrowNotSupportedException(item.GetType().Name); + } + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Property.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Property.cs new file mode 100644 index 000000000..3f5e2eb8e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Property.cs @@ -0,0 +1,109 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public partial class BaseResolve + { + #region Property + protected Expression Expression { get; set; } + protected Expression ExactExpression { get; set; } + public ExpressionContext Context { get; set; } + public bool? IsLeft { get; set; } + public int ContentIndex { get { return this.Context.Index; } } + public int Index { get; set; } + public ExpressionParameter BaseParameter { get; set; } + #endregion + + #region Dictionary + private Dictionary GetMappingColumns(Expression currentExpression) + { + Dictionary result = new Dictionary(); + if (currentExpression == null) + { + return result; + } + List types = new List(); + int i = 0; + if (currentExpression is NewExpression) + { + i = (currentExpression as NewExpression).Arguments.Count; + foreach (var item in (currentExpression as NewExpression).Arguments) + { + if (item.Type.IsClass()) + { + types.Add(item.Type); + } + } + } + else if (currentExpression is MemberInitExpression) + { + i = (currentExpression as MemberInitExpression).Bindings.Count; + foreach (var item in (currentExpression as MemberInitExpression).Bindings) + { + MemberAssignment memberAssignment = (MemberAssignment)item; + if (memberAssignment.Expression.Type.IsClass()) + { + types.Add(memberAssignment.Expression.Type); + } + } + } + if (types.Count == i && (types.Count == types.Distinct().Count())) + { + return result; + } + var array = currentExpression.ToString().Split(','); + foreach (var item in array) + { + var itemArray = item.Split('=').ToArray(); + var last = itemArray.Last().Trim().Split('.').First().TrimEnd(')').TrimEnd('}'); + var first = itemArray.First().Trim(); + if (first.Contains('{')) + { + first = first.Split('{').Last().Trim(); + } + if (first.Contains('(')) + { + first = first.Split('(').Last().Trim(); + } + if (!result.TryAdd(first, last)) + { + //future + } + } + return result; ; + } + protected static Dictionary MethodMapping = new Dictionary() { + { "ToString","ToString"}, + { "ToInt32","ToInt32"}, + { "ToInt16","ToInt32"}, + { "ToInt64","ToInt64"}, + { "ToDecimal","ToDecimal"}, + { "ToDateTime","ToDate"}, + { "ToBoolean","ToBool"}, + { "ToDouble","ToDouble"}, + { "Length","Length"}, + { "Replace","Replace"}, + { "Contains","Contains"}, + { "ContainsArray","ContainsArray"}, + { "EndsWith","EndsWith"}, + { "StartsWith","StartsWith"}, + { "HasValue","HasValue"}, + { "Trim","Trim"}, + { "Equals","Equals"}, + { "ToLower","ToLower"}, + { "ToUpper","ToUpper"}, + { "Substring","Substring"}, + { "DateAdd","DateAdd"}, + { "CompareTo","CompareTo"} + }; + protected static Dictionary MethodTimeMapping = new Dictionary() { + { "AddYears",DateType.Year}, + { "AddMonths",DateType.Month}, + { "AddDays",DateType.Day}, + { "AddHours",DateType.Hour}, + { "AddMinutes",DateType.Minute}, + { "AddSeconds",DateType.Second}, + { "AddMilliseconds",DateType.Millisecond} + }; + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs new file mode 100644 index 000000000..b2ec28feb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs @@ -0,0 +1,114 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + /// + /// BaseResolve-Validate + /// + public partial class BaseResolve + { + + private static bool IsSubToList(Expression item) + { + return ExpressionTool.GetMethodName(item).IsIn("ToList", "First") && IsSubquery(item); + } + + private static bool IsSubquery(Expression item) + { + var method = (item as MethodCallExpression); + if (method == null) + return false; + if (method.Object == null) + return false; + return method.Object.Type.Name.StartsWith("Subquery"); + } + + private bool IsExtSqlFuncObj(Expression item) + { + return this.Context.SqlFuncServices != null && item is MethodCallExpression && this.Context.SqlFuncServices.Any(it => it.UniqueMethodName == ExpressionTool.GetMethodName(item)); + } + private bool IsNullValue(ExpressionParameter parameter, object value) + { + return value == null + && !parameter.ValueIsNull + && parameter.BaseParameter?.OperatorValue.IsIn("=", "<>") == true + && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle); + } + private static bool IsNotCaseExpression(Expression item) + { + if ((item as MethodCallExpression).Method.Name == "IIF") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "IsNull") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "End" && item.ToString().Contains("IF(")) + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "AggregateMax") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "AggregateMin") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "AggregateSum") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "ToBool") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "ToBoolean") + { + return false; + } + else if ((item as MethodCallExpression).Method.Name == "Select" && item.ToString().Contains("Subqueryable()")) + { + return false; + } + else + { + return true; + } + } + private static bool IsBoolValue(Expression item) + { + return item.Type == UtilConstants.BoolType && + (item is MemberExpression) && + (item as MemberExpression).Expression != null && + (item as MemberExpression).Expression.Type == typeof(bool?) && + (item as MemberExpression).Member.Name == "Value"; + } + protected static bool IsConvert(Expression item) + { + return item is UnaryExpression && item.NodeType == ExpressionType.Convert; + } + protected static bool IsNotMember(Expression item) + { + return item is UnaryExpression && + item.Type == UtilConstants.BoolType && + (item as UnaryExpression).NodeType == ExpressionType.Not && + (item as UnaryExpression).Operand is MemberExpression && + ((item as UnaryExpression).Operand as MemberExpression).Expression != null && + ((item as UnaryExpression).Operand as MemberExpression).Expression.NodeType == ExpressionType.Parameter; + } + protected static bool IsNotParameter(Expression item) + { + return item is UnaryExpression && + item.Type == UtilConstants.BoolType && + (item as UnaryExpression).NodeType == ExpressionType.Not && + (item as UnaryExpression).Operand is MemberExpression && + ((item as UnaryExpression).Operand as MemberExpression).Expression != null && + ((item as UnaryExpression).Operand as MemberExpression).Expression.NodeType == ExpressionType.MemberAccess; + } + protected bool IsSubMethod(MethodCallExpression express) + { + return SubTools.SubItemsConst.Any(it => express.Object?.Type.Name.StartsWith("Subqueryable`") == true); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs new file mode 100644 index 000000000..5f0ae058a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs @@ -0,0 +1,407 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class BinaryExpressionResolve : BaseResolve + { + public BinaryExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + var sql = base.GetNewExpressionValue(this.Expression); + this.Context.Result.Append(sql); + break; + default: + Other(parameter); + break; + } + } + + private void Other(ExpressionParameter parameter) + { + var expression = this.Expression as BinaryExpression; + if (expression.NodeType == ExpressionType.ArrayIndex) + { + var parameterName = AppendParameter(ExpressionTool.DynamicInvoke(expression)); + if (this.BaseParameter?.IsLeft == true) + { + base.Context.Result.Append($" {BaseParameter.BaseParameter.OperatorValue} {parameterName} "); + } + else + { + base.Context.Result.Append($" {parameterName} "); + } + return; + } + var operatorValue = parameter.OperatorValue = ExpressionTool.GetOperator(expression.NodeType); + var isSubGroup = IsGroupSubquery(expression.Right, operatorValue); + if (isSubGroup) + { + SubGroup(expression, operatorValue); + } + else if (IsJoinString(expression, operatorValue)) + { + JoinString(parameter, expression); + } + else if (IsUpdateJson(parameter, expression, operatorValue)) + { + parameter.CommonTempData = "IsJson=true"; + DefaultBinary(parameter, expression, operatorValue); + parameter.CommonTempData = null; + } + else if (IsUpdateArray(parameter, expression, operatorValue)) + { + parameter.CommonTempData = "IsArray=true"; + DefaultBinary(parameter, expression, operatorValue); + parameter.CommonTempData = null; + } + else if (IsBinaryGroup(operatorValue, expression)) + { + var isComparisonOperator = ExpressionTool.IsComparisonOperator(expression); + var getLeft = GetNewExpressionValue(expression.Left); + var getRight = GetNewExpressionValue(expression.Right); + base.Context.Result.Append($"( {getLeft} {operatorValue} {getRight} )"); + } + else + { + DefaultBinary(parameter, expression, operatorValue); + } + } + + private bool IsBinaryGroup(string operatorValue, BinaryExpression expression) + { + var left = ExpressionTool.RemoveConvert(expression.Left); + var right = ExpressionTool.RemoveConvert(expression.Right); + if (operatorValue?.IsIn("AND", "OR") == true && left is BinaryExpression && right is BinaryExpression) + { + + var leftChild = ExpressionTool.RemoveConvert((left as BinaryExpression).Right); + var rightChild = ExpressionTool.RemoveConvert((right as BinaryExpression).Right); + var isLeftSelect = ExpressionTool.GetMethodName(leftChild) == "Select" || leftChild is BinaryExpression; + var isRightSelect = ExpressionTool.GetMethodName(rightChild) == "Select" || rightChild is BinaryExpression; + var isLeftGroup = ExpressionTool.ContainsMethodName(left as BinaryExpression, "Group"); + var isRightGroup = ExpressionTool.ContainsMethodName(right as BinaryExpression, "Group"); + if ( + (isLeftSelect && isLeftGroup) + || + (isRightSelect && isRightGroup) + ) + { + return true; + } + } + return false; + } + + private bool IsUpdateArray(ExpressionParameter parameter, BinaryExpression expression, string operatorValue) + { + var isOk = parameter.Context.ResolveType == ResolveExpressType.WhereSingle && operatorValue == "=" && (expression.Left is MemberExpression) && expression.Left.Type.IsClass(); + if (isOk && this.Context.SugarContext != null) + { + var member = (expression.Left as MemberExpression); + if (member.Expression != null) + { + var entity = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var jsonColumn = entity.Columns.FirstOrDefault(it => it.IsArray && it.PropertyName == ExpressionTool.GetMemberName(expression.Left)); + if (jsonColumn != null) + { + return true; + } + } + } + return false; + } + + private bool IsUpdateJson(ExpressionParameter parameter, BinaryExpression expression, string operatorValue) + { + var isOk = parameter.Context.ResolveType == ResolveExpressType.WhereSingle && operatorValue == "=" && (expression.Left is MemberExpression) && expression.Left.Type.IsClass(); + if (isOk && this.Context.SugarContext != null) + { + var member = (expression.Left as MemberExpression); + if (member.Expression != null) + { + var entity = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var jsonColumn = entity.Columns.FirstOrDefault(it => it.IsJson && it.PropertyName == ExpressionTool.GetMemberName(expression.Left)); + if (jsonColumn != null) + { + return true; + } + } + } + return false; + } + + private void JoinString(ExpressionParameter parameter, BinaryExpression expression) + { + var leftString = GetNewExpressionValue(expression.Left); + var RightString = GetNewExpressionValue(expression.Right); + if (leftString == null && base.BaseParameter?.BaseExpression == null && expression.Left is ParameterExpression parameterExpression) + { + leftString = this.Context.SqlParameterKeyWord + "MethodConst1"; + } + var joinString = this.Context.DbMehtods.MergeString(leftString, RightString); + if (this.Context is KdbndpExpressionContext && this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) + { + joinString = new SqlServerMethod().MergeString(leftString, RightString); + } + if (this.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + base.Context.Result.Replace("{0}", $" {joinString} "); + base.Context.Result.Append(" " + ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index + " "); + } + else + { + base.Context.Result.Append($" {joinString} "); + } + } + + + + private void DefaultBinary(ExpressionParameter parameter, BinaryExpression expression, string operatorValue) + { + var isEqual = expression.NodeType == ExpressionType.Equal; + var isComparisonOperator = ExpressionTool.IsComparisonOperator(expression); + base.ExactExpression = expression; + var leftExpression = expression.Left; + var rightExpression = expression.Right; + if (operatorValue.IsIn("AND", "OR") && leftExpression is BinaryExpression exp) + { + if (exp?.Left is BinaryExpression expChild) + { + if (ExpressionTool.GetMethodName(expChild?.Right) == "Select" && ExpressionTool.ContainsMethodName(expChild, "GroupBy")) + { + var childLeft = GetNewExpressionValue(expChild.Left); + var childRight = GetNewExpressionValue(expChild.Right); + var right = GetNewExpressionValue(exp.Right); + var ov = ExpressionTool.GetOperator(exp.NodeType); + base.Context.Result.Append($" (({childLeft + " IN " + childRight}) {operatorValue} {GetNewExpressionValue(rightExpression)}) {ov} {right} "); + return; + } + } + } + if (operatorValue == "=" && ExpressionTool.RemoveConvert(leftExpression) is ConstantExpression) + { + leftExpression = expression.Right; + rightExpression = expression.Left; + } + if (RightIsHasValue(leftExpression, rightExpression, ExpressionTool.IsLogicOperator(expression))) + { + Expression trueValue = Expression.Constant(true); + rightExpression = ExpressionBuilderHelper.CreateExpression(rightExpression, trueValue, ExpressionType.Equal); + } + var leftIsBinary = leftExpression is BinaryExpression; + var rightBinary = rightExpression is BinaryExpression; + var lbrs = leftIsBinary && !rightBinary; + var lsrb = !leftIsBinary && rightBinary; + var lbrb = rightBinary && leftIsBinary; + var lsbs = !leftIsBinary && !rightBinary; + var isAppend = !base.Context.Result.Contains(ExpressionConst.FormatSymbol); + ConvertExpression(ref leftExpression, ref rightExpression, isAppend); + parameter.LeftExpression = leftExpression; + parameter.RightExpression = rightExpression; + Left(expression, leftExpression); + Right(parameter, operatorValue, isEqual, rightExpression, lsbs); + } + + private void SubGroup(BinaryExpression expression, string operatorValue) + { + if (ExpressionTool.IsUnConvertExpress(expression.Right)) + { + InSubGroupByConvertExpress(expression); + } + else + { + InSubGroupBy(expression, operatorValue == "<>" ? "NOT" : ""); + } + } + + private void ConvertExpression(ref Expression leftExpression, ref Expression rightExpression, bool isAppend) + { + if (isAppend) + { + base.Context.Result.Append(ExpressionConst.LeftParenthesis); + base.Context.Result.Append(ExpressionConst.FormatSymbol); + } + else + { + base.Context.Result.Replace(ExpressionConst.FormatSymbol, ExpressionConst.LeftParenthesis + ExpressionConst.FormatSymbol); + } + if (leftExpression is UnaryExpression && (leftExpression as UnaryExpression).Operand is UnaryExpression && (leftExpression as UnaryExpression).NodeType == ExpressionType.Convert) + { + leftExpression = (leftExpression as UnaryExpression).Operand; + } + if (leftExpression is UnaryExpression && (leftExpression as UnaryExpression).Operand.Type == UtilConstants.BoolType && (leftExpression as UnaryExpression).NodeType == ExpressionType.Convert && rightExpression.Type == UtilConstants.BoolTypeNull) + { + leftExpression = (leftExpression as UnaryExpression).Operand; + } + if (rightExpression is UnaryExpression && (rightExpression as UnaryExpression).NodeType == ExpressionType.Convert) + { + rightExpression = (rightExpression as UnaryExpression).Operand; + } + } + + private void Right(ExpressionParameter parameter, string operatorValue, bool isEqual, Expression rightExpression, bool lsbs) + { + base.IsLeft = false; + base.Expression = rightExpression; + base.Start(); + base.IsLeft = null; + if (lsbs && parameter.ValueIsNull) + { + base.Context.Result.Replace(ExpressionConst.ExpressionReplace + parameter.Index, isEqual ? "IS" : "IS NOT"); + base.Context.Result.Replace(ExpressionConst.ExpressionReplace + (parameter.Index + 1), isEqual ? "IS" : "IS NOT"); + } + else + { + base.Context.Result.Replace(ExpressionConst.ExpressionReplace + parameter.Index, operatorValue); + base.Context.Result.Replace(ExpressionConst.ExpressionReplace + (parameter.Index + 1), operatorValue); + } + base.Context.Result.Append(ExpressionConst.RightParenthesis); + if (parameter.BaseExpression is BinaryExpression && parameter.IsLeft == true) + { + base.Context.Result.Append(" " + ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index + " "); + } + } + + private void Left(BinaryExpression expression, Expression leftExpression) + { + base.Expression = leftExpression; + base.IsLeft = true; + base.Start(); + if (leftExpression is UnaryExpression && leftExpression.Type == UtilConstants.BoolType && !this.Context.Result.Contains(ExpressionConst.ExpressionReplace)) + { + this.Context.Result.AppendFormat(" {0} ", ExpressionTool.GetOperator(expression.NodeType)); + } + else if (leftExpression is UnaryExpression && ExpressionTool.RemoveConvert(leftExpression) is BinaryExpression && !this.Context.Result.Contains(ExpressionConst.ExpressionReplace)) + { + this.Context.Result.AppendFormat(" {0} ", ExpressionTool.GetOperator(expression.NodeType)); + } + } + + private void InSubGroupByConvertExpress(BinaryExpression expression) + { + var leftSql = GetNewExpressionValue(expression.Left); + var rightExpression = (expression.Right as UnaryExpression).Operand as MethodCallExpression; + var selector = GetNewExpressionValue(rightExpression.Arguments[0]); + var rightSql = GetNewExpressionValue(rightExpression.Object).Replace("SELECT FROM", $"SELECT {selector} FROM"); + if (this.Context.IsSingle && this.Context.SingleTableNameSubqueryShortName == null) + { + var leftExp = expression.Left; + if (leftExp is UnaryExpression) + { + leftExp = (leftExp as UnaryExpression).Operand; + } + var p = (leftExp as MemberExpression); + this.Context.SingleTableNameSubqueryShortName = p.Expression.ToString(); + } + base.Context.Result.Append($" {leftSql} in ({rightSql}) "); + } + private void InSubGroupBy(BinaryExpression expression, string not) + { + var leftSql = GetNewExpressionValue(ExpressionTool.RemoveConvert(expression.Left)); + var rightExpression = expression.Right as MethodCallExpression; + if (rightExpression.Arguments[0] is LambdaExpression) + { + if ((rightExpression.Arguments[0] as LambdaExpression).Parameters?.Count > 0) + { + foreach (var item in (rightExpression.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(item.Type); + this.Context.RefreshMapping(); + } + } + } + } + var selector = ""; + bool hasMethodCallWithName = ExpressionTool.ContainsMethodName(expression, "Join"); + if (hasMethodCallWithName) + { + selector = GetNewExpressionValue(rightExpression.Arguments[0], ResolveExpressType.WhereMultiple); + } + else + { + selector = GetNewExpressionValue(rightExpression.Arguments[0]); + } + var selectorExp = rightExpression.Arguments[0]; + if (hasMethodCallWithName == false && selector.Contains('.') && selectorExp is LambdaExpression) + { + var selectorExpLam = (selectorExp as LambdaExpression); + var name = (selectorExpLam.Parameters[0] as ParameterExpression).Name; + selector = selector.Replace(this.Context.GetTranslationColumnName(name) + ".", ""); + } + var rightSql = GetNewExpressionValue(rightExpression.Object).Replace("SELECT FROM", $"SELECT {selector} FROM"); + if (this.Context.IsSingle && this.Context.SingleTableNameSubqueryShortName == null) + { + var leftExp = expression.Left; + if (leftExp is UnaryExpression) + { + leftExp = (leftExp as UnaryExpression).Operand; + } + var p = (leftExp as MemberExpression); + this.Context.SingleTableNameSubqueryShortName = p.Expression.ToString(); + } + if (UtilMethods.IsParentheses(rightSql + "")) + { + base.Context.Result.Append($" {leftSql} {not} in {rightSql} "); + } + else + { + base.Context.Result.Append($" {leftSql} {not} in ({rightSql}) "); + } + } + + private bool IsGroupSubquery(Expression rightExpression, string operatorValue) + { + if (operatorValue != "=" && operatorValue != "<>") + { + return false; + } + if (rightExpression == null) + { + return false; + } + if (ExpressionTool.IsUnConvertExpress(rightExpression)) + { + rightExpression = (rightExpression as UnaryExpression).Operand; + } + if ((rightExpression is MethodCallExpression) == false) + { + return false; + } + var method = (rightExpression as MethodCallExpression); + if (method.Method.Name != "Select") + { + return false; + } + var topMethods = ExpressionTool.GetTopLevelMethodCalls(method); + if (!topMethods.Contains("Subqueryable")) + { + return false; + } + if (!topMethods.Contains("GroupBy")) + { + return false; + } + return true; + } + private static bool IsJoinString(BinaryExpression expression, string operatorValue) + { + return operatorValue == "+" + && expression.Right.Type == UtilConstants.StringType + && expression.Left.Type == UtilConstants.StringType; + } + private static bool RightIsHasValue(Expression leftExpression, Expression rightExpression, bool isLogic) + { + return isLogic && + leftExpression.Type == UtilConstants.BoolType && + rightExpression.Type == UtilConstants.BoolType && + rightExpression is MethodCallExpression && + (rightExpression as MethodCallExpression).Method.Name == "HasValue"; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BlockExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BlockExpressionResolve.cs new file mode 100644 index 000000000..4891cf87e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/BlockExpressionResolve.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public class BlockExpressionResolve : BaseResolve + { + public BlockExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/CoalesceResolveItems.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/CoalesceResolveItems.cs new file mode 100644 index 000000000..335a2d2ea --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/CoalesceResolveItems.cs @@ -0,0 +1,39 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class CoalesceResolveItems : MethodCallExpressionResolve + { + public CoalesceResolveItems(ExpressionParameter parameter) : base(parameter) + { + string name = "IsNull"; + var express = base.Expression as BinaryExpression; + var args = new List() { + express.Left, + express.Right + }; + var isLeft = parameter.IsLeft; + MethodCallExpressionModel model = new MethodCallExpressionModel(); + model.Args = new List(); + switch (this.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + Check.Exception(name == "GetSelfAndAutoFill", "SqlFunc.GetSelfAndAutoFill can only be used in Select."); + base.Where(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + base.Select(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + base.Field(parameter, isLeft, name, args, model); + break; + default: + break; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs new file mode 100644 index 000000000..12fb81b7f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs @@ -0,0 +1,93 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class ConditionalExpressionResolve : MethodCallExpressionResolve + { + public ConditionalExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + + string name = "IIF"; + var express = base.Expression as ConditionalExpression; + var args = new List() { + express.Test, + express.IfTrue, + express.IfFalse + }; + if (ExpressionTool.GetParameters(express.Test).Count == 0) + { + while (express != null) + { + var ps = ExpressionTool.GetParameters(express.Test); + if (ps?.Count == 0) + { + var value = ExpressionTool.DynamicInvoke(express.Test); + if (value is bool boolValue) + { + args[0] = boolValue ? UtilConstants.ExpTrue : UtilConstants.ExpFalse; + // 根据结果选择分支 + var next = boolValue ? express.IfTrue : express.IfFalse; + args[1] = next; + args[2] = next; + + // 如果选择的分支还是一个条件表达式,就继续展开 + if (ExpressionTool.RemoveConvert(next) is ConditionalExpression childConditional) + { + express = childConditional; + args = new List() { + express.Test, + express.IfTrue, + express.IfFalse + }; + continue; + } + else + { + break; // 到底了,不是条件表达式,跳出循环 + } + } + else + { + break; // 不是bool,无法判断,退出 + } + } + else + { + break; // 有参数,不能动态执行,退出 + } + } + } + if (IsBoolMember(express)) + { + Expression trueValue = Expression.Constant(true); + args[0] = ExpressionBuilderHelper.CreateExpression(express.Test, trueValue, ExpressionType.Equal); + } + var isLeft = parameter.IsLeft; + MethodCallExpressionModel model = new MethodCallExpressionModel(); + model.Args = new List(); + switch (this.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + Check.Exception(name == "GetSelfAndAutoFill", "SqlFunc.GetSelfAndAutoFill can only be used in Select."); + base.Where(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + base.Select(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + base.Field(parameter, isLeft, name, args, model); + break; + default: + break; + } + } + + private static bool IsBoolMember(ConditionalExpression express) + { + return express.Test is MemberExpression && (express.Test as MemberExpression).Expression is ParameterExpression; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs new file mode 100644 index 000000000..5ab826e46 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs @@ -0,0 +1,166 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class ConstantExpressionResolve : BaseResolve + { + public ConstantExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = base.Expression as ConstantExpression; + string customParameter = GetCustomParameter(parameter, expression); + if (customParameter == null) + { + DefaultConstant(parameter, expression); + } + else + { + CustomConstant(parameter, customParameter); + } + } + + private void CustomConstant(ExpressionParameter parameter, string customParameter) + { + var baseParameter = parameter.BaseParameter; + var isSetTempData = baseParameter.CommonTempData.HasValue() && baseParameter.CommonTempData.Equals(CommonTempDataType.Result); + if (isSetTempData) + { + baseParameter.CommonTempData = customParameter; + } + else + { + AppendMember(parameter, parameter.IsLeft, customParameter); + } + } + + private string GetCustomParameter(ExpressionParameter parameter, ConstantExpression expression) + { + string customParameter = null; + if (parameter.OppsiteExpression != null) + { + var exp = ExpressionTool.RemoveConvert(parameter.OppsiteExpression); + if (exp is MemberExpression) + { + var member = (exp as MemberExpression); + var memberParent = member.Expression; + if (memberParent != null && this.Context?.SugarContext?.Context != null) + { + var entity = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(memberParent.Type); + var columnInfo = entity.Columns.FirstOrDefault(it => it.PropertyName == member.Member.Name); + if (columnInfo?.SqlParameterDbType is Type) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { expression.Value, 100 }) as SugarParameter; + customParameter = base.AppendParameter(p); + + } + } + } + } + return customParameter; + } + + private void DefaultConstant(ExpressionParameter parameter, ConstantExpression expression) + { + var isLeft = parameter.IsLeft; + object value = ExpressionTool.GetValue(expression.Value, this.Context); + var isNullStr = value?.ObjToString() == "NULL"; + value = ConvetValue(parameter, expression, value); + if (IsEnumString(value)) + value = ConvertEnum(value); + var baseParameter = parameter.BaseParameter; + baseParameter.ChildExpression = expression; + var isSetTempData = baseParameter.CommonTempData.HasValue() && baseParameter.CommonTempData.Equals(CommonTempDataType.Result); + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.SelectSingle: + case ResolveExpressType.Update: + case ResolveExpressType.SelectMultiple: + baseParameter.CommonTempData = value; + break; + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + var parentIsBinary = parameter.BaseParameter.CurrentExpression is BinaryExpression; + var parentIsRoot = parameter.BaseParameter.CurrentExpression is LambdaExpression; + var isBool = value != null && value.GetType() == UtilConstants.BoolType; + if (parentIsRoot && isBool) + { + this.Context.Result.Append(value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False()); + break; + } + if (parentIsBinary && isBool) + { + var isLogicOperator = + parameter.BaseExpression.NodeType == ExpressionType.And || + parameter.BaseExpression.NodeType == ExpressionType.AndAlso || + parameter.BaseExpression.NodeType == ExpressionType.Or || + parameter.BaseExpression.NodeType == ExpressionType.OrElse; + if (isLogicOperator) + { + AppendMember(parameter, isLeft, (value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False())); + break; + } + } + if (value == null && parentIsBinary) + { + parameter.BaseParameter.ValueIsNull = true; + value = this.Context.DbMehtods.Null(); + } + if (isNullStr) + { + this.Context.Result.Append(AppendParameter(value)); + break; + } + AppendValue(parameter, isLeft, value); + } + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + default: + break; + } + } + + private object ConvetValue(ExpressionParameter parameter, ConstantExpression expression, object value) + { + if (expression.Type == UtilConstants.IntType && parameter.OppsiteExpression != null && ExpressionTool.IsUnConvertExpress(parameter.OppsiteExpression)) + { + var exp = ExpressionTool.RemoveConvert(parameter.OppsiteExpression); + if (exp.Type == typeof(char) && value is int) + { + value = Convert.ToChar(Convert.ToInt32(value)); + } + } + + return value; + } + + private object ConvertEnum(object value) + { + if (base.BaseParameter?.OppsiteExpression is UnaryExpression) + { + var oppsiteExpression = base.BaseParameter?.OppsiteExpression as UnaryExpression; + var oppsiteValue = oppsiteExpression.Operand; + if (oppsiteValue.Type.IsEnum()) + { + value = UtilMethods.ChangeType2(value, oppsiteValue.Type).ToString(); + } + } + + return value; + } + + private bool IsEnumString(object value) + { + return this.Context.TableEnumIsString == true + && value?.IsInt() == true + && base.BaseParameter?.OppsiteExpression != null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/LambdaExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/LambdaExpressionResolve.cs new file mode 100644 index 000000000..c455aeea0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/LambdaExpressionResolve.cs @@ -0,0 +1,18 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class LambdaExpressionResolve : BaseResolve + { + public LambdaExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + LambdaExpression lambda = base.Expression as LambdaExpression; + var expression = lambda.Body; + base.Expression = expression; + if (parameter.Context.ResolveType.IsIn(ResolveExpressType.FieldMultiple, ResolveExpressType.FieldSingle)) + { + parameter.CommonTempData = CommonTempDataType.Append; + } + base.Start(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs new file mode 100644 index 000000000..d68ac6629 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs @@ -0,0 +1,325 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class MapperExpressionResolve + { + private Expression expression; + private List mappers; + private InvalidOperationException ex; + private SqlSugarProvider context; + private QueryBuilder querybuiler; + private ISqlBuilder sqlBuilder; + private string sql; + public MapperExpressionResolve(Expression expression, InvalidOperationException ex) + { + this.expression = expression; + this.ex = ex; + this.mappers = CallContext.MapperExpression.Value; + Error01(); + var isMember = expression is MemberExpression; + if (isMember) + { + ResolveMember(); + } + else + { + ResolveList(); + } + } + + private void ResolveList() + { + var methodExpression = expression as MethodCallExpression; + var callName = methodExpression.Method.Name; + var exp = methodExpression.Arguments[0] as MemberExpression; + ThrowTrue(exp == null); + var childExpression = exp; + MapperExpression mapper = GetMapperMany(exp); + var fillInfo = GetFillInfoMany(childExpression, mapper); + var mappingFild1Info = GetMappingFild1ManyInfo(childExpression, mapper); + var mappingFild1Info2 = GetMappingFild2Info(childExpression, mapper); + //var SelectInfo = GetSelectInfo(expression); + this.context.InitMappingInfo(childExpression.Expression.Type); + var entity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Expression.Type); + oneToMany(methodExpression, callName, entity, childExpression.Expression.ToString(), fillInfo, mappingFild1Info, mappingFild1Info2); + } + + private void ResolveMember() + { + var exp = expression as MemberExpression; + ThrowTrue(exp.Expression == null); + var childExpression = exp.Expression; + MapperExpression mapper = GetMapper(exp); + var fillInfo = GetFillInfo(childExpression, mapper); + var mappingFild1Info = GetMappingFild1Info(childExpression, mapper); + var mappingFild1Info2 = GetMappingFild2Info(childExpression, mapper); + var SelectInfo = GetSelectInfo(expression); + var entity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type); + + var isExMapper = mappingFild1Info2 != null; + var isFillFild1SameType = fillInfo.Type == mappingFild1Info.Type; + var isSameProperty = false; + + if (isExMapper) + { + ExtMapper(fillInfo, mappingFild1Info, mappingFild1Info2, SelectInfo); + } + else if (isSameProperty) + { + + } + else if (isFillFild1SameType) + { + throw new NotSupportedException(expression.ToString()); + } + else + { + oneToOne(fillInfo, mappingFild1Info, mappingFild1Info2, SelectInfo); + } + } + + + private void oneToOne(MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2, MapperExpressionInfo selectInfo) + { + var pkColumn = selectInfo.EntityInfo.Columns.Where(it => it.IsPrimarykey == true).FirstOrDefault(); + if (pkColumn == null) + { + pkColumn = selectInfo.EntityInfo.Columns.First(); + } + var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName); + var whereLeft = sqlBuilder.GetTranslationColumnName(pkColumn.DbColumnName); + var whereRight = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString); + this.sql = this.context.Queryable() + .AS(tableName) + .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .Select(sqlBuilder.GetTranslationColumnName(selectInfo.FieldName)).ToSql().Key; + } + + private void oneToMany(MethodCallExpression methodCallExpression, string methodName, EntityInfo mainEntity, string shortName, MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2) + { + var pkColumn = mainEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + if (pkColumn == null) + { + pkColumn = mainEntity.Columns.FirstOrDefault(); + } + var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName); + var whereLeft = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString); + var whereRight = sqlBuilder.GetTranslationColumnName(shortName + "." + pkColumn.DbColumnName); + string whereExpression = GetWhereExpression(methodCallExpression); + if (methodName == "Any") + { + this.sql = " (" + this.context.Queryable() + .AS(tableName) + .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .WhereIF(!string.IsNullOrEmpty(whereExpression), whereExpression) + .Select("COUNT(1)").ToSql().Key + ")>0 "; + } + else + { + this.sql = this.context.Queryable() + .AS(tableName) + .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .WhereIF(!string.IsNullOrEmpty(whereExpression), whereExpression) + .Select("COUNT(1)").ToSql().Key; + } + } + + private string GetWhereExpression(MethodCallExpression methodCallExpression) + { + if (methodCallExpression.Arguments.Count <= 1) + return null; + var exp = methodCallExpression.Arguments[1]; + var querybuiler = InstanceFactory.GetQueryBuilder(this.context.CurrentConnectionConfig); + querybuiler.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.context.CurrentConnectionConfig); + querybuiler.Builder = InstanceFactory.GetSqlbuilder(this.context.CurrentConnectionConfig); + querybuiler.Builder.Context = querybuiler.Context; + querybuiler.Builder.QueryBuilder = querybuiler; + querybuiler.Context = this.context; + var expValue = querybuiler.GetExpressionValue(exp, ResolveExpressType.WhereMultiple); + var paramterName = (exp as LambdaExpression).Parameters[0].Name; + var sql = expValue.GetResultString(); + sql = sql.Replace(querybuiler.Builder.GetTranslationColumnName(paramterName) + ".", ""); + if (querybuiler.Parameters?.Count > 0) + { + foreach (var item in querybuiler.Parameters) + { + sql = sql.Replace(item.ParameterName, item.Value.ObjToString().ToSqlValue()); + } + } + return sql; + } + + private MapperExpressionInfo GetSelectInfo(Expression expression) + { + + var field = expression; + if (field is UnaryExpression) + { + field = (field as UnaryExpression).Operand; + } + var type = ((field as MemberExpression).Expression).Type; + this.context.InitMappingInfo(type); + var name = (field as MemberExpression).Member.Name; + var entity = this.context.EntityMaintenance.GetEntityInfo(type); + var fieldName = entity.Columns.First(it => it.PropertyName == name).DbColumnName; + return new MapperExpressionInfo() + { + Type = type, + FieldName = fieldName, + EntityInfo = entity + }; + } + + private MapperExpressionInfo GetMappingFild2Info(Expression childExpression, MapperExpression mapper) + { + if (mapper.MappingField2Expression == null) + return null; + var exp = mapper.MappingField2Expression; + var field = (exp as LambdaExpression).Body; + if (field is UnaryExpression) + { + field = (field as UnaryExpression).Operand; + } + var type = ((field as MemberExpression).Expression).Type; + this.context.InitMappingInfo(type); + var name = (field as MemberExpression).Member.Name; + var entity = this.context.EntityMaintenance.GetEntityInfo(type); + var fieldName = entity.Columns.First(it => it.PropertyName == name).DbColumnName; + return new MapperExpressionInfo() + { + Type = type, + FieldName = fieldName + }; + } + + private MapperExpressionInfo GetMappingFild1Info(Expression childExpression, MapperExpression mapper) + { + var exp = mapper.MappingField1Expression; + var field = (exp as LambdaExpression).Body; + if (field is UnaryExpression) + { + field = (field as UnaryExpression).Operand; + } + var type = ((field as MemberExpression).Expression).Type; + this.context.InitMappingInfo(type); + var name = (field as MemberExpression).Member.Name; + var entity = this.context.EntityMaintenance.GetEntityInfo(type); + var fieldName = entity.Columns.First(it => it.PropertyName == name).DbColumnName; + var array = (field as MemberExpression).ToString().Split('.').ToList(); + array[array.Count - 1] = fieldName; + var filedString = string.Join(".", array); + return new MapperExpressionInfo() + { + Type = type, + FieldName = fieldName, + FieldString = filedString, + EntityInfo = entity + }; + } + + private MapperExpressionInfo GetFillInfo(Expression childExpression, MapperExpression mapper) + { + this.querybuiler = mapper.QueryBuilder; + this.context = mapper.Context; + this.sqlBuilder = mapper.SqlBuilder; + if (this.querybuiler.TableShortName.IsNullOrEmpty()) + { + this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString(); + } + this.context.InitMappingInfo(childExpression.Type); + return new MapperExpressionInfo() + { + EntityInfo = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type) + }; + } + + private MapperExpression GetMapper(MemberExpression exp) + { + var mapper = mappers.Where(it => it.Type == MapperExpressionType.oneToOne) + .Reverse() + .Where(it => (it.FillExpression as LambdaExpression).Body.ToString() == exp.Expression.ToString()).FirstOrDefault(); + ThrowTrue(mapper == null); + return mapper; + } + + public string GetMemberName(MemberExpression memberExpression) + { + return ""; + } + + private void ExtMapper(MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2, MapperExpressionInfo selectInfo) + { + var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName); + var whereLeft = sqlBuilder.GetTranslationColumnName(mappingFild1Info2.FieldName); + var whereRight = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString); + this.sql = this.context.Queryable() + .AS(tableName) + .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .Select(sqlBuilder.GetTranslationColumnName(selectInfo.FieldName)).ToSql().Key; + } + + public MapperSql GetSql() + { + return new MapperSql() { Sql = " (" + this.sql + ") " }; + } + + private MapperExpression GetMapperMany(MemberExpression exp) + { + var mapper = mappers.Where(it => it.Type == MapperExpressionType.oneToN) + .Reverse() + .Where(it => (it.FillExpression as LambdaExpression).Body.ToString() == exp.ToString()).FirstOrDefault(); + ThrowTrue(mapper == null); + return mapper; + } + private MapperExpressionInfo GetFillInfoMany(Expression childExpression, MapperExpression mapper) + { + this.querybuiler = mapper.QueryBuilder; + this.context = mapper.Context; + this.sqlBuilder = mapper.SqlBuilder; + if (this.querybuiler.TableShortName.IsNullOrEmpty()) + { + this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString(); + } + var type = (childExpression as MemberExpression).Type.GetGenericArguments()[0]; + this.context.InitMappingInfo(type); + return new MapperExpressionInfo() + { + EntityInfo = this.context.EntityMaintenance.GetEntityInfo(type) + }; + } + private MapperExpressionInfo GetMappingFild1ManyInfo(Expression childExpression, MapperExpression mapper) + { + var exp = mapper.MappingField1Expression; + var field = (exp as LambdaExpression).Body; + if (field is UnaryExpression) + { + field = (field as UnaryExpression).Operand; + } + var type = ((field as MemberExpression).Expression).Type; + this.context.InitMappingInfo(type); + var name = (field as MemberExpression).Member.Name; + var entity = this.context.EntityMaintenance.GetEntityInfo(type); + var fieldName = entity.Columns.First(it => it.PropertyName == name).DbColumnName; + //var array = (field as MemberExpression).ToString().Split('.').ToList(); + //array[array.Count() - 1] = fieldName; + //var filedString = string.Join(".", array); + return new MapperExpressionInfo() + { + Type = type, + FieldName = fieldName, + FieldString = fieldName, + EntityInfo = entity + }; + } + + void Error01() + { + Check.Exception(mappers == null, ErrorMessage.GetThrowMessage(expression.ToString() + "no support Check if the navigation is configured correctly or Includes() is missing", "当前表达式" + expression.ToString() + " 不支持,查看导航是否配置正确等或者缺少Includes() ")); + } + void ThrowTrue(bool isError) + { + Check.Exception(isError, ErrorMessage.GetThrowMessage(expression.ToString() + "no support Check if the navigation is configured correctly or Includes() is missing", "不支持表达式" + expression.ToString() + " ,查看导航是否配置正确等或者缺少Includes() ")); + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberConstExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberConstExpressionResolve.cs new file mode 100644 index 000000000..e0d819ea7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberConstExpressionResolve.cs @@ -0,0 +1,69 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class MemberConstExpressionResolve : BaseResolve + { + public MemberConstExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = base.Expression as MemberExpression; + var isLeft = parameter.IsLeft; + object value = ExpressionTool.GetMemberValue(expression.Member, expression); + var baseParameter = parameter.BaseParameter; + var isSetTempData = baseParameter.CommonTempData.HasValue() && baseParameter.CommonTempData.Equals(CommonTempDataType.Result); + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.Update: + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + value = Select(parameter, value); + break; + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + Where(parameter, isLeft, value, baseParameter, isSetTempData); + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + break; + } + } + + private void Where(ExpressionParameter parameter, bool? isLeft, object value, ExpressionParameter baseParameter, bool isSetTempData) + { + if (parameter.OppsiteExpression != null) + { + var exp = ExpressionTool.RemoveConvert(parameter.OppsiteExpression); + value = GetMemberValue(value, exp); + var valueFullName = value?.GetType()?.FullName; + if (valueFullName == "Microsoft.Extensions.Primitives.StringValues") + { + value = value.ToString(); + } + } + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + AppendValue(parameter, isLeft, value); + } + } + + private object Select(ExpressionParameter parameter, object value) + { + if (value?.GetType().IsEnum() == true) + { + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString == true) + { + value = Convert.ToString(value); + } + else + { + value = Convert.ToInt64(value); + } + } + parameter.BaseParameter.CommonTempData = value; + return value; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs new file mode 100644 index 000000000..75ebf1956 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs @@ -0,0 +1,869 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class MemberExpressionResolve : BaseResolve + { + public ExpressionParameter Parameter { get; set; } + + public MemberExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + ExpressionParameter baseParameter; + MemberExpression expression; + bool? isLeft; + bool isSetTempData, isValue, isValueBool, isLength, isDateValue, isHasValue, isDateDate, isMemberValue, isSingle, fieldIsBool, isSelectField, isField; + SettingParameters(parameter, out baseParameter, out expression, out isLeft, out isSetTempData, out isValue, out isValueBool, out isLength, out isDateValue, out isHasValue, out isDateDate, out isMemberValue, out isSingle, out fieldIsBool, out isSelectField, out isField); + baseParameter.ChildExpression = expression; + ProcessNavigationMemberAndUpdateExpression(ref expression, ref isValue); + if (isLength) + { + ResolveLength(parameter, isLeft, expression); + } + else if (IsDateDiff(expression)) + { + ResolveDateDiff(parameter, isLeft, expression); + } + else if (expression.Member.Name == "DayOfWeek" && expression.Type == typeof(DayOfWeek)) + { + ResolveDayOfWeek(parameter, isLeft, expression); + } + else if (isHasValue) + { + ResolveHasValue(parameter, expression); + } + else if (isDateValue) + { + ResolveDateValue(parameter, isLeft, expression); + } + else if (isValueBool) + { + ResolveValueBool(parameter, baseParameter, expression, isLeft, isSingle); + } + else if (isValue && expression.Expression != null && expression.Expression is MethodCallExpression) + { + ResolveCallValue(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + } + else if (isValue & IsNavValue(expression)) + { + expression = expression.Expression as MemberExpression; + ResolveMemberValue(parameter, baseParameter, expression, isLeft, isSetTempData); + } + else if (isValue) + { + ResolveValue(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + } + else if (expression.Expression != null && expression.Expression.Type == UtilConstants.DateType && expression is MemberExpression && expression.Expression is MethodCallExpression) + { + ResolveDateDateByCall(parameter, isLeft, expression); + } + else if (isDateDate) + { + ResolveDateDate(parameter, isLeft, expression); + } + else if (IsConvertMemberName(expression)) + { + ResolveConvertMemberName(parameter, expression, isLeft); + } + else if (isMemberValue) + { + ResolveMemberValue(parameter, baseParameter, expression, isLeft, isSetTempData); + } + else if (fieldIsBool && !isField && !isSelectField) + { + ResolvefieldIsBool(parameter, baseParameter, isLeft, isSetTempData, expression, isSingle); + } + else + { + ResolveDefault(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + } + } + + private void ProcessNavigationMemberAndUpdateExpression(ref MemberExpression expression, ref bool isValue) + { + if (isValue && expression.Expression is MemberExpression childMemExp) + { + if (childMemExp.Expression is MemberExpression navMemExp) + { + if (ExpressionTool.IsNavMember(this.Context, navMemExp)) + { + expression = childMemExp; + isValue = false; + } + } + } + } + + + + #region Navigate + private static bool IsNavValue(MemberExpression expression) + { + var isDateMember = expression.Type == UtilConstants.DateType && expression.Expression is MemberExpression; + return isDateMember && + (expression.Expression as MemberExpression)?.Expression is MemberExpression; + } + private void DefaultOneToOneN(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, OneToOneNavgateExpressionN navN) + { + var value = navN.GetMemberSql(); + SetNavigateResult(); + this.Context.SingleTableNameSubqueryShortName = navN.shorName; + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + AppendValue(parameter, isLeft, value); + } + } + + private void DefaultOneToOne(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, OneToOneNavgateExpression nav) + { + var value = nav.GetSql(); + SetNavigateResult(); + this.Context.SingleTableNameSubqueryShortName = nav.ShorName; + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + AppendValue(parameter, isLeft, value); + } + } + + #endregion + + #region Resolve default + private void ResolveDefault(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + string fieldName = string.Empty; + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.Update: + case ResolveExpressType.SelectSingle: + fieldName = GetSingleName(parameter, expression, isLeft); + if (isSetTempData) + baseParameter.CommonTempData = fieldName; + else + base.Context.Result.Append(fieldName); + break; + case ResolveExpressType.SelectMultiple: + fieldName = GetMultipleName(parameter, expression, isLeft); + if (isSetTempData) + baseParameter.CommonTempData = fieldName; + else + base.Context.Result.Append(fieldName); + break; + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + ResolveWhereLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + break; + case ResolveExpressType.FieldSingle: + fieldName = GetSingleName(parameter, expression, isLeft); + var fieldIsCommonTemp = IsFieldIsCommonTemp(isSetTempData, parameter); + if (fieldIsCommonTemp) + { + baseParameter.CommonTempData = fieldName; + } + else + { + base.Context.Result.Append(fieldName); + } + break; + case ResolveExpressType.FieldMultiple: + fieldName = GetMultipleName(parameter, expression, isLeft); + var fieldIsCommonTemp2 = IsFieldIsCommonTemp(isSetTempData, parameter); + if (fieldIsCommonTemp2) + { + baseParameter.CommonTempData = fieldName; + } + else + { + base.Context.Result.Append(fieldName); + } + break; + case ResolveExpressType.ArrayMultiple: + case ResolveExpressType.ArraySingle: + fieldName = GetName(parameter, expression, isLeft, parameter.Context.ResolveType == ResolveExpressType.ArraySingle); + var fieldIsCommonTemp3 = IsFieldIsCommonTemp(isSetTempData, parameter); + if (fieldIsCommonTemp3) + { + baseParameter.CommonTempData = fieldName; + } + else + { + base.Context.Result.Append(fieldName); + } + break; + default: + break; + } + } + + private bool IsFieldIsCommonTemp(bool isSetTempData, ExpressionParameter parameter) + { + if (parameter.BaseParameter == null) + return false; + var childExpression = parameter.BaseParameter.ChildExpression.ObjToString(); + var expression = parameter.BaseParameter.CurrentExpression.ObjToString(); + var datevaluelist = UtilConstants.DateTypeStringList.Select(it => childExpression + "." + it); + return isSetTempData && datevaluelist.Contains(expression); + } + + #endregion + + #region Resolve Where + private void ResolveBoolLogic(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + string fieldName = string.Empty; + if (isSetTempData) + { + if (ExpressionTool.IsConstExpression(expression)) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + baseParameter.CommonTempData = value + "=1 "; + } + else + { + fieldName = GetName(parameter, expression, null, isSingle); + baseParameter.CommonTempData = fieldName + "=1 "; + } + } + else + { + if (ExpressionTool.IsConstExpression(expression)) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + base.AppendValue(parameter, isLeft, value + "=1 "); + } + else + { + fieldName = GetName(parameter, expression, isLeft, isSingle); + AppendMember(parameter, isLeft, fieldName + "=1 "); + } + } + } + + private void ResolveWhereLogic(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + string fieldName = string.Empty; + if (isSetTempData) + { + if (ExpressionTool.IsConstExpression(expression)) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + baseParameter.CommonTempData = value; + } + else + { + fieldName = GetName(parameter, expression, null, isSingle); + baseParameter.CommonTempData = fieldName; + } + } + else + { + if (ExpressionTool.IsConstExpression(expression)) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + base.AppendValue(parameter, isLeft, value); + } + else + { + fieldName = GetName(parameter, expression, isLeft, isSingle); + AppendMember(parameter, isLeft, fieldName); + } + } + } + #endregion + + #region Resolve special member + + private void ResolveMemberValue(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData) + { + var nav = new OneToOneNavgateExpression(this.Context?.SugarContext?.Context, this); + nav.ExpContext = this.Context; + var navN = new OneToOneNavgateExpressionN(this.Context?.SugarContext?.Context); + if (nav.IsNavgate(expression)) + { + if (this.Context?.SugarContext?.QueryBuilder?.JoinQueryInfos != null) + { + var p = expression.Expression.ObjToString(); + var querybuilder = this.Context?.SugarContext?.QueryBuilder; + var joinInfos = querybuilder.JoinQueryInfos; + var joinInfo = joinInfos.FirstOrDefault(it => $"{querybuilder.TableShortName}.{it.ShortName.Replace("pnv_", "")}" == p); + if (joinInfo != null) + { + var columnInfo = nav.ProPertyEntity.Columns.FirstOrDefault(it => it.PropertyName == nav.MemberName); + var value = new MapperSql() { Sql = querybuilder.Builder.GetTranslationColumnName(joinInfo.ShortName) + "." + querybuilder.Builder.GetTranslationColumnName(columnInfo.DbColumnName) }; + + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + AppendValue(parameter, isLeft, value); + } + } + else + { + DefaultOneToOne(parameter, baseParameter, isLeft, isSetTempData, nav); + } + } + else + { + DefaultOneToOne(parameter, baseParameter, isLeft, isSetTempData, nav); + } + } + else if (navN.IsNavgate(expression)) + { + DefaultOneToOneN(parameter, baseParameter, isLeft, isSetTempData, navN); + } + else + { + ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression); + } + } + + private void ResolveConvertMemberName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft) + { + var memParameter = (expression.Expression as UnaryExpression).Operand as ParameterExpression; + var name = ExpressionTool.GetMemberName(expression); + if (this.Context.IsSingle) + { + AppendMember(parameter, isLeft, this.Context.GetTranslationColumnName(name)); + } + else + { + AppendMember(parameter, isLeft, this.Context.GetTranslationColumnName(memParameter.Name + "." + name)); + } + } + + private void ResolveDayOfWeek(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var exp = expression.Expression; + var value = GetNewExpressionValue(exp); + var result = this.Context.DbMehtods.DateValue(new MethodCallExpressionModel() + { + Args = new List() { + + new MethodCallExpressionArgs(){ + MemberName=value, + MemberValue=value + }, + new MethodCallExpressionArgs(){ + MemberName=DateType.Weekday, + MemberValue=DateType.Weekday + } + } + }); ; + base.AppendMember(parameter, isLeft, result); + } + + + private void ResolveDateDiff(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var binaryExp = expression.Expression as BinaryExpression; + var beginExp = binaryExp.Right; + var endExp = binaryExp.Left; + + var dateType = DateType.Day; + var begin = GetNewExpressionValue(beginExp); + var end = GetNewExpressionValue(endExp); + + foreach (var item in UtilMethods.EnumToDictionary()) + { + if (expression.Member.Name.Contains(item.Key, StringComparison.CurrentCultureIgnoreCase)) + { + dateType = item.Value; + break; + } + } + var result = this.Context.DbMehtods.DateDiff(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ + MemberName=dateType, + MemberValue=dateType + }, + new MethodCallExpressionArgs(){ + MemberName=begin, + MemberValue=begin + }, + new MethodCallExpressionArgs(){ + MemberName=end, + MemberValue=end + } + } + }); ; + base.AppendMember(parameter, isLeft, result); + } + private void ResolveDateDateByCall(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var value = GetNewExpressionValue(expression.Expression); + if (expression.Member.Name == "Date") + { + AppendMember(parameter, isLeft, GetToDateShort(value)); + } + else + { + foreach (int myCode in Enum.GetValues(typeof(DateType))) + { + string strName = Enum.GetName(typeof(DateType), myCode);//获取名称 + if (expression.Member.Name == strName) + { + AppendMember(parameter, isLeft, this.Context.DbMehtods.MergeString(this.GetDateValue(value, (DateType)(myCode)))); + } + } + } + } + private void ResolveCallValue(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + try + { + baseParameter.ChildExpression = expression; + string fieldName = string.Empty; + if (isSetTempData) + { + var value = ExpressionTool.DynamicInvoke(expression); + baseParameter.CommonTempData = value; + } + else + { + var value = ExpressionTool.DynamicInvoke(expression); + base.AppendValue(parameter, isLeft, value); + } + } + catch + { + Check.Exception(true, "Not Support {0}", expression.ToString()); + } + } + + private MemberExpression ResolveValue(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + expression = expression.Expression as MemberExpression; + baseParameter.ChildExpression = expression; + if (UtilMethods.GetUnderType(expression.Type) == UtilConstants.BoolType && parameter.BaseExpression != null && ExpressionTool.IsLogicOperator(parameter.BaseExpression)) + { + ResolveBoolLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + } + else + { + ResolveWhereLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + } + return expression; + } + + private void ResolveValueBool(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSingle) + { + string fieldName = GetName(parameter, expression.Expression as MemberExpression, isLeft, isSingle); + if (expression.Type == UtilConstants.BoolType && baseParameter.OperatorValue.IsNullOrEmpty()) + { + fieldName = this.Context.DbMehtods.EqualTrue(fieldName); + } + AppendMember(parameter, isLeft, fieldName); + } + + private void ResolveMemberValue(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, MemberExpression expression) + { + if (ExpressionTool.IsOwnsOne(this.Context, expression)) + { + var column = ExpressionTool.GetOwnsOneColumnInfo(this.Context, expression); + var columnName = column.DbColumnName; + if (this.Context.IsJoin) + { + var expParameterInfo = ExpressionTool.GetParameters(expression).First(); + columnName = $"{expParameterInfo.Name}.{columnName}"; + } + columnName = this.Context.GetTranslationColumnName(columnName); + if (isSetTempData) + { + baseParameter.CommonTempData = columnName; + } + else + { + AppendMember(parameter, isLeft, columnName); + } + return; + } + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + if (isSetTempData) + { + if (value is MapperSql) + { + value = (value as MapperSql).Sql; + } + baseParameter.CommonTempData = value; + } + else + { + if (parameter?.OppsiteExpression != null) + { + var exp = ExpressionTool.RemoveConvert(parameter?.OppsiteExpression); + if (exp is MemberExpression) + { + var member = (exp as MemberExpression); + var memberParent = member.Expression; + if (memberParent != null && this.Context?.SugarContext?.Context != null) + { + var entity = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(memberParent.Type); + var columnInfo = entity.Columns.FirstOrDefault(it => it.PropertyName == member.Member.Name); + if (columnInfo?.SqlParameterDbType is Type) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + this.ContentIndex }) as SugarParameter; + value = p.Value; + } + } + } + } + AppendValue(parameter, isLeft, value); + } + } + private void ResolvefieldIsBool(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, MemberExpression expression, bool isSingle) + { + var fieldName = GetName(parameter, expression, isLeft, isSingle); + if (isSetTempData) + { + baseParameter.CommonTempData = fieldName; + } + else + { + fieldName = this.Context.DbMehtods.EqualTrue(fieldName.ObjToString()); + AppendMember(parameter, isLeft, fieldName); + } + } + + private void ResolveDateDate(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var name = expression.Member.Name; + var oldCommonTempDate = parameter.CommonTempData; + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + this.Start(); + var isConst = parameter.CommonTempData.GetType() == UtilConstants.DateType; + if (isConst) + { + if (this.Context?.Case?.IsDateString == true) + { + AppendMember(parameter, isLeft, GetToDateShort("'" + parameter.CommonTempData.ObjToDate().Date.ToString("yyyy-MM-dd") + "'")); + } + else + { + AppendValue(parameter, isLeft, parameter.CommonTempData.ObjToDate().Date); + } + } + else + { + var GetYear = new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs() { IsMember=true, MemberName=parameter.CommonTempData, MemberValue=parameter.CommonTempData }, + new MethodCallExpressionArgs() { MemberName=DateType.Year, MemberValue=DateType.Year} + } + }; + if (parameter.CommonTempData is MapperSql) + { + parameter.CommonTempData = ((MapperSql)parameter.CommonTempData).Sql; + } + AppendMember(parameter, isLeft, GetToDateShort(parameter.CommonTempData.ObjToString())); + } + parameter.CommonTempData = oldCommonTempDate; + } + + private void ResolveDateValue(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var name = expression.Member.Name; + var oldCommonTempDate = parameter.CommonTempData; + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + var isConst = this.Expression is ConstantExpression; + var isDateTimeNowDateStartWith = expression.ObjToString().StartsWith("DateTime.Now.Date."); + var isDateContains = expression.ObjToString().Contains(".Date."); + if (this.Expression.Type == UtilConstants.DateType && this.Expression.ToString() == "DateTime.Now") + { + this.Expression = expression; + var parameterName = base.AppendParameter(ExpressionTool.GetMemberValue(expression.Member, expression)); + base.AppendMember(parameter, isLeft, parameterName); + } + else if (isDateTimeNowDateStartWith) + { + this.Expression = expression; + var parameterName = base.AppendParameter(ExpressionTool.GetMemberValue(expression.Member, expression)); + base.AppendMember(parameter, isLeft, parameterName); + } + else if (isDateContains) + { + parameter.CommonTempData = base.GetNewExpressionValue(this.Expression); + var result = this.Context.DbMehtods.DateValue(new MethodCallExpressionModel() + { + Conext = this.Context, + Args = new List() { + new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }, + new MethodCallExpressionArgs() { IsMember = true, MemberName = name, MemberValue = name } + } + }); + base.AppendMember(parameter, isLeft, result); + } + else + { + this.Start(); + if (parameter.CommonTempData != null && parameter.CommonTempData is DateTime) + { + parameter.CommonTempData = base.AppendParameter(parameter.CommonTempData); + } + else if (parameter.CommonTempData != null && parameter.CommonTempData?.GetType()?.FullName == "System.DateOnly") + { + parameter.CommonTempData = base.AppendParameter(parameter.CommonTempData); + } + var result = this.Context.DbMehtods.DateValue(new MethodCallExpressionModel() + { + Conext = this.Context, + Args = new List() { + new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }, + new MethodCallExpressionArgs() { IsMember = true, MemberName = name, MemberValue = name } + } + }); + base.AppendMember(parameter, isLeft, result); + } + parameter.CommonTempData = oldCommonTempDate; + } + + private void ResolveHasValue(ExpressionParameter parameter, MemberExpression expression) + { + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + this.Start(); + var methodParamter = new MethodCallExpressionArgs() { IsMember = true, MemberName = parameter.CommonTempData, MemberValue = null }; + if (expression.Expression?.Type != null) + { + methodParamter.Type = UtilMethods.GetUnderType(expression.Expression?.Type); + } + var result = this.Context.DbMehtods.HasValue(new MethodCallExpressionModel() + { + Args = new List() { + methodParamter + } + }); + if (parameter.BaseExpression != null && ExpressionTool.IsLogicOperator(parameter.BaseExpression) && parameter.IsLeft == true) + { + if (base.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + base.Context.Result.Replace(ExpressionConst.FormatSymbol, ""); + } + this.Context.Result.Append(result + " " + ExpressionTool.GetOperator(parameter.BaseExpression.NodeType) + " "); + } + else + { + this.Context.Result.Append(result); + } + parameter.CommonTempData = null; + } + + private void ResolveLength(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var ps = ExpressionTool.GetParameters(expression); + if (expression.Expression != null && ps.Count == 0) + { + var p = base.AppendParameter(ExpressionTool.DynamicInvoke(expression.Expression)); + var methodParamter2 = new MethodCallExpressionArgs() { IsMember = true, MemberName = p, MemberValue = null }; + var result2 = this.Context.DbMehtods.Length(new MethodCallExpressionModel() + { + Args = new List() { + methodParamter2 + } + }); + base.AppendMember(parameter, isLeft, result2); + return; + } + if (parameter.Context.ResolveType == ResolveExpressType.FieldSingle) + { + parameter.Context.ResolveType = ResolveExpressType.WhereSingle; + } + if (parameter.Context.ResolveType == ResolveExpressType.FieldMultiple) + { + parameter.Context.ResolveType = ResolveExpressType.WhereMultiple; + } + var oldCommonTempDate = parameter.CommonTempData; + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + var isConst = this.Expression is ConstantExpression; + this.Start(); + var methodParamter = new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }; + var result = this.Context.DbMehtods.Length(new MethodCallExpressionModel() + { + Args = new List() { + methodParamter + } + }); + base.AppendMember(parameter, isLeft, result); + parameter.CommonTempData = oldCommonTempDate; + } + #endregion + + #region Helper + private static bool IsConvertMemberName(MemberExpression expression) + { + return expression.Expression is UnaryExpression && (expression.Expression as UnaryExpression).Operand is ParameterExpression; + } + + private static bool IsDateDiff(MemberExpression expression) + { + if (expression.Expression != null && + expression.Expression is BinaryExpression) + { + var binExp = (expression.Expression as BinaryExpression); + var nodeType = binExp.NodeType; + if (nodeType == ExpressionType.Subtract && binExp.Left.Type == UtilConstants.DateType && binExp.Right.Type == UtilConstants.DateType) + { + return true; + } + } + return + expression.Expression != null && + expression.Expression is BinaryExpression && + expression.Expression.Type == UtilConstants.TimeSpanType && + expression.Member.Name.StartsWith("Total") && + expression.Member.Name.EndsWith('s') + ; + } + + private string AppendMember(ExpressionParameter parameter, bool? isLeft, string fieldName) + { + if (parameter.BaseExpression is BinaryExpression || (parameter.BaseParameter.CommonTempData?.Equals(CommonTempDataType.Append) == true)) + { + fieldName = string.Format(" {0} ", fieldName); + if (isLeft == true) + { + fieldName += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index; + } + if (base.Context.Result.Contains(ExpressionConst.FormatSymbol)) + { + base.Context.Result.Replace(ExpressionConst.FormatSymbol, fieldName); + } + else + { + base.Context.Result.Append(fieldName); + } + } + else + { + base.Context.Result.Append(fieldName); + } + + return fieldName; + } + + private string GetName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft, bool isSingle) + { + if (isSingle) + { + return GetSingleName(parameter, expression, IsLeft); + } + else + { + return GetMultipleName(parameter, expression, IsLeft); + } + } + + private string GetMultipleName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft) + { + string shortName = expression.Expression.ToString(); + string fieldName = expression.Member.Name; + fieldName = this.Context.GetDbColumnName(expression.Expression.Type.Name, fieldName); + if (UtilMethods.GetMoreSetting(this.Context).IsCorrectErrorSqlParameterName) + { + fieldName = Context.GetTranslationColumnName(shortName) + UtilConstants.Dot + Context.GetTranslationColumnName(fieldName); + } + else + { + fieldName = Context.GetTranslationColumnName(shortName + UtilConstants.Dot + fieldName); + } + return fieldName; + } + + private string GetSingleName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft) + { + string fieldName = expression.Member.Name; + fieldName = this.Context.GetDbColumnName(expression.Expression.Type.Name, fieldName); + + var isSpace = fieldName.Contains(UtilConstants.Space); + var guid = string.Empty; + if (isSpace) + { + guid = SnowFlakeSingle.Instance.NextId().ToString(); + fieldName = fieldName.Replace(UtilConstants.Space, guid); + } + fieldName = Context.GetTranslationColumnName(fieldName); + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true && fieldName?.Contains(ExpressionConst.LeftParenthesis) == true) + { + fieldName = Context.GetTranslationText(fieldName); + } + if (isSpace) + { + fieldName = fieldName.Replace(guid, UtilConstants.Space); + } + return fieldName; + } + + private string GetDateValue(object value, DateType type) + { + var pars = new MethodCallExpressionModel() + { + Conext = this.Context, + Args = new List() { + new MethodCallExpressionArgs() { IsMember=true, MemberName=value, MemberValue=value }, + new MethodCallExpressionArgs() { MemberName=type, MemberValue=type} + } + }; + return this.Context.DbMehtods.DateValue(pars); + } + + private string GetToDateShort(string value) + { + var pars = new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs() { MemberName=value, MemberValue=value }, + } + }; + return this.Context.DbMehtods.ToDateShort(pars); + } + + private void SettingParameters(ExpressionParameter parameter, out ExpressionParameter baseParameter, out MemberExpression expression, out bool? isLeft, out bool isSetTempData, out bool isValue, out bool isValueBool, out bool isLength, out bool isDateValue, out bool isHasValue, out bool isDateDate, out bool isMemberValue, out bool isSingle, out bool fieldIsBool, out bool isSelectField, out bool isField) + { + baseParameter = parameter.BaseParameter; + expression = base.Expression as MemberExpression; + var childExpression = expression.Expression as MemberExpression; + var memberName = expression.Member.Name; + var childIsMember = childExpression != null; + var isRoot = parameter.BaseExpression == null; + isLeft = parameter.IsLeft; + isSetTempData = parameter.IsSetTempData; + isValue = memberName == "Value" && expression.Member.DeclaringType.Name == "Nullable`1"; + var isBool = expression.Type == UtilConstants.BoolType; + isValueBool = isValue && isBool && isRoot; + isLength = memberName == "Length" && childIsMember && childExpression.Type == UtilConstants.StringType; + isDateValue = memberName.IsIn(Enum.GetNames(typeof(DateType))) && (childIsMember && childExpression.Type == UtilConstants.DateType); + if (isDateValue == false && childIsMember && childExpression?.Type?.FullName == "System.DateOnly" && memberName.IsIn(Enum.GetNames(typeof(DateType)))) + { + isDateValue = true; + } + var isLogicOperator = ExpressionTool.IsLogicOperator(baseParameter.OperatorValue) || baseParameter.OperatorValue.IsNullOrEmpty(); + isHasValue = isLogicOperator && memberName == "HasValue" && expression.Expression != null && expression.NodeType == ExpressionType.MemberAccess; + isDateDate = memberName == "Date" && expression.Expression.Type == UtilConstants.DateType; + isMemberValue = expression.Expression != null && expression.Expression.NodeType != ExpressionType.Parameter && !isValueBool; + isSingle = parameter.Context.ResolveType.IsIn(ResolveExpressType.WhereSingle, ResolveExpressType.SelectSingle, ResolveExpressType.FieldSingle, ResolveExpressType.ArraySingle); + fieldIsBool = isBool && isLogicOperator && (parameter.BaseParameter == null || !(parameter.BaseParameter.CurrentExpression is MemberInitExpression || parameter.BaseParameter.CurrentExpression is NewExpression)); + var isSelect = this.Context.ResolveType.IsIn(ResolveExpressType.SelectSingle, ResolveExpressType.SelectMultiple); + isSelectField = isSelect && isRoot; + isField = this.Context.ResolveType.IsIn(ResolveExpressType.FieldSingle, ResolveExpressType.FieldMultiple); + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs new file mode 100644 index 000000000..d304ffb45 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs @@ -0,0 +1,385 @@ +using System.Linq.Expressions; +using System.Reflection; +namespace SqlSugar +{ + public class MemberInitExpressionResolve : BaseResolve + { + public MemberInitExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = base.Expression as MemberInitExpression; + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + break; + case ResolveExpressType.WhereMultiple: + break; + case ResolveExpressType.ArraySingle: + case ResolveExpressType.SelectSingle: + Select(expression, parameter, true); + break; + case ResolveExpressType.SelectMultiple: + Select(expression, parameter, false); + break; + case ResolveExpressType.FieldSingle: + break; + case ResolveExpressType.FieldMultiple: + break; + case ResolveExpressType.Update: + Update(expression, parameter); + break; + default: + break; + } + } + + private void Update(MemberInitExpression expression, ExpressionParameter parameter) + { + int i = 0; + var entityMaintenance = this.Context?.SugarContext?.Context?.EntityMaintenance; + foreach (MemberBinding binding in expression.Bindings) + { + ++i; + if (binding.BindingType != MemberBindingType.Assignment) + { + throw new NotSupportedException(); + } + MemberAssignment memberAssignment = (MemberAssignment)binding; + var type = expression.Type; + var memberName = this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name); + var item = memberAssignment.Expression; + item = ExpressionTool.RemoveConvert(item); + //Column IsJson Handler + if (memberAssignment.Member.CustomAttributes != null) + { + var customAttribute = memberAssignment.Member.GetCustomAttribute(); + + if (customAttribute?.IsJson ?? false) + { + var paramterValue = ExpressionTool.DynamicInvoke(item); + var parameterName = AppendParameter(new SerializeService().SerializeObject(paramterValue)); + var parameterObj = this.Context.Parameters.FirstOrDefault(it => it.ParameterName == parameterName); + if (parameterObj != null) + { + parameterObj.IsJson = true; + } + this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); + + continue; + } + } + + if ((item is MemberExpression) && ((MemberExpression)item).Expression == null) + { + var paramterValue = ExpressionTool.DynamicInvoke(item); + string parameterName = AppendParameter(paramterValue); + this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); + } + else if (entityMaintenance?.GetEntityInfo(type).Columns.Any(it => it.SqlParameterDbType is Type + && it.PropertyInfo.Name == memberName) == true + && IsConstNew(ExpressionTool.RemoveConvertThanOne(item))) + { + var columnInfo = entityMaintenance.GetEntityInfo(expression.Type).Columns.First(it => it.SqlParameterDbType is Type && it.PropertyInfo.Name == memberName); + var columnDbType = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = columnDbType.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(columnDbType); + var value = ExpressionTool.DynamicInvoke(item); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + i }) as SugarParameter; + parameter.Context.Result.Append(base.Context.GetEqString(memberName, p.ParameterName)); + this.Context.Parameters.Add(p); + } + else if (IsNotMember(item)) + { + if (base.Context.Result.IsLockCurrentParameter == false) + { + base.Context.Result.CurrentParameter = parameter; + base.Context.Result.IsLockCurrentParameter = true; + parameter.IsAppendTempDate(); + base.Expression = item; + base.Expression = (item as UnaryExpression).Operand; + base.Start(); + parameter.IsAppendResult(); + var result = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=parameter.CommonTempData.ObjToString()+"=1",Type=UtilConstants.BoolType }, + new MethodCallExpressionArgs(){ IsMember=true,MemberName=AppendParameter(0) }, + new MethodCallExpressionArgs(){ IsMember=true, MemberName=AppendParameter(1) } + } + }); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, result)); + base.Context.Result.CurrentParameter = null; + } + } + else if (IsNotParameter(item)) + { + try + { + parameter.Context.Result.Append(base.Context.GetEqString(memberName, AppendParameter(ExpressionTool.DynamicInvoke(item).ObjToBool()))); + } + catch + { + throw new NotSupportedException(item.ToString()); + } + } + else if (IsMethod(item)) + { + if (item is UnaryExpression) + item = (item as UnaryExpression).Operand; + var callMethod = item as MethodCallExpression; + if (MethodTimeMapping.Any(it => it.Key == callMethod.Method.Name) || MethodMapping.Any(it => it.Key == callMethod.Method.Name) || IsExtMethod(callMethod.Method.Name) || IsSubMethod(callMethod) || callMethod.Method.DeclaringType.FullName.StartsWith(UtilConstants.AssemblyName + UtilConstants.Dot)) + { + MethodCall(parameter, memberName, item); + } + else + { + var paramterValue = ExpressionTool.DynamicInvoke(item); + string parameterName = AppendParameter(paramterValue); + this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); + } + } + else if (IsConst(item) && IsConvert(item) && UtilMethods.IsNullable(item.Type) && UtilMethods.GetUnderType(item.Type) == UtilConstants.BoolType) + { + item = (item as UnaryExpression).Operand; + parameter.Context.Result.Append(base.Context.GetEqString(memberName, GetNewExpressionValue(item))); + } + else if (IsConst(item)) + { + base.Expression = ExpressionTool.RemoveConvertThanOne(item); + base.Start(); + string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); + var addItem = new SugarParameter(parameterName, parameter.CommonTempData); + if (addItem.Value == null && item.Type?.Name == "Nullable`1") + { + var genericType = item.Type?.GenericTypeArguments?.FirstOrDefault(); + if (genericType != null) + { + addItem.DbType = new SugarParameter(parameterName, UtilMethods.GetDefaultValue(genericType)).DbType; + } + } + ConvertParameterTypeByType(item, addItem); + + this.Context.Parameters.Add(addItem); + this.Context.ParameterIndex++; + } + else if (item is MemberExpression) + { + if (base.Context.Result.IsLockCurrentParameter == false) + { + base.Context.Result.CurrentParameter = parameter; + base.Context.Result.IsLockCurrentParameter = true; + parameter.IsAppendTempDate(); + base.Expression = item; + base.Start(); + parameter.IsAppendResult(); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString().Replace(",", UtilConstants.ReplaceCommaKey))); + + if (this.Context.Parameters != null) + { + var memberParameter = this.Context.Parameters?.FirstOrDefault(it => it.Value == null && it.ParameterName == parameter.CommonTempData.ObjToString()); + if (memberParameter != null) + { + ConvertParameterTypeByType(item, memberParameter); + } + } + + base.Context.Result.CurrentParameter = null; + } + } + else if (item is BinaryExpression) + { + var result = GetNewExpressionValue(item); + if (result.HasValue()) + { + result = result.Replace(",", UtilConstants.ReplaceCommaKey); + } + this.Context.Result.Append(base.Context.GetEqString(memberName, result)); + } + else if (item is MemberInitExpression) + { + try + { + var value = ExpressionTool.DynamicInvoke(item); + var parameterName = AppendParameter(value); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); + } + catch (Exception ex) + { + throw new NotSupportedException("Not Supported " + item.ToString() + " " + ex.Message); + } + } + else if (item is NewExpression) + { + try + { + var value = ExpressionTool.DynamicInvoke(item); + var parameterName = AppendParameter(value); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); + } + catch (Exception ex) + { + throw new NotSupportedException("Not Supported " + item.ToString() + " " + ex.Message); + } + } + else if (item is ConditionalExpression) + { + var result = GetNewExpressionValue(item); + this.Context.Result.Append(base.Context.GetEqString(memberName, result)); + } + } + } + + private static void ConvertParameterTypeByType(Expression item, SugarParameter addItem) + { + var dataType = UtilMethods.GetUnderType(item.Type); + if (addItem.Value == null && dataType == UtilConstants.DateType) + { + addItem.DbType = System.Data.DbType.Date; + } + if (addItem.Value == null && dataType.IsIn(UtilConstants.ULongType, UtilConstants.UIntType, UtilConstants.FloatType, UtilConstants.IntType, UtilConstants.LongType, UtilConstants.DecType, UtilConstants.DobType)) + { + addItem.DbType = System.Data.DbType.Int32; + } + if (addItem.Value == null && dataType == UtilConstants.BoolType) + { + addItem.DbType = System.Data.DbType.Boolean; + } + } + + private static bool IsConst(Expression item) + { + return item is UnaryExpression || item.NodeType == ExpressionType.Constant || (item is MemberExpression) && ((MemberExpression)item).Expression.NodeType == ExpressionType.Constant; + } + private static bool IsConstNew(Expression item) + { + if (item != null) + { + if (ExpressionTool.GetParameters(item).Count == 0) + { + return true; + } + } + return item is UnaryExpression || item.NodeType == ExpressionType.Constant || (item is MemberExpression) && ((MemberExpression)item).Expression.NodeType == ExpressionType.Constant; + } + + private static bool IsMethod(Expression item) + { + return item is MethodCallExpression || (item is UnaryExpression && (item as UnaryExpression).Operand is MethodCallExpression); + } + + private void MethodCall(ExpressionParameter parameter, string memberName, Expression item) + { + if (IsSubMethod(item as MethodCallExpression)) + { + UtilMethods.GetOldValue(parameter.CommonTempData, () => + { + parameter.CommonTempData = CommonTempDataType.Result; + base.Expression = item; + base.Start(); + var subSql = base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString()); + var isSubJoin = subSql.Contains(" JOIN ") && subSql.Contains(" ON "); + if (subSql.Contains(',')) + { + subSql = subSql.Replace(",", UtilConstants.ReplaceCommaKey); + } + if (ResolveExpressType.Update == this.Context.ResolveType) + { + string name = this.Context.GetTranslationTableName(parameter.CurrentExpression.Type.Name, true); + if (name.Contains('.')) + { + + } + else if (isSubJoin) + { + var shortName = (base.BaseParameter.BaseParameter.CurrentExpression as LambdaExpression).Parameters[0].Name; + subSql = subSql.Replace(this.Context.GetTranslationColumnName(shortName), name); + } + else + { + var p = (base.BaseParameter?.BaseParameter?.CurrentExpression as LambdaExpression)?.Parameters[0].Name; + subSql = subSql.Replace(this.Context.SqlTranslationLeft + p + this.Context.SqlTranslationRight + ".", name + "."); + subSql = subSql.Replace(this.Context.SqlTranslationLeft + p.ToUpper() + this.Context.SqlTranslationRight + ".", name + "."); + subSql = subSql.Replace(this.Context.SqlTranslationLeft + p.ToLower() + this.Context.SqlTranslationRight + ".", name + "."); + } + } + parameter.Context.Result.Append(subSql); + }); + } + else + { + base.Expression = item; + base.Start(); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString().Replace(",", UtilConstants.ReplaceCommaKey))); + } + } + + private void Select(MemberInitExpression expression, ExpressionParameter parameter, bool isSingle) + { + foreach (MemberBinding binding in expression.Bindings) + { + if (binding.BindingType != MemberBindingType.Assignment) + { + throw new NotSupportedException(); + } + MemberAssignment memberAssignment = (MemberAssignment)binding; + var memberName = memberAssignment.Member.Name; + if (this.Context?.SugarContext?.QueryBuilder?.AppendNavInfo?.MappingNavProperties?.ContainsKey(memberName) == true) + { + continue; + } + var item = memberAssignment.Expression; + if (item.Type.IsClass() && item is MemberExpression && (item as MemberExpression).Expression is ParameterExpression) + { + var rootType = ((item as MemberExpression).Expression as ParameterExpression).Type; + if (this.Context.SugarContext != null) + { + var navColumn = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(rootType) + .Columns.FirstOrDefault(x => x.PropertyName == memberName); + if (navColumn?.Navigat != null) + { + break; + } + } + } + if (IsNullable(item) && item is UnaryExpression) + { + var memtype = ExpressionTool.GetMemberInfoType(memberAssignment.Member); + if (IsNullable(memtype) && UtilMethods.GetUnderType(memtype) == UtilMethods.GetUnderType(item.Type)) + { + item = (item as UnaryExpression).Operand; + } + } + ResolveNewExpressions(parameter, item, memberName); + } + } + + private static bool IsNullable(Type memtype) + { + return memtype.Name == "Nullable`1"; + } + + private static bool IsNullable(Expression item) + { + return item.Type.Name == "Nullable`1"; + } + + //private bool IsSubMethod(MethodCallExpression express) + //{ + // return SubTools.SubItemsConst.Any(it =>express.Object != null && express.Object.Type.Name == "Subqueryable`1"); + //} + private bool IsExtMethod(string methodName) + { + if (this.Context.SqlFuncServices == null) return false; + return this.Context.SqlFuncServices.Select(it => it.UniqueMethodName).Contains(methodName); + } + private bool CheckMethod(MethodCallExpression expression) + { + if (IsExtMethod(expression.Method.Name)) + return true; + if (expression.Method.ReflectedType().FullName != ExpressionConst.SqlFuncFullName) + return false; + else + return true; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberNewExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberNewExpressionResolve.cs new file mode 100644 index 000000000..081e6d7ff --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberNewExpressionResolve.cs @@ -0,0 +1,14 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class MemberNewExpressionResolve : BaseResolve + { + public MemberNewExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = base.Expression as MemberExpression; + var isLeft = parameter.IsLeft; + object value = null; + value = ExpressionTool.DynamicInvoke(expression); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberNoExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberNoExpressionResolve.cs new file mode 100644 index 000000000..b6ee7fea4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MemberNoExpressionResolve.cs @@ -0,0 +1,61 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class MemberNoExpressionResolve : BaseResolve + { + public MemberNoExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = base.Expression as MemberExpression; + var isLeft = parameter.IsLeft; + var isField = expression.Member is System.Reflection.FieldInfo; + var isProperty = expression.Member is System.Reflection.PropertyInfo; + var baseParameter = parameter.BaseParameter; + var isSetTempData = baseParameter.CommonTempData.HasValue() && baseParameter.CommonTempData.Equals(CommonTempDataType.Result); + object value = GetValue(expression, isField, isProperty); + switch (base.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + Update(parameter, isLeft, baseParameter, isSetTempData, value); + break; + case ResolveExpressType.FieldSingle: + break; + case ResolveExpressType.FieldMultiple: + break; + default: + break; + } + } + + private void Update(ExpressionParameter parameter, bool? isLeft, ExpressionParameter baseParameter, bool isSetTempData, object value) + { + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + AppendValue(parameter, isLeft, value); + } + } + + private static object GetValue(MemberExpression expression, bool isField, bool isProperty) + { + object value = null; + if (isField) + { + value = ExpressionTool.GetFiledValue(expression); + } + else if (isProperty) + { + value = ExpressionTool.GetPropertyValue(expression); + } + + return value; + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs new file mode 100644 index 000000000..fa40e16c4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs @@ -0,0 +1,339 @@ +using SqlSugar; + +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class MethodCallExpressionResolve : BaseResolve + { + int contextIndex = 0; + + public MethodCallExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + contextIndex = this.Context.Index; + var express = base.Expression as MethodCallExpression; + if (express == null) return; + var isLeft = parameter.IsLeft; + string methodName = express.Method.Name; + var isValidNativeMethod = IsValidNativeMethod(express, methodName); + List appendArgs = null; + if (MethodTimeMapping.TryGetValue(methodName, out DateType dateType)) + { + appendArgs = new List(); + string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; + appendArgs.Add(new MethodCallExpressionArgs() { IsMember = false, MemberName = paramterName, MemberValue = dateType }); + this.Context.Parameters.Add(new SugarParameter(paramterName, dateType.ToString())); + this.Context.ParameterIndex++; + methodName = "DateAdd"; + isValidNativeMethod = true; + } + else if (methodName == "get_Item") + { + string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; + this.Context.Parameters.Add(new SugarParameter(paramterName, ExpressionTool.DynamicInvoke(express))); + this.Context.Result.Append(string.Format(" {0} ", paramterName)); + this.Context.ParameterIndex++; + return; + } + else if (methodName == "NewGuid") + { + this.Context.Result.Append(this.Context.DbMehtods.NewUid(null)); + return; + } + else if (methodName == "GetConfigValue") + { + GetConfigValue(express, parameter); + return; + } + else if (IsSubMethod(express, methodName)) + { + //Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported"); + SubResolve subResolve = new SubResolve(express, this.Context, parameter.OppsiteExpression); + var appendSql = subResolve.GetSql(); + if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle) || (parameter.BaseParameter != null && parameter.BaseParameter.CommonTempData?.Equals(CommonTempDataType.Result) == true)) + { + parameter.BaseParameter.CommonTempData = appendSql; + } + else + { + base.AppendValue(parameter, isLeft, appendSql); + } + return; + } + else if (IsIfElse(express, methodName)) + { + CaseWhenResolve caseResole = new CaseWhenResolve(express, this.Context, parameter.OppsiteExpression); + var appendSql = caseResole.GetSql(); + var isRoot = contextIndex == 2 && parameter.BaseExpression == null; + if (isRoot || (parameter.BaseExpression != null && ExpressionTool.IsLogicOperator(parameter.BaseExpression))) + { + appendSql = appendSql + "=1 "; + } + if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle, ResolveExpressType.Update)) + { + parameter.BaseParameter.CommonTempData = appendSql; + } + else + { + base.AppendValue(parameter, isLeft, appendSql); + } + return; + } + if (IsContainsArray(express, methodName, isValidNativeMethod)) + { + methodName = "ContainsArray"; + isValidNativeMethod = true; + } + if (isValidNativeMethod) + { + NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName], appendArgs); + } + else + { + SqlFuncMethod(parameter, express, isLeft); + } + } + + private void NativeExtensionMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft, string name, List appendArgs = null) + { + var method = express.Method; + var args = express.Arguments.Cast().ToList(); + MethodCallExpressionModel model = new MethodCallExpressionModel(); + model.Name = name; + model.Args = new List(); + switch (this.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + if (express.Object != null) + args.Insert(0, express.Object); + Where(parameter, isLeft, name, args, model, appendArgs); + break; + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + if (express.Object != null) + args.Insert(0, express.Object); + Select(parameter, isLeft, name, args, model, appendArgs); + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + if (express.Method.Name == "ToString" && express.Object != null && express.Object?.Type == UtilConstants.DateType) + { + var format = (args[0] as ConstantExpression)?.Value + ""; + if (string.IsNullOrEmpty(format) && args[0] is MemberExpression) + { + format = ExpressionTool.GetExpressionValue(args[0]) + ""; + } + var value = GetNewExpressionValue(express.Object); + var dateString2 = this.Context.DbMehtods.GetDateString(value, format); + if (IsSqlServerModel()) + { + dateString2 = string.Format("FORMAT({0},'{1}','en-US')", value, format); + } + if (dateString2 == null) + { + var dateString = GeDateFormat(format, value); + base.AppendValue(parameter, isLeft, dateString); + } + else + { + base.AppendValue(parameter, isLeft, dateString2); + } + } + else + { + var value = GetNewExpressionValue(express, this.Context.IsJoin ? ResolveExpressType.WhereMultiple : ResolveExpressType.WhereSingle); + base.AppendValue(parameter, isLeft, value); + } + break; + default: + break; + } + } + protected void SqlFuncMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft) + { + if (!CheckMethod(express)) + { + CusMethod(parameter, express, isLeft); + } + else + { + var method = express.Method; + string name = method.Name; + if (name == "Any" && ExpressionTool.IsVariable(express.Arguments[0])) + { + name = "ListAny"; + } + else if (name == "All" && ExpressionTool.IsVariable(express.Arguments[0])) + { + name = "ListAll"; + } + else if (name == "IndexOf") + { + name = "CharIndexNew"; + } + var args = express.Arguments.Cast().ToList(); + MethodCallExpressionModel model = new MethodCallExpressionModel(); + model.Args = new List(); + switch (this.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + Check.Exception(name == "GetSelfAndAutoFill", "SqlFunc.GetSelfAndAutoFill can only be used in Select."); + if (name == "CharIndexNew" && args.Count == 1) + { + args.Insert(0, express.Object); + } + Where(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + Select(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + Field(parameter, isLeft, name, args, model); + break; + default: + break; + } + } + } + + + protected void Field(ExpressionParameter parameter, bool? isLeft, string name, IEnumerable args, MethodCallExpressionModel model, List appendArgs = null) + { + if (this.Context.ResolveType == ResolveExpressType.FieldSingle) + { + this.Context.ResolveType = ResolveExpressType.WhereSingle; + } + else + { + this.Context.ResolveType = ResolveExpressType.WhereMultiple; + } + Where(parameter, isLeft, name, args, model); + } + protected void Select(ExpressionParameter parameter, bool? isLeft, string name, IEnumerable args, MethodCallExpressionModel model, List appendArgs = null) + { + if (name.IsIn("GetSelfAndAutoFill", "SelectAll")) + { + var memberValue = (args.First() as MemberExpression)?.Expression?.ToString(); + if (memberValue == null && args.First() is ParameterExpression) + { + memberValue = (args.First() as ParameterExpression).Type.GetProperties().First().Name; + } + var data = new MethodCallExpressionArgs() { MemberValue = memberValue, IsMember = true, MemberName = memberValue }; + model.Args.Add(data); + if (args.Count() == 2) + { + data.MemberName = (args.Last()).ToString().Replace("\"", ""); + data.MemberValue = "."; + } + } + else + { + foreach (var item in args) + { + if (name == "IIF" && item == args.First() && item is MemberExpression) + { + Expression trueValue = Expression.Constant(true); + var newItem = ExpressionBuilderHelper.CreateExpression(item, trueValue, ExpressionType.Equal); + var member = (item as MemberExpression); + if (member.Member.Name == "HasValue") + { + newItem = ExpressionBuilderHelper.CreateExpression(member.Expression, Expression.Constant(null), ExpressionType.NotEqual); + } + AppendItem(parameter, name, new List() { newItem }, model, newItem); + } + else + { + AppendItem(parameter, name, args, model, item); + } + } + if (appendArgs != null) + { + model.Args.AddRange(appendArgs); + } + } + if (parameter.BaseParameter.BaseParameter.BaseParameter == null) + { + this.Context.Result.Append(GetMethodValue(name, model)); + } + else + { + parameter.BaseParameter.CommonTempData = GetMethodValue(name, model); + } + } + protected void Where(ExpressionParameter parameter, bool? isLeft, string name, IEnumerable args, MethodCallExpressionModel model, List appendArgs = null) + { + foreach (var item in args) + { + var expItem = item; + if (name == "IIF" && item is UnaryExpression) + { + expItem = ExpressionTool.RemoveConvert(expItem); + } + else if (item is UnaryExpression) + { + expItem = (item as UnaryExpression).Operand; + } + else if (item is MethodCallExpression callExpression && callExpression.Method.Name == "op_Implicit") + { + expItem = callExpression.Arguments[0]; + } + AppendItem(parameter, name, args, model, expItem); + } + if (appendArgs != null) + { + model.Args.AddRange(appendArgs); + } + var methodValue = GetMethodValue(name, model); + if (parameter.BaseExpression is BinaryExpression && parameter.OppsiteExpression.Type == UtilConstants.BoolType && name == "HasValue" && !(parameter.OppsiteExpression is BinaryExpression) && !(parameter.OppsiteExpression is MethodCallExpression && parameter.OppsiteExpression.Type == UtilConstants.BoolType)) + { + methodValue = packIfElse(methodValue); + } + if (parameter.OppsiteExpression != null && name == "IsNullOrEmpty" && parameter.OppsiteExpression.Type == UtilConstants.BoolType && parameter.OppsiteExpression is ConstantExpression) + { + methodValue = packIfElse(methodValue); + } + var isRoot = contextIndex == 2; + if (isRoot && parameter.BaseExpression == null && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle) && (parameter.CurrentExpression is MethodCallExpression) && ((parameter.CurrentExpression as MethodCallExpression).Method.Name.IsIn("ToBool", "ToBoolean"))) + { + methodValue = methodValue + "=1 "; + ; + } + if (isRoot && parameter.BaseExpression == null && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle) && (parameter.CurrentExpression is ConditionalExpression) && ((parameter.CurrentExpression as ConditionalExpression).Type == UtilConstants.BoolType)) + { + var isContainsTrue = MethodValueIsTrue(methodValue); + if (isContainsTrue) + { + methodValue = methodValue + "=true "; + } + else + { + methodValue = methodValue + "=1 "; + } + } + if (isRoot && parameter.BaseExpression == null && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle) && (parameter.CurrentExpression is MethodCallExpression) && ((parameter.CurrentExpression as MethodCallExpression).Method.Name.IsIn("IIF")) && (parameter.CurrentExpression as MethodCallExpression).Method.ReturnType == UtilConstants.BoolType) + { + methodValue = methodValue + "=1 "; + } + if (parameter.BaseExpression != null && ExpressionTool.IsLogicOperator(parameter.BaseExpression) && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle) && (parameter.CurrentExpression is ConditionalExpression) && ((parameter.CurrentExpression as ConditionalExpression).Type == UtilConstants.BoolType)) + { + methodValue = methodValue + "=1 "; + } + if (parameter.BaseExpression != null && ExpressionTool.IsLogicOperator(parameter.BaseExpression) && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle) && (parameter.CurrentExpression is MethodCallExpression) && ((parameter.CurrentExpression as MethodCallExpression).Method.Name.IsIn("IIF")) && (parameter.CurrentExpression as MethodCallExpression).Method.ReturnType == UtilConstants.BoolType) + { + methodValue = methodValue + "=1 "; + } + if (parameter.BaseExpression != null && ExpressionTool.IsLogicOperator(parameter.BaseExpression) && this.Context.ResolveType.IsIn(ResolveExpressType.WhereMultiple, ResolveExpressType.WhereSingle) && (parameter.CurrentExpression is MethodCallExpression) && ((parameter.CurrentExpression as MethodCallExpression).Method.Name.IsIn("ToBool", "ToBoolean"))) + { + methodValue = methodValue + "=1 "; + } + base.AppendValue(parameter, isLeft, methodValue); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve_BaseDateFomat.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve_BaseDateFomat.cs new file mode 100644 index 000000000..4d532ac85 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve_BaseDateFomat.cs @@ -0,0 +1,284 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + /// + /// MethodCall base DateFomat + /// + public partial class MethodCallExpressionResolve : BaseResolve + { + public string GeDateFormat(string formatString, string value) + { + if (IsOracle() && formatString == "yyyy-MM-dd HH:mm:ss") + { + return $"to_char({value},'yyyy-MM-dd HH24:mi:ss') "; + } + else if (IsOracle() || IsPg()) + { + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) + { + return string.Format("FORMAT({0},'{1}','en-US')", value, formatString); + } + if (!(formatString?.Contains("24") == true)) + { + formatString = formatString.Replace("HH", "hh24"); + if (!(formatString?.Contains("24") == true)) + { + formatString = formatString.Replace("hh", "hh24"); + } + } + formatString = formatString.Replace("mm", "mi"); + //if (formatString.HasValue() && formatString.Contains("hh:mm")) + //{ + // formatString = formatString.Replace("hh:mm", "hh:mi"); + //} + //else if (formatString.HasValue() && formatString.Contains("hhmm")) + //{ + // formatString = formatString.Replace("hhmm", "hhmi"); + //} + //else if (formatString.HasValue() && formatString.Contains("HH:mm")) + //{ + // formatString = formatString.Replace("HH:mm", "HH:mi"); + //} + //else if (formatString.HasValue() && formatString.Contains("HHmm")) + //{ + // formatString = formatString.Replace("HHmm", "HHmi"); + //} + return $"to_char({value},'{formatString}') "; + } + else if (IsSqlite() && formatString == "yyyy-MM-dd") + { + return $"strftime('%Y-%m-%d', {value})"; + } + else if (IsSqlite() && formatString == "yyyy-MM-dd HH:mm:ss") + { + return $"strftime('%Y-%m-%d %H:%M:%S', {value})"; + } + else if (IsSqlite() && formatString == "yyyy-MM-dd hh:mm:ss") + { + return $"strftime('%Y-%m-%d %H:%M:%S', {value})"; + } + else if (IsSqlite() && formatString == "yyyy-MM") + { + return $"strftime('%Y-%m', {value})"; + } + else if (IsSqlite() && formatString == "yyyyMM") + { + return $"strftime('%Y%m', {value})"; + } + else if (IsSqlite() && formatString == "yyyyMMdd") + { + return $"strftime('%Y%m%d', {value})"; + } + else if (IsSqlite() && formatString.Contains('%')) + { + return $"strftime('{formatString}', {value})"; + } + else if (IsMySql() && formatString == "yyyy-MM-dd") + { + return $"DATE_FORMAT({value}, '%Y-%m-%d')"; + } + else if (IsMySql() && formatString == "yyyy-MM") + { + return $"DATE_FORMAT({value}, '%Y-%m')"; + } + else if (IsMySql() && formatString == "yyyyMM") + { + return $"DATE_FORMAT({value}, '%Y%m')"; + } + else if (IsMySql() && formatString == "yyyyMMdd") + { + return $"DATE_FORMAT({value}, '%Y%m%d')"; + } + else if (IsMySql() && formatString == "yyyy-MM-dd HH:mm:ss") + { + return $"DATE_FORMAT({value}, '%Y-%m-%d %H:%i:%S')"; + } + else if (IsMySql() && formatString == "yyyy-MM-dd hh:mm:ss") + { + return $"DATE_FORMAT({value}, '%Y-%m-%d %H:%i:%S')"; + } + else if (IsMySql() && formatString.Contains('%')) + { + return $"DATE_FORMAT({value}, '{formatString}')"; + } + else if (formatString == "yyyy-MM-dd" && IsSqlServer()) + { + return $"CONVERT(varchar(100),convert(datetime,{value}), 23)"; + } + else if (formatString == "yyyy-MM" && IsSqlServer()) + { + return $"CONVERT(varchar(7),convert(datetime,{value}), 23)"; + } + else if (formatString == "yyyy-MM-dd HH:mm:ss" && IsSqlServer()) + { + return $"CONVERT(varchar(100),convert(datetime,{value}), 120)"; + } + else if (formatString == "yyyy-MM-dd hh:mm:ss" && IsSqlServer()) + { + return $"CONVERT(varchar(100),convert(datetime,{value}), 120)"; + } + else if (formatString == "yyyy-MM-dd HH:mm" && IsSqlServer()) + { + return $"CONVERT(varchar(16),convert(datetime,{value}), 120)"; + } + else if (formatString == "yyyy-MM-dd hh:mm" && IsSqlServer()) + { + return $"CONVERT(varchar(16),convert(datetime,{value}), 120)"; + } + else if (formatString == "yyyy-MM-dd hh:mm:ss.ms" && IsSqlServer()) + { + return $"CONVERT(varchar(100),convert(datetime,{value}), 121)"; + } + else if (IsSqlServer() && formatString?.IsInt() == true) + { + return string.Format("CONVERT(varchar(100),convert(datetime,{0}), {1})", value, formatString); + } + else if (IsSqlServer()) + { + return string.Format("FORMAT({0},'{1}','en-US')", value, formatString); + } + else if (IsMySql() && !formatString.Contains('%')) + { + var newFormt = formatString + .Replace("yyyy", "%Y") + .Replace("yy", "%Y") + .Replace("MM", "%m") + .Replace("M", "%m") + .Replace("dd", "%d") + .Replace("HH", "%H") + .Replace("hh", "%h") + .Replace("mm", "%i") + .Replace("ss", "%s") + .Replace("fff", "%f"); + return $"DATE_FORMAT({value}, '{newFormt}')"; + } + else if (IsSqlite() && !formatString.Contains('%')) + { + var newFormt = formatString + .Replace("yyyy", "%Y") + .Replace("yy", "%Y") + .Replace("MM", "%m") + .Replace("M", "%m") + .Replace("dd", "%d") + .Replace("HH", "%H") + .Replace("hh", "%h") + .Replace("mm", "%M") + .Replace("ss", "%S") + .Replace("fff", "%f"); + return $"strftime('{newFormt}',{value})"; + } + var parameter = new MethodCallExpressionArgs() { IsMember = true, MemberValue = DateType.Year }; + var parameter2 = new MethodCallExpressionArgs() { IsMember = true, MemberName = value }; + var parameters = new MethodCallExpressionModel() { Args = new List() { parameter2, parameter } }; + var begin = @"^"; + var end = @"$"; + formatString = formatString.Replace("yyyy", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + formatString = formatString.Replace("yy", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + + parameters.Args.Last().MemberValue = DateType.Month; + if (IsMySql()) + { + formatString = formatString.Replace("MM", begin + UtilMethods.ConvertStringToNumbers("LPAD(" + this.GetMethodValue("DateValue", parameters).ObjToString() + ",2,0)") + end); + } + else if (IsSqlite()) + { + formatString = formatString.Replace("MM", begin + UtilMethods.ConvertStringToNumbers("SUBSTR('00' ||" + this.GetMethodValue("DateValue", parameters).ObjToString() + ", -2, 2)") + end); + } + else if (IsPg()) + { + formatString = formatString.Replace("MM", begin + UtilMethods.ConvertStringToNumbers("lpad(cast(" + this.GetMethodValue("DateValue", parameters).ObjToString() + " as varchar(20)),2,'0')") + end); + } + else if (IsOracle()) + { + formatString = formatString.Replace("MM", begin + UtilMethods.ConvertStringToNumbers("lpad(cast(" + this.GetMethodValue("DateValue", parameters).ObjToString() + " as varchar(20)),2,'0')") + end); + } + else + { + formatString = formatString.Replace("MM", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + } + formatString = formatString.Replace("M", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + + parameters.Args.Last().MemberValue = DateType.Day; + if (IsSqlServer()) + { + formatString = formatString.Replace("dd", begin + UtilMethods.ConvertStringToNumbers(string.Format("CASE WHEN LEN({0})=1 THEN '0'+ {0} else {0} end", this.GetMethodValue("DateValue", parameters))) + end); + } + formatString = formatString.Replace("dd", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + formatString = formatString.Replace("d", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + + parameters.Args.Last().MemberValue = DateType.Hour; + formatString = Regex.Replace(formatString, "hh", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end, RegexOptions.IgnoreCase); + formatString = Regex.Replace(formatString, "h", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end, RegexOptions.IgnoreCase); + + parameters.Args.Last().MemberValue = DateType.Minute; + formatString = formatString.Replace("mm", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + formatString = formatString.Replace("m", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + + parameters.Args.Last().MemberValue = DateType.Second; + formatString = formatString.Replace("ss", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + formatString = formatString.Replace("s", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + + if (!IsSqlite()) + { + parameters.Args.Last().MemberValue = DateType.Millisecond; + formatString = formatString.Replace("ms", begin + UtilMethods.ConvertStringToNumbers(this.GetMethodValue("DateValue", parameters).ObjToString()) + end); + } + + var items = Regex.Matches(formatString, @"\^\d+\$").Cast().ToList(); + foreach (var item in items) + { + formatString = formatString.Replace(item.Value, "$@" + UtilMethods.ConvertNumbersToString(item.Value.TrimStart('^').TrimEnd('$')) + "$"); + } + var strings = formatString.TrimStart('$').TrimEnd('$').Split('$'); + var joinStringParameter = new MethodCallExpressionModel() + { + Args = new List() + }; + foreach (var r in strings) + { + if (!string.IsNullOrEmpty(r) && r.Substring(0, 1) == "@") + { + joinStringParameter.Args.Add(new MethodCallExpressionArgs() + { + MemberName = r.TrimStart('@') + }); + } + else + { + + var name = base.AppendParameter(r); + joinStringParameter.Args.Add(new MethodCallExpressionArgs() + { + MemberName = name + }); + } + } + return this.GetMethodValue("MergeString", joinStringParameter).ObjToString(); + } + private bool IsSqlServer() + { + return this.Context is SqlServerExpressionContext; + } + private bool IsMySql() + { + var name = this.Context.GetType().Name; + var result = (name == "MySqlExpressionContext"); + return result; + } + private bool IsSqlite() + { + return this.Context is SqliteExpressionContext; + } + private bool IsPg() + { + return this.Context is PostgreSQLExpressionContext + || this.Context is KdbndpExpressionContext; + } + private bool IsOracle() + { + return this.Context is OracleExpressionContext + || this.Context is DmExpressionContext; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve_Helper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve_Helper.cs new file mode 100644 index 000000000..d7830c62d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve_Helper.cs @@ -0,0 +1,1207 @@ +using System.Collections; +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + /// + ///MethodCall Helper + /// + public partial class MethodCallExpressionResolve : BaseResolve + { + private void CusMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft) + { + try + { + OneToManyNavgateExpression nav = new OneToManyNavgateExpression(this.Context?.SugarContext?.Context, this); + nav.ParameterIndex = this.Context.ParameterIndex; + this.Context.ParameterIndex++; + if (nav.IsNavgate(express)) + { + var sql = nav.GetSql(); + SetNavigateResult(); + this.Context.SingleTableNameSubqueryShortName = nav.ShorName; + base.AppendValue(parameter, isLeft, sql); + return; + } + + OneToManyNavgateExpressionN nav2 = new OneToManyNavgateExpressionN(this.Context?.SugarContext?.Context, this); + if (nav2.IsNavgate(express)) + { + var sql = nav2.GetSql(); + SetNavigateResult(); + this.Context.SingleTableNameSubqueryShortName = nav2.shorName; + base.AppendValue(parameter, isLeft, sql); + return; + } + + var constValue = ExpressionTool.DynamicInvoke(express); + if (constValue is MapperSql) + { + constValue = (constValue as MapperSql).Sql; + base.AppendValue(parameter, isLeft, constValue); + return; + } + parameter.BaseParameter.CommonTempData = constValue; + var parameterName = base.AppendParameter(constValue); + if (parameter.BaseParameter.CommonTempData?.Equals(CommonTempDataType.Result) == true) + { + this.Context.Result.Append(parameterName); + } + else + { + base.AppendValue(parameter, isLeft, parameterName); + } + } + catch (Exception ex) + { + if (ex is SqlSugarException) + { + Check.Exception(true, string.Format(ex.Message, express.Method.Name)); + } + else + { + Check.Exception(true, ErrorMessage.MethodError, express.Method.Name); + } + } + } + private static bool MethodValueIsTrue(object methodValue) + { + return methodValue?.ToString().Contains("THEN true ELSE false END") == true; + } + private object packIfElse(object methodValue) + { + methodValue = this.Context.DbMehtods.CaseWhen(new List>() { + new KeyValuePair("IF",methodValue.ObjToString()), + new KeyValuePair("Return", this.Context.DbMehtods.TrueValue()), + new KeyValuePair("End", this.Context.DbMehtods.FalseValue()) + }); + return methodValue; + } + private void SetShortName(Expression exp) + { + var lamExp = (exp as LambdaExpression); + if (lamExp.Parameters?.Count == 1) + { + if (this.Context.SingleTableNameSubqueryShortName == null) + { + this.Context.SingleTableNameSubqueryShortName = lamExp.Parameters.First().Name; + } + } + } + + + private void AppendItem(ExpressionParameter parameter, string name, IEnumerable args, MethodCallExpressionModel model, Expression item) + { + if (ExpressionTool.IsUnConvertExpress(item)) + { + item = (item as UnaryExpression).Operand; + } + if (this.Context.IsSingle && args.Any(it => ExpressionTool.IsSubQuery(it)) && base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression != null) + { + var exp = base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; + if (exp is LambdaExpression) + { + SetShortName(exp); + } + else if (exp is UnaryExpression) + { + exp = base.BaseParameter?.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; + if (exp is LambdaExpression) + { + SetShortName(exp); + } + } + } + else if (this.Context.IsSingle && args.Any(it => ExpressionTool.IsIsNullSubQuery(it))) + { + var exp = base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; + if (exp is LambdaExpression) + { + SetShortName(exp); + } + else if (exp is UnaryExpression) + { + exp = base.BaseParameter?.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; + if (exp is LambdaExpression) + { + SetShortName(exp); + } + } + } + var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression; + var isConst = item is ConstantExpression; + var isIIF = name == "IIF"; + var isSubIIF = (isIIF && item.ToString().StartsWith("IIF")); + var isIFFBoolMember = isIIF && (item is MemberExpression) && (item as MemberExpression).Type == UtilConstants.BoolType; + var isIFFUnary = isIIF && (item is UnaryExpression) && (item as UnaryExpression).Operand.Type == UtilConstants.BoolType; + var isIFFBoolBinary = isIIF && (item is BinaryExpression) && (item as BinaryExpression).Type == UtilConstants.BoolType; + var isIFFBoolMethod = isIIF && (item is MethodCallExpression) && (item as MethodCallExpression).Type == UtilConstants.BoolType; + var isFirst = item == args.First(); + var isBoolValue = item.Type == UtilConstants.BoolType && item.ToString().StartsWith("value("); + var isLength = ExpressionTool.GetIsLength(item); + if (isFirst && isIIF && isConst) + { + var value = (item as ConstantExpression).Value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False(); + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = true, + MemberName = value, + MemberValue = value + }; + model.Args.Add(methodCallExpressionArgs); + } + else if (isFirst && isIIF && isIFFBoolMember && (item as MemberExpression)?.Member?.Name == "HasValue") + { + var value = base.GetNewExpressionValue(item); + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = true, + MemberName = value, + MemberValue = value + }; + model.Args.Add(methodCallExpressionArgs); + } + else if (name != null && name != "MappingColumn" && !name.StartsWith("Row") && ExpressionTool.GetMethodName(item) == "Format" && ExpressionTool.GetParameters(item).Count == 0) + { + var value = ExpressionTool.DynamicInvoke(item); + var p = AppendParameter(value); + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = true, + MemberName = p, + MemberValue = p + }; + model.Args.Add(methodCallExpressionArgs); + } + else if (isLength) + { + var value = GetNewExpressionValue(item); + + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = true, + MemberName = value, + MemberValue = value + }; + model.Args.Add(methodCallExpressionArgs); + } + else if (isIFFUnary && !isFirst) + { + AppendModelByIIFMember(parameter, model, (item as UnaryExpression).Operand); + } + else if (isIFFBoolMember && !isFirst) + { + AppendModelByIIFMember(parameter, model, item); + + } + else if (isIFFBoolBinary && !isFirst) + { + var binaryExp = item as BinaryExpression; + var binaryExpEqual = binaryExp != null && ExpressionTool.IsComparisonOperatorBool(binaryExp); + if (binaryExpEqual) + { + var expValue = GetNewExpressionValue(item); + expValue = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() + { + Name = "IIF", + Args = new List() + { + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName=expValue + }, + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= Context.DbMehtods.TrueValue() + }, + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= Context.DbMehtods.FalseValue() + } + } + }); + model.Args.Add(new MethodCallExpressionArgs() + { + IsMember = false, + MemberName = expValue, + MemberValue = expValue + }); + } + else + { + AppendModelByIIFBinary(parameter, model, item); + } + + } + else if (isIFFBoolMethod && !isFirst) + { + AppendModelByIIFMethod(parameter, model, item); + } + else if (isBinaryExpression) + { + model.Args.Add(GetMethodCallArgs(parameter, item, name)); + } + else if (isSubIIF) + { + model.Args.Add(GetMethodCallArgs(parameter, item)); + } + else if (isBoolValue && !isIIF && item is MemberExpression) + { + model.Args.Add(GetMethodCallArgs(parameter, (item as MemberExpression).Expression)); + } + else if (isBoolValue && isIIF && item is MemberExpression && ExpressionTool.GetParameters(item).Count == 0) + { + var expValue = AppendParameter(ExpressionTool.DynamicInvoke(item)); + expValue = this.Context.DbMehtods.Equals(new MethodCallExpressionModel() + { + Name = "Equals", + Args = new List() + { + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName=expValue + }, + new MethodCallExpressionArgs(){ + IsMember=true, + MemberName= Context.DbMehtods.TrueValue() + } + } + }); + model.Args.Add(new MethodCallExpressionArgs() + { + IsMember = false, + MemberName = expValue, + MemberValue = expValue + }); + } + else if (isBoolValue && isIIF && item is MemberExpression) + { + var argItem = GetMethodCallArgs(parameter, (item as MemberExpression).Expression); + if (argItem.IsMember) + { + var pName = this.Context.SqlParameterKeyWord + "true_0"; + if (!this.Context.Parameters.Any(it => it.ParameterName == pName)) + this.Context.Parameters.Add(new SugarParameter(pName, true)); + argItem.MemberName = $" {argItem.MemberName}={pName} "; + } + model.Args.Add(argItem); + } + else if (name.IsIn("ListAny", "ListAll") && item is LambdaExpression) + { + var sql = GetNewExpressionValue(item, ResolveExpressType.WhereMultiple); + var lamExp = (item as LambdaExpression); + var pExp = lamExp.Parameters[0]; + var pname = pExp.Name; + var columns = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(pExp.Type).Columns; + if (columns.Count == 0 && pExp.Type.IsValueType && pExp.Type != typeof(string)) + { + columns = new List() { new EntityColumnInfo() { UnderType = UtilMethods.GetUnderType(pExp.Type), PropertyName = pExp.Type.Name, DbTableName = pExp.Type.Name } }; + } + model.Args.Add(new MethodCallExpressionArgs() + { + MemberValue = new ListAnyParameter() + { + Sql = sql, + Name = pname, + Columns = columns, + ConvetColumnFunc = this.Context.GetTranslationColumnName + } + }); + if (lamExp.Body is MethodCallExpression callExpression) + { + var callObject = callExpression.Object; + + if (callObject is MemberExpression memberExpression && memberExpression?.Expression is ParameterExpression parameterExpression) + { + var entity = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(parameterExpression.Type); + var columnInfo = entity.Columns.FirstOrDefault(it => it.PropertyName == memberExpression.Member.Name); + model.DataObject = columnInfo; + } + } + if (this.Context.IsSingle && this.Context.SingleTableNameSubqueryShortName == null) + { + ParameterExpressionVisitor visitor = new ParameterExpressionVisitor(); + visitor.Visit(lamExp); + var tableParamter = visitor.Parameters.FirstOrDefault(it => it.Name != pname); + if (tableParamter != null) + { + this.Context.SingleTableNameSubqueryShortName = tableParamter.Name; + } + } + } + else + { + AppendModel(parameter, model, item, name, args); + } + } + + + private void AppendModelByIIFMember(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) + { + parameter.CommonTempData = CommonTempDataType.Result; + base.Expression = item; + base.Start(); + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = parameter.ChildExpression is MemberExpression, + MemberName = parameter.CommonTempData + }; + if (methodCallExpressionArgs.IsMember && parameter.ChildExpression?.ToString() == "DateTime.Now") + { + methodCallExpressionArgs.IsMember = false; + } + var value = methodCallExpressionArgs.MemberName; + if (methodCallExpressionArgs.IsMember) + { + var childExpression = parameter.ChildExpression as MemberExpression; + if (childExpression.Expression != null && childExpression.Expression is ConstantExpression) + { + methodCallExpressionArgs.IsMember = false; + } + } + if (methodCallExpressionArgs.IsMember == false) + { + var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + methodCallExpressionArgs.MemberName = parameterName; + methodCallExpressionArgs.MemberValue = value; + this.Context.Parameters.Add(new SugarParameter(parameterName, value)); + } + model.Args.Add(methodCallExpressionArgs); + parameter.ChildExpression = null; + } + private void AppendModelByIIFBinary(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) + { + Check.Exception(true, "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support ", item.ToString()); + } + private void AppendModelByIIFMethod(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) + { + var methodExpression = item as MethodCallExpression; + if (methodExpression.Method.Name.IsIn("ToBool", "ToBoolean", "IIF")) + { + model.Args.Add(base.GetMethodCallArgs(parameter, item)); + } + else if (methodExpression.Method.Name.IsIn("Contains", "EndsWith", "StartsWith")) + { + Expression conditionalExpression = ExpressionTool.GetConditionalExpression(item); + model.Args.Add(base.GetMethodCallArgs(parameter, conditionalExpression)); + } + else + { + Check.Exception(true, "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support ", item.ToString()); + } + } + + private void AppendModel(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item, string name, IEnumerable args) + { + parameter.CommonTempData = CommonTempDataType.Result; + base.Expression = item; + var isRemoveParamter = false; + var isNegate = false; + if (item.Type == UtilConstants.DateType && parameter.CommonTempData.ObjToString() == CommonTempDataType.Result.ToString() && item.ToString() == "DateTime.Now.Date") + { + parameter.CommonTempData = DateTime.Now.Date; + } + else if (item is ConditionalExpression) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else if (IsNot(item)) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else if (IsDateDate(item)) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else if (IsDateValue(item)) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else if (model.Name == "ToString" && item is ConstantExpression && (item as ConstantExpression).Type.IsEnum()) + { + parameter.CommonTempData = item.ToString(); + } + else if (IsDateItemValue(item)) + { + parameter.CommonTempData = GetNewExpressionValue(item); + } + else if (name == "Format" && item is NewArrayExpression) + { + var exps = (item as NewArrayExpression).Expressions; + parameter.CommonTempData = exps.Select(it => + { + var res = GetNewExpressionValue(ExpressionTool.RemoveConvert(it)); + return res; + }).ToArray(); + } + else if (name == "Format" && item is ConstantExpression) + { + parameter.CommonTempData = ExpressionTool.GetExpressionValue(item); + } + else if (name == "FullTextContains" && item is NewArrayExpression) + { + var array = ExpressionTool.GetNewArrayMembers(item as NewArrayExpression); + parameter.CommonTempData = array.Select(it => this.Context.GetTranslationColumnName(it)).ToList(); + isRemoveParamter = true; + } + else if (ExpressionTool.IsNegate(item) && (item as UnaryExpression)?.Operand is MemberExpression) + { + var exp = (item as UnaryExpression)?.Operand; + parameter.CommonTempData = GetNewExpressionValue(exp) + " * -1 "; + isRemoveParamter = true; + isNegate = true; + } + else + { + base.Start(); + } + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = parameter.ChildExpression is MemberExpression && !ExpressionTool.IsConstExpression(parameter.ChildExpression as MemberExpression), + MemberName = parameter.CommonTempData + }; + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) + { + if (methodCallExpressionArgs.MemberName is string) + { + methodCallExpressionArgs.MemberName = ExpressionTool.ResolveMemberValue(this.Context, item, methodCallExpressionArgs.MemberName?.ToString()); + } + } + if (methodCallExpressionArgs.MemberName is MapperSql) + { + methodCallExpressionArgs.MemberName = (methodCallExpressionArgs.MemberName as MapperSql).Sql; + } + if (methodCallExpressionArgs.IsMember && parameter.ChildExpression?.ToString() == "DateTime.Now") + { + methodCallExpressionArgs.IsMember = false; + } + var value = methodCallExpressionArgs.MemberName; + if (methodCallExpressionArgs.IsMember) + { + var childExpression = parameter.ChildExpression as MemberExpression; + if (childExpression.Expression != null && childExpression.Expression is ConstantExpression) + { + methodCallExpressionArgs.IsMember = false; + } + } + if (IsDateDate(item) || IsDateValue(item) || IsDateItemValue(item) || item is ConditionalExpression || IsNot(item)) + { + methodCallExpressionArgs.IsMember = true; + } + if (methodCallExpressionArgs.IsMember == false && (item is MethodCallExpression && item.ToString() == "GetDate()") || (item is UnaryExpression && ((UnaryExpression)item).Operand.ToString() == "GetDate()")) + { + var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + methodCallExpressionArgs.MemberName = value; + methodCallExpressionArgs.MemberValue = null; + } + else if (methodCallExpressionArgs.IsMember == false && isNegate == false) + { + var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + methodCallExpressionArgs.MemberName = parameterName; + if (name == "ToString" && UtilMethods.GetUnderType(base.Expression.Type).IsEnum()) + { + value = value?.ToString(); + } + else if (name == "ContainsArray" && args.Count() == 2 && value != null && value is IList) + { + List result = new List(); + foreach (var memItem in (value as IList)) + { + result.Add(GetMemberValue(memItem, args.Last())); + } + value = result; + } + else if (!(item is ParameterExpression) && name.IsIn("Contains", "StartsWith", "EndsWith") && item == args.Last() && ExpressionTool.IsSqlParameterDbType(this.Context, args.First())) + { + var myvalue = ExpressionTool.DynamicInvoke(args.Last()); + var parametre = ExpressionTool.GetParameterBySqlParameterDbType(this.Context.ParameterIndex, myvalue, this.Context, args.First()); + this.Context.Parameters.Add(parametre); + methodCallExpressionArgs.MemberName = parametre.ParameterName; + methodCallExpressionArgs.MemberValue = parametre.Value; + methodCallExpressionArgs.IsMember = true; + isRemoveParamter = true; + this.Context.ParameterIndex++; + } + methodCallExpressionArgs.MemberValue = value; + if (isRemoveParamter != true) + { + if (value == null && item != null) + { + this.Context.Parameters.Add(new SugarParameter(parameterName, value, UtilMethods.GetUnderType(item.Type))); + } + else + { + this.Context.Parameters.Add(new SugarParameter(parameterName, value)); + } + } + } + model.Args.Add(methodCallExpressionArgs); + parameter.ChildExpression = null; + } + + + private void GetConfigValue(MethodCallExpression express, ExpressionParameter parameter) + { + var exp = express.Arguments[0]; + var name = Regex.Match(express.Method.ToString(), @"GetConfigValue\[(.+)\]").Groups[1].Value; + string code = null; + if (express.Arguments.Count > 1) + { + code = ExpressionTool.GetExpressionValue(express.Arguments[1]) + ""; + } + var entityDb = SqlFuncExtendsion.TableInfos.FirstOrDefault(y => y.Type.Name == name && y.Code == code); + Check.Exception(entityDb == null, string.Format("GetConfigValue no configuration Entity={0} UniqueCode={1}", name, code)); + var entity = new ConfigTableInfo() + { + Code = entityDb.Code, + TableName = entityDb.TableName, + Key = entityDb.Key, + Parameter = new List(), + Type = entityDb.Type, + Value = entityDb.Value, + Where = entityDb.Where + }; + if (entityDb.Parameter != null && entityDb.Parameter.Count != 0) + { + foreach (var item in entityDb.Parameter) + { + entity.Parameter.Add(new SugarParameter("", null) + { + DbType = item.DbType, + Direction = item.Direction, + IsArray = item.IsArray, + IsJson = item.IsJson, + IsNullable = item.IsNullable, + IsRefCursor = item.IsRefCursor, + ParameterName = item.ParameterName, + Size = item.Size, + SourceColumn = item.SourceColumn, + SourceColumnNullMapping = item.SourceColumnNullMapping, + SourceVersion = item.SourceVersion, + TempDate = item.TempDate, + TypeName = item.TypeName, + Value = item.Value, + _Size = item._Size + + }); + } + } + string sql = " (SELECT {0} FROM {1} WHERE {2}={3}"; + if (ExpressionTool.IsUnConvertExpress(exp)) + { + exp = (exp as UnaryExpression).Operand; + } + var member = exp as MemberExpression; + var it = member.Expression; + var type = it.Type; + var properyName = member.Member.Name; + var eqName = string.Format("{0}.{1}", this.Context.GetTranslationColumnName(it.ToString()), this.Context.GetDbColumnName(type.Name, properyName)); + if (this.Context.IsSingle) + { + this.Context.SingleTableNameSubqueryShortName = it.ToString(); + } + sql = string.Format(sql, entity.Value, this.Context.GetTranslationColumnName(entity.TableName), entity.Key, eqName); + if (entity.Parameter != null) + { + foreach (var item in entity.Parameter) + { + var oldName = item.ParameterName; + item.ParameterName = Regex.Split(oldName, "_con_").First() + "_con_" + this.Context.ParameterIndex; + entity.Where = entity.Where.Replace(oldName, item.ParameterName); + } + this.Context.ParameterIndex++; + this.Context.Parameters.AddRange(entity.Parameter); + } + if (entity.Where.HasValue()) + { + sql += " AND " + entity.Where; + } + sql += " )"; + if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle, ResolveExpressType.Update)) + { + parameter.BaseParameter.CommonTempData = sql; + } + else + { + AppendMember(parameter, parameter.IsLeft, sql); + } + } + private object GetMethodValue(string name, MethodCallExpressionModel model) + { + model.Parameters = this.Context.Parameters; + if (IsExtMethod(name)) + { + model.Expression = this.Expression; + model.BaseExpression = this.BaseParameter.CurrentExpression; + DbType type = DbType.SqlServer; + if (this.Context is SqlServerExpressionContext) + type = DbType.SqlServer; + else if (this.Context is MySqlExpressionContext) + type = DbType.MySql; + else if (this.Context is SqliteExpressionContext) + type = DbType.Sqlite; + else if (this.Context is OracleExpressionContext) + type = DbType.Oracle; + else if (this.Context is PostgreSQLExpressionContext) + type = DbType.PostgreSQL; + else if (this.Context.GetType().Name.StartsWith("MySql")) + { + type = DbType.MySql; + } + else + { + type = GetType(this.Context.GetType().Name); + } + return this.Context.SqlFuncServices.First(it => it.UniqueMethodName == name).MethodValue(model, type, this.Context); + } + else + { + var iLike = this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.EnableILike == true; + if (name == "Parse" && TempParseType.IsIn(UtilConstants.GuidType) && model.Args?.Count > 1) + { + name = "Equals"; + } + else if (name == "Parse") + { + name = "To" + TempParseType.Name; + } + else if (name == "IsNullOrWhiteSpace") + { + name = "IsNullOrEmpty"; + } + if (model.Conext == null) + { + model.Conext = this.Context; + } + switch (name) + { + case "IIF": + return this.Context.DbMehtods.IIF(model); + case "HasNumber": + return this.Context.DbMehtods.HasNumber(model); + case "HasValue": + return this.Context.DbMehtods.HasValue(model); + case "IsNullOrEmpty": + model.Conext = this.Context; + return this.Context.DbMehtods.IsNullOrEmpty(model); + case "ToLower": + return this.Context.DbMehtods.ToLower(model); + case "ToUpper": + return this.Context.DbMehtods.ToUpper(model); + case "Trim": + return this.Context.DbMehtods.Trim(model); + case "Contains": + return GetLike(this.Context.DbMehtods.Contains(model), iLike); + case "ContainsArray": + if (model.Args[0].MemberValue == null) + { + var first = this.Context.Parameters.FirstOrDefault(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); + if (first.HasValue()) + { + model.Args[0].MemberValue = first.Value; + } + } + if (this.Context.TableEnumIsString == true) + { + List enumStringList = new List(); + foreach (var inItem in (model.Args[0].MemberValue as IEnumerable)) + { + if (inItem != null) + { + if (UtilMethods.GetUnderType(inItem.GetType()).IsEnum()) + { + enumStringList.Add(inItem.ToString()); + } + } + } + if (enumStringList.Count != 0) + { + model.Args[0].MemberValue = enumStringList; + } + } + var caResult = this.Context.DbMehtods.ContainsArray(model); + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); + return caResult; + case "ContainsArrayUseSqlParameters": + if (model.Args[0].MemberValue == null) + { + var first = this.Context.Parameters.FirstOrDefault(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); + if (first.HasValue()) + { + model.Args[0].MemberValue = first.Value; + } + } + model.Data = this.Context.SqlParameterKeyWord + "INP_" + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + if (model.Args[0].MemberValue.HasValue()) + { + var inValueIEnumerable = (IEnumerable)model.Args[0].MemberValue; + int i = 0; + foreach (var item in inValueIEnumerable) + { + this.Context.Parameters.Add(new SugarParameter(model.Data + "_" + i, item)); + i++; + } + } + var caResult2 = this.Context.DbMehtods.ContainsArrayUseSqlParameters(model); + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); + return caResult2; + case "Equals": + return this.Context.DbMehtods.Equals(model); + case "EqualsNull": + return this.Context.DbMehtods.EqualsNull(model); + case "DateIsSame": + if (model.Args.Count == 2) + return this.Context.DbMehtods.DateIsSameDay(model); + else + { + var dsResult = this.Context.DbMehtods.DateIsSameByType(model); + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[2].MemberName.ObjToString()); + return dsResult; + } + case "DateAdd": + model.Conext = this.Context; + if (model.Args.Count == 2) + return this.Context.DbMehtods.DateAddDay(model); + else + { + var daResult = this.Context.DbMehtods.DateAddByType(model); + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[2].MemberName.ObjToString()); + return daResult; + } + case "DateValue": + var dvResult = this.Context.DbMehtods.DateValue(model); + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[1].MemberName.ObjToString()); + return dvResult; + case "Between": + return this.Context.DbMehtods.Between(model); + case "StartsWith": + return GetLike(this.Context.DbMehtods.StartsWith(model), iLike); + case "EndsWith": + return GetLike(this.Context.DbMehtods.EndsWith(model), iLike); + case "ToInt32": + return this.Context.DbMehtods.ToInt32(model); + case "ToInt64": + return this.Context.DbMehtods.ToInt64(model); + case "ToDate": + return this.Context.DbMehtods.ToDate(model); + case "ToDateTime": + return this.Context.DbMehtods.ToDate(model); + case "ToTime": + return this.Context.DbMehtods.ToTime(model); + case "ToString": + if (model.Args.Count > 1) + { + var dateString2 = this.Context.DbMehtods.GetDateString(model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString()); + if (IsSqlServerModel()) + { + return string.Format("FORMAT({0},'{1}','en-US')", model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString()); + } + if (dateString2 != null) return dateString2; + return GeDateFormat(model.Args.Last().MemberValue.ObjToString(), model.Args.First().MemberName.ObjToString()); + } + //Check.Exception(model.Args.Count > 1, "ToString (Format) is not supported, Use ToString().If time formatting can be used it.Date.Year+\"-\"+it.Data.Month+\"-\"+it.Date.Day "); + return this.Context.DbMehtods.ToString(model); + case "ToVarchar": + return this.Context.DbMehtods.ToVarchar(model); + case "ToDecimal": + return this.Context.DbMehtods.ToDecimal(model); + case "ToGuid": + return this.Context.DbMehtods.ToGuid(model); + case "ToDouble": + return this.Context.DbMehtods.ToDouble(model); + case "ToBool": + return this.Context.DbMehtods.ToBool(model); + case "ToBoolean": + return this.Context.DbMehtods.ToBool(model); + case "Substring": + if (model.Args.Count == 2) + { + model.Args.Add(new MethodCallExpressionArgs() + { + MemberName = "100000", + IsMember = true, + MemberValue = "100000", + }); + } + model.Conext = this.Context; + return this.Context.DbMehtods.Substring(model); + case "Replace": + return this.Context.DbMehtods.Replace(model); + case "Length": + return this.Context.DbMehtods.Length(model); + case "AggregateSum": + return this.Context.DbMehtods.AggregateSum(model); + case "AggregateAvg": + return this.Context.DbMehtods.AggregateAvg(model); + case "AggregateMin": + return this.Context.DbMehtods.AggregateMin(model); + case "AggregateMax": + return this.Context.DbMehtods.AggregateMax(model); + case "AggregateCount": + return this.Context.DbMehtods.AggregateCount(model); + case "AggregateDistinctCount": + return this.Context.DbMehtods.AggregateDistinctCount(model); + case "MappingColumn": + var mappingColumnResult = this.Context.DbMehtods.MappingColumn(model); + if (model.Args.Count == 1 && mappingColumnResult.IsNullOrEmpty()) + { + return model.Args[0].MemberName.ObjToString().TrimStart('\'').TrimEnd('\''); + } + var isValid = model.Args[0].IsMember && model.Args[1].IsMember == false; + //Check.Exception(!isValid, "SqlFunc.MappingColumn parameters error, The property name on the left, string value on the right"); + if (model.Args.Count > 1) + { + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[1].MemberName.ObjToString()); + } + else + { + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); + } + if (string.IsNullOrEmpty(mappingColumnResult)) + { + return model.Args[1].MemberName.ObjToString().TrimStart('\'').TrimEnd('\''); + } + return mappingColumnResult; + case "IsNull": + return this.Context.DbMehtods.IsNull(model); + case "MergeString": + return this.Context.DbMehtods.MergeString(model.Args.Select(it => it.MemberName.ObjToString()).ToArray()); + case "SelectAll": + case "GetSelfAndAutoFill": + this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); + var result1 = this.Context.DbMehtods.GetSelfAndAutoFill(this.Context.GetTranslationColumnName(model.Args[0].MemberValue.ObjToString()), this.Context.IsSingle); + if ((model.Args[0].MemberValue + "") == "." && this.Context.IsSingle) + { + result1 = this.Context.GetTranslationTableName(model.Args[0].MemberName + "", false) + ".*/**/" + result1; + } + return result1; + case "GetDate": + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) + { + return "GetDate()"; + } + return this.Context.DbMehtods.GetDate(); + case "GetRandom": + return this.Context.DbMehtods.GetRandom(); + case "CharIndex": + return this.Context.DbMehtods.CharIndex(model); + case "BitwiseAnd": + return this.Context.DbMehtods.BitwiseAnd(model); + case "BitwiseInclusiveOR": + return this.Context.DbMehtods.BitwiseInclusiveOR(model); + case "ToDateShort": + return this.Context.DbMehtods.ToDateShort(model); + case "Oracle_ToChar": + return this.Context.DbMehtods.Oracle_ToChar(model); + case "Oracle_ToDate": + return this.Context.DbMehtods.Oracle_ToDate(model); + case "SqlServer_DateDiff": + return this.Context.DbMehtods.SqlServer_DateDiff(model); + case "Format": + var xx = base.BaseParameter; + var result = this.Context.DbMehtods.Format(model); + if (this.Context.MethodName == "MappingColumn" || this.Context.MethodName?.StartsWith("Row") == true) + { + result = this.Context.DbMehtods.FormatRowNumber(model); + } + this.Context.Parameters.RemoveAll(it => model.Args.Select(x => x.MemberName.ObjToString()).Contains(it.ParameterName)); + return result; + case "Abs": + return this.Context.DbMehtods.Abs(model); + case "Round": + return this.Context.DbMehtods.Round(model); + case "DateDiff": + return this.Context.DbMehtods.DateDiff(model); + case "GreaterThan": + return this.Context.DbMehtods.GreaterThan(model); + case "GreaterThanOrEqual": + return this.Context.DbMehtods.GreaterThanOrEqual(model); + case "LessThan": + return this.Context.DbMehtods.LessThan(model); + case "LessThanOrEqual": + return this.Context.DbMehtods.LessThanOrEqual(model); + case "Asc": + return this.Context.DbMehtods.Asc(model); + case "Desc": + return this.Context.DbMehtods.Desc(model); + case "Stuff": + return this.Context.DbMehtods.Stuff(model); + case "RowNumber": + return this.Context.DbMehtods.RowNumber(model); + case "Rank": + return this.Context.DbMehtods.RowNumber(model).Replace("row_number() over(", " rank() over("); + case "DenseRank": + return this.Context.DbMehtods.RowNumber(model).Replace("row_number() over(", " dense_rank() over("); + case "RowCount": + return this.Context.DbMehtods.RowCount(model); + case "RowSum": + return this.Context.DbMehtods.RowSum(model); + case "RowMax": + return this.Context.DbMehtods.RowMax(model); + case "RowMin": + return this.Context.DbMehtods.RowMin(model); + case "RowAvg": + return this.Context.DbMehtods.RowAvg(model); + case "Exists": + if (model.Args.Count > 1) + { + this.Context.Parameters.RemoveAll(it => model.Args[1].MemberName.ObjToString().Contains(it.ParameterName)); + List conditionalModels = (List)model.Args[1].MemberValue; + var sqlObj = this.Context.SugarContext.Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels, 0); + var sql = sqlObj.Key; + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value, 0, "_" + this.Context.ParameterIndex + "_B"); + model.Args[1].MemberName = sql; + if (sqlObj.Value != null) + { + this.Context.Parameters.AddRange(sqlObj.Value); + } + else + { + return " 1=1 "; + } + } + return this.Context.DbMehtods.Exists(model); + + case "JsonField": + return this.Context.DbMehtods.JsonField(model); + case "JsonArrayLength": + return this.Context.DbMehtods.JsonArrayLength(model); + case "JsonContainsFieldName": + return this.Context.DbMehtods.JsonContainsFieldName(model); + case "JsonParse": + return this.Context.DbMehtods.JsonParse(model); + case "JsonLike": + return this.Context.DbMehtods.JsonLike(model); + case "Collate": + return this.Context.DbMehtods.Collate(model); + case "AggregateSumNoNull": + return this.Context.DbMehtods.AggregateSumNoNull(model); + case "JsonListObjectAny": + return this.Context.DbMehtods.JsonListObjectAny(model); + case "JsonArrayAny": + return this.Context.DbMehtods.JsonArrayAny(model); + case "CompareTo": + return this.Context.DbMehtods.CompareTo(model); + case "SplitIn": + return this.Context.DbMehtods.SplitIn(model); + case "ListAny": + this.Context.Result.IsNavicate = true; + this.Context.Parameters.RemoveAll(it => model.Args[0].MemberName.ObjToString().Contains(it.ParameterName)); + return this.Context.DbMehtods.ListAny(model); + case "ListAll": + this.Context.Result.IsNavicate = true; + this.Context.Parameters.RemoveAll(it => model.Args[0].MemberName.ObjToString().Contains(it.ParameterName)); + return this.Context.DbMehtods.ListAll(model); + case "Modulo": + return this.Context.DbMehtods.Modulo(model); + case "Like": + return GetLike(this.Context.DbMehtods.Like(model), iLike); + case "ToSingle": + return this.Context.DbMehtods.ToSingle(model); + case "GreaterThan_LinqDynamicCore": + return this.Context.DbMehtods.GreaterThan(model); + case "LessThan_LinqDynamicCore": + return this.Context.DbMehtods.LessThan(model); + default: + if (typeof(IDbMethods).GetMethods().Any(it => it.Name == name)) + { + return this.Context.DbMehtods.GetType().GetMethod(name).Invoke(this.Context.DbMehtods, new object[] { model }); + } + break; + } + } + return null; + } + + private bool IsSqlServerModel() + { + return this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; + } + + private string GetLike(string result, bool iLike) + { + if (iLike) + { + result = result.Replace(" like ", " ilike "); + } + return result; + } + + private DbType GetType(string name) + { + DbType result = DbType.SqlServer; + foreach (var item in UtilMethods.EnumToDictionary()) + { + if (name.StartsWith(item.Value.ToString())) + { + result = item.Value; + break; + } + } + return result; + } + + private bool IsContainsArray(MethodCallExpression express, string methodName, bool isValidNativeMethod) + { + if (isMemoryExtensionsContainsArray(express, methodName)) + { + return true; + } + return !isValidNativeMethod && express.Method.DeclaringType.Namespace.IsIn("System.Collections", "System.Linq", "System.Collections.Generic") && methodName == "Contains"; + } + private bool isMemoryExtensionsContainsArray(MethodCallExpression express, string methodName) + { + var isMemoryExtensionsContainsArray = false; + if (express.Method.DeclaringType.Name == "MemoryExtensions" && methodName == "Contains") + { + if (express.Arguments.Count == 2) + { + if (express.Arguments.First() is MethodCallExpression callExpression) + { + if (callExpression.Method.Name == "op_Implicit") + { + isMemoryExtensionsContainsArray = true; + } + } + } + } + + return isMemoryExtensionsContainsArray; + } + + private bool IsSubMethod(MethodCallExpression express, string methodName) + { + return SubTools.SubItemsConst.Any(it => it.Name == methodName) && (express.Object?.Type.Name.StartsWith("Subqueryable`") == true); + } + private bool CheckMethod(MethodCallExpression expression) + { + if (expression?.Object?.Type?.Name?.StartsWith("ISugarQueryable`") == true) + { + Check.ExceptionEasy("Sublookup is implemented using SqlFunc.Subquery(); Queryable objects cannot be used", "子查请使用SqlFunc.Subquery()来实现,不能用Queryable对象"); + } + if (expression.Method.Name == "SelectAll") + { + return true; + } + if (expression.Method.Name == "IndexOf") + { + return true; + } + if (expression.Method.Name == "CompareTo") + { + return true; + } + if (expression.Method.Name == "Any" && expression.Arguments.Count > 0 && ExpressionTool.IsVariable(expression.Arguments[0])) + { + return true; + } + if (expression.Method.Name == "All" && expression.Arguments.Count > 0 && ExpressionTool.IsVariable(expression.Arguments[0])) + { + return true; + } + if (expression.Method.Name == "Format" && expression.Method.DeclaringType == UtilConstants.StringType) + { + return true; + } + if (IsExtMethod(expression.Method.Name)) + return true; + if (IsParseMethod(expression)) + return true; + if (expression.Method.Name == "IsNullOrEmpty" && expression.Method.DeclaringType == UtilConstants.StringType) + { + return true; + } + if (expression.Method.Name == "IsNullOrWhiteSpace" && expression.Method.DeclaringType == UtilConstants.StringType) + { + return true; + } + if (expression.Method.ReflectedType().FullName != ExpressionConst.SqlFuncFullName) + return false; + else + return true; + } + private Type TempParseType; + public bool IsParseMethod(MethodCallExpression expression) + { + if (expression.Method.Name == "Parse" && expression.Method.DeclaringType.IsIn( + UtilConstants.DecType, + UtilConstants.DateType, + UtilConstants.DobType, + UtilConstants.GuidType, + UtilConstants.FloatType, + UtilConstants.ShortType, + UtilConstants.LongType, + UtilConstants.IntType, + UtilConstants.BoolType)) + { + TempParseType = expression.Method.DeclaringType; + return true; + } + return false; + } + private static bool IsNot(Expression item) + { + return item is UnaryExpression && (item as UnaryExpression).NodeType == ExpressionType.Not; + } + private bool IsDateItemValue(Expression item) + { + var result = false; + if (item is MemberExpression) + { + var memberExp = item as MemberExpression; + if (memberExp?.Expression != null && memberExp.Expression.Type == UtilConstants.DateType) + { + foreach (var dateType in UtilMethods.EnumToDictionary()) + { + if (memberExp.Member.Name.EqualCase(dateType.Key)) + { + result = true; + break; + } + else if (memberExp.Member.Name == "DayOfWeek") + { + result = true; + break; + } + } + } + } + + return result; + } + private static bool IsDateDate(Expression item) + { + return item.Type == UtilConstants.DateType && item is MemberExpression && (item as MemberExpression).Member.Name == "Date" && item.ToString() != "DateTime.Now.Date"; + } + private static bool IsDateValue(Expression item) + { + return item.Type == UtilConstants.IntType && + item is MemberExpression && + (item as MemberExpression).Expression != null && + (item as MemberExpression).Expression.Type == UtilConstants.DateType && + (item as MemberExpression).Expression is MemberExpression && + ((item as MemberExpression).Expression as MemberExpression).Member.Name == "Value"; + } + private bool IsValidNativeMethod(MethodCallExpression express, string methodName) + { + return MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System"); + } + private bool IsExtMethod(string methodName) + { + if (this.Context.SqlFuncServices == null) return false; + return this.Context.SqlFuncServices.Select(it => it.UniqueMethodName).Contains(methodName); + } + private bool IsIfElse(MethodCallExpression express, string methodName) + { + if (methodName == "End" && express.Object.Type == typeof(CaseWhen)) + return true; + else + return false; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs new file mode 100644 index 000000000..fb92e2903 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs @@ -0,0 +1,112 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class NewArrayExpessionResolve : BaseResolve + { + public NewArrayExpessionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = (NewArrayExpression)base.Expression; + switch (base.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + #region Filed + try + { + var value = ExpressionTool.DynamicInvoke(expression); + var isLeft = parameter.IsLeft; + var baseParameter = parameter.BaseParameter; + var isSetTempData = baseParameter.CommonTempData.HasValue() && baseParameter.CommonTempData.Equals(CommonTempDataType.Result); + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + var parentIsBinary = parameter.BaseParameter.CurrentExpression is BinaryExpression; + var parentIsRoot = parameter.BaseParameter.CurrentExpression is LambdaExpression; + var isBool = value != null && value.GetType() == UtilConstants.BoolType; + if (parentIsRoot && isBool) + { + this.Context.Result.Append(value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False()); + break; + } + if (parentIsBinary && isBool) + { + var isLogicOperator = + parameter.BaseExpression.NodeType == ExpressionType.And || + parameter.BaseExpression.NodeType == ExpressionType.AndAlso || + parameter.BaseExpression.NodeType == ExpressionType.Or || + parameter.BaseExpression.NodeType == ExpressionType.OrElse; + if (isLogicOperator) + { + AppendMember(parameter, isLeft, (value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False())); + break; + } + } + if (value == null && parentIsBinary) + { + parameter.BaseParameter.ValueIsNull = true; + value = this.Context.DbMehtods.Null(); + } + AppendValue(parameter, isLeft, value); + } + } + catch (Exception) + { + Check.ThrowNotSupportedException("NewArrayExpression"); + } + #endregion + break; + case ResolveExpressType.ArraySingle: + ArraySingle(expression); + break; + case ResolveExpressType.Join: + Join(parameter, expression); + break; + default: + break; + } + } + + private void Join(ExpressionParameter parameter, NewArrayExpression expression) + { + base.Context.ResolveType = ResolveExpressType.WhereMultiple; + int i = 0; + foreach (var item in expression.Expressions) + { + if (item is UnaryExpression) + { + base.Expression = item; + base.Start(); + if (parameter.CommonTempData is JoinType) + { + if (i > 0) + { + base.Context.Result.Append("," + parameter.CommonTempData.ObjToString().Replace(",", UtilConstants.ReplaceCommaKey) + ","); + } + else + { + base.Context.Result.Append(parameter.CommonTempData.ObjToString().Replace(",", UtilConstants.ReplaceCommaKey) + ","); + } + ++i; + } + } + } + } + + private void ArraySingle(NewArrayExpression expression) + { + foreach (var item in expression.Expressions) + { + base.Expression = item; + base.Start(); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/NewExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/NewExpressionResolve.cs new file mode 100644 index 000000000..4b2c3a2bd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/NewExpressionResolve.cs @@ -0,0 +1,174 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class NewExpressionResolve : BaseResolve + { + public NewExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var expression = base.Expression as NewExpression; + if (expression.Type.IsIn(UtilConstants.DateType, UtilConstants.GuidType)) + { + NewValueType(parameter, expression); + return; + } + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + Check.ThrowNotSupportedException(expression.ToString()); + break; + case ResolveExpressType.WhereMultiple: + Check.ThrowNotSupportedException(expression.ToString()); + break; + case ResolveExpressType.SelectSingle: + Check.Exception(expression.Type == UtilConstants.DateType, "ThrowNotSupportedException {0} ", expression.ToString()); + Select(expression, parameter, true); + break; + case ResolveExpressType.SelectMultiple: + Check.Exception(expression.Type == UtilConstants.DateType, "ThrowNotSupportedException {0} ", expression.ToString()); + Select(expression, parameter, false); + break; + case ResolveExpressType.FieldSingle: + Check.ThrowNotSupportedException(expression.ToString()); + break; + case ResolveExpressType.FieldMultiple: + case ResolveExpressType.ArrayMultiple: + case ResolveExpressType.ArraySingle: + ArraySingle(expression); + break; + case ResolveExpressType.Join: + Join(expression); + break; + default: + break; + } + } + + private void Join(NewExpression expression) + { + base.Context.ResolveType = ResolveExpressType.WhereMultiple; + int i = 0; + foreach (var item in expression.Arguments) + { + if (item.Type != typeof(JoinType)) + { + base.Expression = item; + base.Start(); + } + if (item.Type == typeof(JoinType)) + { + var joinValue = item.ObjToString(); + if (joinValue.Contains('(')) + { + joinValue = ExpressionTool.DynamicInvoke(item).ObjToString(); + } + if (i > 0) + { + base.Context.Result.Append("," + joinValue + ","); + } + else + { + base.Context.Result.Append(joinValue + ","); + } + ++i; + } + } + } + + private void ArraySingle(NewExpression expression) + { + foreach (var item in expression.Arguments) + { + if (IsDateValue(item)) + { + var value = GetNewExpressionValue(item); + base.Context.Result.Append(value); + } + else + { + base.Expression = item; + base.Start(); + } + } + } + + private bool IsDateValue(Expression item) + { + var isMember = item is MemberExpression; + if (isMember) + { + var m = (item as MemberExpression); + var isInt = m.Type == UtilConstants.IntType; + if (m.Expression != null && isInt && m.Expression is MemberExpression) + { + var mm = (m.Expression as MemberExpression); + if (m.Member.Name.IsIn("Year", "Day", "Month") && mm.Type == UtilConstants.DateType) + { + return true; + } + } + } + return false; + } + + private void NewValueType(ExpressionParameter parameter, NewExpression expression) + { + try + { + var value = ExpressionTool.DynamicInvoke(expression); + var isSetTempData = parameter.CommonTempData.HasValue() && parameter.CommonTempData.Equals(CommonTempDataType.Result); + if (isSetTempData) + { + parameter.CommonTempData = value; + } + else + { + AppendValue(parameter, parameter.IsLeft, value); + } + } + catch (Exception ex) + { + Check.Exception(expression.Type == UtilConstants.DateType, "ThrowNotSupportedException {0} ", ex.ToString()); + } + } + + private void Select(NewExpression expression, ExpressionParameter parameter, bool isSingle) + { + if (expression.Arguments != null) + { + int i = 0; + foreach (var item in expression.Arguments) + { + + string memberName = expression.Members?[i]?.Name; + if (memberName == null && expression.Members == null && item is MemberExpression member) + { + memberName = member.Member.Name; + this.Context.SugarContext.QueryBuilder.IsParameterizedConstructor = true; + } + if (this.Context?.SugarContext?.QueryBuilder?.AppendNavInfo?.MappingNavProperties?.ContainsKey(memberName) == true) + { + ++i; + continue; + } + ++i; + if (item is ParameterExpression) + { + var itemType = item.Type; + var ignoreProperty = itemType.GetProperties().FirstOrDefault(it => it.PropertyType == itemType); + if (ignoreProperty != null && ignoreProperty.Name != memberName) + { + if (this.Context.SugarContext.QueryBuilder.SelectNewIgnoreColumns == null) + { + this.Context.SugarContext.QueryBuilder.SelectNewIgnoreColumns = new List>(); + } + this.Context.SugarContext.QueryBuilder.SelectNewIgnoreColumns.Add(new KeyValuePair(ignoreProperty.Name, itemType.Name)); + } + } + ResolveNewExpressions(parameter, item, memberName); + } + } + } + } +} + diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToManyNavgateExpression.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToManyNavgateExpression.cs new file mode 100644 index 000000000..cb01caa25 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToManyNavgateExpression.cs @@ -0,0 +1,337 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class OneToManyNavgateExpression + { + private SqlSugarProvider context; + private EntityInfo EntityInfo; + private EntityInfo ProPertyEntity; + private Navigate Navigat; + public string ShorName; + public string PropertyShortName; + private string MemberName; + private string MethodName; + private string whereSql; + public int ParameterIndex = 0; + private MethodCallExpressionResolve methodCallExpressionResolve; + public OneToManyNavgateExpression(SqlSugarProvider context, MethodCallExpressionResolve methodCallExpressionResolve) + { + this.context = context; + this.methodCallExpressionResolve = methodCallExpressionResolve; + } + + internal bool IsNavgate(Expression expression) + { + var result = false; + var exp = expression; + if (exp is UnaryExpression) + { + exp = (exp as UnaryExpression).Operand; + } + if (exp is MethodCallExpression) + { + var memberExp = exp as MethodCallExpression; + MethodName = memberExp.Method.Name; + if (memberExp.Method.Name.IsIn("Any", "Count") && memberExp.Arguments.Count > 0 && memberExp.Arguments[0] is MemberExpression) + { + result = ValidateNav(result, memberExp.Arguments[0] as MemberExpression, memberExp.Arguments[0]); + if (memberExp.Arguments.Count > 1) + { + var pars = ExpressionTool.ExpressionParameters(memberExp.Arguments.Last()); + if (pars != null && ProPertyEntity != null && pars.Any(z => z.Type == ProPertyEntity.Type)) + { + PropertyShortName = pars.First(z => z.Type == ProPertyEntity.Type).Name; + } + whereSql = GetWhereSql(memberExp); + } + } + } + return result; + } + + private string GetWhereSql(MethodCallExpression memberExp) + { + var whereExp = memberExp.Arguments[1]; + if (PropertyShortName.HasValue() && Navigat != null && Navigat.NavigatType == NavigateType.OneToMany) + { + InitType(whereExp); + var result = this.methodCallExpressionResolve.GetNewExpressionValue(whereExp, ResolveExpressType.WhereMultiple); + return result; + } + else if (whereExp != null && whereExp.Type == typeof(List)) + { + var value = ExpressionTool.GetExpressionValue(whereExp) as List; + //this.context.Utilities.Context.Queryable().Where(value).ToList(); + if (value.HasValue()) + { + var sqlbuilder = this.context.Queryable().SqlBuilder; + var sqlObj = sqlbuilder.ConditionalModelToSql(value, 0); + var sql = sqlObj.Key; + var count = methodCallExpressionResolve?.Context?.SugarContext?.QueryBuilder?.Parameters?.Count ?? 0; + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value, 0, "_" + count + "_"); + methodCallExpressionResolve.Context.Parameters.AddRange(sqlObj.Value); + return sql; + } + else + { + return " 1=1 "; + } + } + else + { + InitType(whereExp); + var result = this.methodCallExpressionResolve.GetNewExpressionValue(whereExp); + return result; + } + } + + private void InitType(Expression whereExp) + { + if (whereExp is LambdaExpression) + { + var parameters = (whereExp as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + foreach (var item in parameters) + { + this.context.InitMappingInfo(item.Type); + } + } + } + } + + private bool ValidateNav(bool result, MemberExpression memberExp, Expression childExpression) + { + if (childExpression != null && childExpression is MemberExpression) + { + var child2Expression = (childExpression as MemberExpression).Expression; + if (child2Expression.Type.IsClass() && child2Expression is ParameterExpression) + { + var rootType = child2Expression.Type; + var rootEntity = this.context.EntityMaintenance.GetEntityInfo(rootType); + var type = childExpression.Type.GetGenericArguments()[0]; + var entity = this.context.EntityMaintenance.GetEntityInfo(type); + if (rootEntity.Columns.Any(x => x.PropertyName == (childExpression as MemberExpression).Member.Name && x.Navigat != null)) + { + EntityInfo = rootEntity; + ShorName = child2Expression.ToString(); + MemberName = memberExp.Member.Name; + ProPertyEntity = entity; + Navigat = rootEntity.Columns.FirstOrDefault(x => x.PropertyName == (childExpression as MemberExpression).Member.Name).Navigat; + result = true; + } + } + } + + return result; + } + internal MapperSql GetSql() + { + if (Navigat.NavigatType == NavigateType.OneToMany) + { + return GetOneToManySql(); + } + else if (Navigat.NavigatType == NavigateType.Dynamic) + { + return GetDynamicSql(); + } + else + { + return GetManyToManySql(); + } + + } + + private MapperSql GetDynamicSql() + { + if (Navigat.Name == null) + { + Check.ExceptionEasy( + true, + " NavigateType.Dynamic User-defined navigation objects need to be configured with json to be used in expressions . " + this.ProPertyEntity.Type.Name, + " NavigateType.Dynamic 自定义导航对象需要配置json才能在表达式中使用。 " + this.ProPertyEntity.Type.Name); + } + MapperSql mapper = new MapperSql(); + var queryable = this.context.Queryable(); + //selectName = queryable.QueryBuilder.Builder.GetTranslationColumnName(selectName); + if (PropertyShortName.HasValue()) + { + queryable.QueryBuilder.TableShortName = PropertyShortName; + } + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500; + var isClearFilter = false; + Type[] clearTypes = null; + if (this.methodCallExpressionResolve?.Context?.SugarContext?.QueryBuilder != null) + { + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500 + this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex; + this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex++; + isClearFilter = this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.IsDisabledGobalFilter; + clearTypes = this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.RemoveFilters; + } + queryable + .AS(this.ProPertyEntity.DbTableName) + .ClearFilter(clearTypes) + .Filter(isClearFilter ? null : this.ProPertyEntity.Type) + .WhereIF(!string.IsNullOrEmpty(whereSql), whereSql); + var json = Newtonsoft.Json.Linq.JArray.Parse(Navigat.Name); + foreach (var item in json) + { + string m = item["m"] + ""; + string c = item["c"] + ""; + var leftName = this.EntityInfo.Columns.First(it => it.PropertyName == m).DbColumnName; + var rightName = this.ProPertyEntity.Columns.First(it => it.PropertyName == c).DbColumnName; + queryable.Where($" {queryable.SqlBuilder.GetTranslationColumnName(ShorName)}.{queryable.SqlBuilder.GetTranslationColumnName(leftName)}={queryable.SqlBuilder.GetTranslationColumnName(rightName)} "); + } + var sqlObj = queryable.ToSql(); + // .Where($" {name}={queryable.QueryBuilder.Builder.GetTranslationColumnName(ShorName)}.{pk} ").Select(MethodName == "Any" ? "1" : " COUNT(1) ").ToSql(); + if (sqlObj.Value?.Count > 0) + { + foreach (var item in sqlObj.Value) + { + if (!this.methodCallExpressionResolve.Context.Parameters.Any(it => it.ParameterName == item.ParameterName)) + { + this.methodCallExpressionResolve.Context.Parameters.Add(item); + } + } + } + mapper.Sql = sqlObj.Key; + mapper.Sql = $" ({mapper.Sql}) "; + mapper.Sql = GetMethodSql(mapper.Sql); + return mapper; + } + + private MapperSql GetManyToManySql() + { + + var bPk = this.ProPertyEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true)?.DbColumnName; + var aPk = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey == true)?.DbColumnName; + if (Navigat.BClassId.HasValue()) + { + bPk = this.ProPertyEntity.Columns.FirstOrDefault(it => it.PropertyName == Navigat.BClassId)?.DbColumnName; + } + if (Navigat.AClassId.HasValue()) + { + aPk = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == Navigat.AClassId)?.DbColumnName; + } + Check.ExceptionEasy(aPk.IsNullOrEmpty(), $"{this.EntityInfo.EntityName}need primary key", $"{this.EntityInfo.EntityName}需要主键"); + Check.ExceptionEasy(bPk.IsNullOrEmpty(), $"{this.ProPertyEntity.EntityName}need primary key", $"{this.ProPertyEntity.EntityName}需要主键"); + MapperSql mapper = new MapperSql(); + var queryable = this.context.Queryable(); + bPk = queryable.QueryBuilder.Builder.GetTranslationColumnName(bPk); + aPk = queryable.QueryBuilder.Builder.GetTranslationColumnName(aPk); + var mappingType = Navigat.MappingType; + Check.ExceptionEasy(mappingType == null, "ManyToMany misconfiguration", "多对多配置错误"); + var mappingEntity = this.context.EntityMaintenance.GetEntityInfo(mappingType); + var mappingTableName = queryable.QueryBuilder.Builder.GetTranslationTableName(mappingEntity.DbTableName); + var mappingA = mappingEntity.Columns.First(it => it.PropertyName == Navigat.MappingAId).DbColumnName; + var mappingB = mappingEntity.Columns.First(it => it.PropertyName == Navigat.MappingBId).DbColumnName; + mappingA = queryable.QueryBuilder.Builder.GetTranslationColumnName(mappingA); + mappingB = queryable.QueryBuilder.Builder.GetTranslationColumnName(mappingB); + var bTableName = queryable.QueryBuilder.Builder.GetTranslationTableName(this.ProPertyEntity.DbTableName); + this.context.InitMappingInfo(mappingType); + var queryBuilerAB = this.context.Queryable().QueryBuilder; + queryBuilerAB.LambdaExpressions.ParameterIndex = 100 + this.ParameterIndex; + var filters = queryBuilerAB.GetFilters(mappingType); + if (filters.HasValue() && this.methodCallExpressionResolve?.Context?.SugarContext?.QueryBuilder?.IsDisabledGobalFilter != true) + { + aPk += " AND " + filters; + if (queryBuilerAB.Parameters != null) + { + this.methodCallExpressionResolve.Context.Parameters.AddRange(queryBuilerAB.Parameters); + } + } + + mapper.Sql = $" (select {(MethodName == "Any" ? "1" : " COUNT(1) ")} from {bTableName} {this.ProPertyEntity.DbTableName}_1 where {this.ProPertyEntity.DbTableName}_1.{bPk} in (select {mappingB} from {mappingTableName} where {mappingA} = {ShorName}.{aPk} ) )"; + if (this.whereSql.HasValue()) + { + mapper.Sql = mapper.Sql.TrimEnd(')'); + if (this.whereSql.Contains($" {PropertyShortName}.")) + { + this.whereSql = this.whereSql.Replace($" {PropertyShortName}.", $" {this.ProPertyEntity.DbTableName}_1."); + } + else if (this.whereSql.Contains($" {queryable.QueryBuilder.Builder.GetTranslationColumnName(PropertyShortName)}.")) + { + this.whereSql = this.whereSql.Replace($" {queryable.QueryBuilder.Builder.GetTranslationColumnName(PropertyShortName)}.", $" {this.ProPertyEntity.DbTableName}_1."); + } + else if (this.whereSql.Contains($"({queryable.QueryBuilder.Builder.GetTranslationColumnName(PropertyShortName)}.")) + { + this.whereSql = this.whereSql.Replace($"({queryable.QueryBuilder.Builder.GetTranslationColumnName(PropertyShortName)}.", $"({this.ProPertyEntity.DbTableName}_1."); + } + mapper.Sql = mapper.Sql + " AND " + this.whereSql + ")"; + } + if (MethodName == "Any") + { + mapper.Sql = $" {mapper.Sql} "; + } + else + { + mapper.Sql = $" ({mapper.Sql}) "; + } + mapper.Sql = GetMethodSql(mapper.Sql); + return mapper; + } + private MapperSql GetOneToManySql() + { + var pkColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey == true); + if (Navigat.Name2.HasValue()) + { + pkColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == Navigat.Name2); + } + Check.ExceptionEasy(pkColumn == null, $"{this.EntityInfo.EntityName} need primary key ", + $"导航属性 {this.EntityInfo.EntityName}需要主键"); + var pk = pkColumn.DbColumnName; + var name = this.ProPertyEntity.Columns.First(it => it.PropertyName == Navigat.Name).DbColumnName; + //var selectName = this.ProPertyEntity.Columns.First(it => it.PropertyName == MemberName).DbColumnName; + MapperSql mapper = new MapperSql(); + var queryable = this.context.Queryable(); + pk = queryable.QueryBuilder.Builder.GetTranslationColumnName(pk); + name = queryable.QueryBuilder.Builder.GetTranslationColumnName(name); + //selectName = queryable.QueryBuilder.Builder.GetTranslationColumnName(selectName); + if (PropertyShortName.HasValue()) + { + queryable.QueryBuilder.TableShortName = PropertyShortName; + } + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500; + var isClearFilter = false; + Type[] clearTypes = null; + if (this.methodCallExpressionResolve?.Context?.SugarContext?.QueryBuilder != null) + { + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500 + this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex; + this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex++; + isClearFilter = this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.IsDisabledGobalFilter; + clearTypes = this.methodCallExpressionResolve.Context.SugarContext.QueryBuilder.RemoveFilters; + } + var sqlObj = queryable + .AS(this.ProPertyEntity.DbTableName) + .ClearFilter(clearTypes) + .Filter(isClearFilter ? null : this.ProPertyEntity.Type) + .WhereIF(!string.IsNullOrEmpty(whereSql), whereSql) + .Where($" {name}={queryable.QueryBuilder.Builder.GetTranslationColumnName(ShorName)}.{pk} ").Select(MethodName == "Any" ? "1" : " COUNT(1) ").ToSql(); + if (sqlObj.Value?.Count > 0) + { + foreach (var item in sqlObj.Value) + { + if (!this.methodCallExpressionResolve.Context.Parameters.Any(it => it.ParameterName == item.ParameterName)) + { + this.methodCallExpressionResolve.Context.Parameters.Add(item); + } + } + } + mapper.Sql = sqlObj.Key; + mapper.Sql = $" ({mapper.Sql}) "; + mapper.Sql = GetMethodSql(mapper.Sql); + return mapper; + } + + private string GetMethodSql(string sql) + { + if (MethodName == "Any") + { + return $" ( EXISTS {sql} ) "; + } + return sql; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToManyNavgateExpressionN.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToManyNavgateExpressionN.cs new file mode 100644 index 000000000..d43827b40 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToManyNavgateExpressionN.cs @@ -0,0 +1,311 @@ +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + internal class OneToManyNavgateExpressionN + { + #region Constructor + public SqlSugarProvider context; + public string shorName; + public EntityInfo entityInfo; + public List items; + public string whereSql; + public MethodCallExpressionResolve methodCallExpressionResolve; + public OneToManyNavgateExpressionN(SqlSugarProvider context, MethodCallExpressionResolve methodCallExpressionResolve) + { + this.context = context; + this.methodCallExpressionResolve = methodCallExpressionResolve; + } + #endregion + + internal bool IsNavgate(Expression expression) + { + var result = false; + var exp = expression; + if (exp is UnaryExpression) + { + exp = (exp as UnaryExpression).Operand; + } + if (exp is MethodCallExpression) + { + var memberExp = exp as MethodCallExpression; + if (memberExp.Method.Name.IsIn("Any", "Count") && memberExp.Arguments.Count > 0 && memberExp.Arguments[0] is MemberExpression) + { + result = ValiteOneManyCall(result, memberExp, memberExp.Arguments[0] as MemberExpression, memberExp.Arguments[0]); + if (memberExp.Arguments.Count > 1) + { + whereSql = GetWhereSql(memberExp); + } + } + } + return result; + } + private bool ValiteOneManyCall(bool result, MethodCallExpression callExpression, MemberExpression memberExp, Expression childExpression) + { + if (childExpression != null && childExpression is MemberExpression) + { + var oldChildExpression = childExpression; + var child2Expression = (childExpression as MemberExpression).Expression; + if (child2Expression == null || (child2Expression is ConstantExpression)) + { + return false; + } + items = new List(); + var childType = oldChildExpression.Type; + if (!childType.FullName.IsCollectionsList()) + { + return false; + } + childType = childType.GetGenericArguments()[0]; + items.Add(new ExpressionItems() { Type = 3, Expression = callExpression, ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(childType) }); + items.Add(new ExpressionItems() { Type = 2, Expression = oldChildExpression, ThisEntityInfo = this.context.EntityMaintenance.GetEntityInfo(childType), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type) }); + if (items.Any(it => it.Type == 2 && it.Nav == null)) + { + return false; + } + while (child2Expression != null) + { + if (IsClass(child2Expression)) + { + items.Add(new ExpressionItems() { Type = 2, Expression = child2Expression, ThisEntityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(GetMemberExpression(child2Expression).Type) }); + child2Expression = GetMemberExpression(child2Expression); + + } + else if (IsParameter(child2Expression)) + { + shorName = child2Expression.ToString(); + entityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type); + break; + } + else + { + break; + } + } + if (!items.Any(it => it.Type == 2 && it.Nav == null)) + { + return true; + } + } + return result; + } + public object GetSql() + { + MapperSql MapperSql = new MapperSql(); + var memberInfo = this.items.Where(it => it.Type == 3).First(); + var subInfos = this.items.Where(it => it.Type == 2).Reverse().ToList(); + var formInfo = subInfos.First(); + var joinInfos = subInfos.Skip(1).ToList(); + var i = 0; + var masterShortName = formInfo.ThisEntityInfo.DbTableName + i; + var queryable = this.context.Queryable(masterShortName).AS(formInfo.ThisEntityInfo.DbTableName); + i++; + var lastShortName = ""; + var index = 0; + foreach (var item in joinInfos) + { + if (item.Nav.NavigatType == NavigateType.OneToMany) + { + lastShortName = OneToMany(ref formInfo, ref i, queryable, ref index, item); + } + else if (item.Nav.NavigatType == NavigateType.OneToOne) + { + lastShortName = OneToOne(ref formInfo, ref i, queryable, ref index, item); + } + else + { + lastShortName = ManyToMany(ref formInfo, ref i, queryable, ref index, item); + } + } + var isAny = (memberInfo.Expression as MethodCallExpression).Method.Name == "Any"; + queryable.Select(isAny ? "1" : " COUNT(1) "); + var last = subInfos.First(); + var FirstPkColumn = last.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + FirstPkColumn = GetFirstPkColumn(last, FirstPkColumn); + Check.ExceptionEasy(FirstPkColumn == null, $"{last.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{last.ThisEntityInfo.EntityName} 缺少主键"); + var PkColumn = last.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == last.Nav.Name); + Check.ExceptionEasy(PkColumn == null, $"{last.ParentEntityInfo.EntityName} no found {last.Nav.Name}", $"{last.ParentEntityInfo.EntityName} 不存在 {last.Nav.Name}"); + queryable.Where($" {queryable.SqlBuilder.GetTranslationColumnName(this.shorName)}.{queryable.SqlBuilder.GetTranslationColumnName(PkColumn.DbColumnName)} = {queryable.SqlBuilder.GetTranslationColumnName(masterShortName)}.{queryable.SqlBuilder.GetTranslationColumnName(FirstPkColumn.DbColumnName)} "); + queryable.WhereIF(this.whereSql.HasValue(), GetWhereSql1(this.whereSql, lastShortName, joinInfos, queryable.SqlBuilder)); + MapperSql.Sql = $"( {queryable.ToSql().Key} ) "; + if (isAny) + { + MapperSql.Sql = $" EXISTS( {MapperSql.Sql}) "; + + } + return MapperSql; + } + + private static EntityColumnInfo GetFirstPkColumn(ExpressionItems last, EntityColumnInfo FirstPkColumn) + { + if (last.Nav.NavigatType == NavigateType.OneToOne && last.Nav.Name2.HasValue()) + { + var name2 = last.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == last.Nav.Name2); + if (name2 != null) + { + FirstPkColumn = name2; + } + } + return FirstPkColumn; + } + + private static string OneToMany(ref ExpressionItems formInfo, ref int i, ISugarQueryable queryable, ref int index, ExpressionItems item) + { + string lastShortName; + var shortName = item.ThisEntityInfo.DbTableName + i; + EntityColumnInfo pkColumn; + EntityColumnInfo navColum; + //if (index == 0) + //{ + pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name); + navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + if (item.Nav.Name2.HasValue()) + { + navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name2); + } + //} + //else + //{ + // pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + // navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name); + //} + Check.ExceptionEasy(pkColumn == null, $"{item.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{item.ThisEntityInfo.EntityName} 缺少主键"); + var on = $" {queryable.SqlBuilder.GetTranslationColumnName(shortName)}.{queryable.SqlBuilder.GetTranslationColumnName(pkColumn.DbColumnName)}={queryable.SqlBuilder.GetTranslationColumnName(formInfo.ThisEntityInfo.DbTableName + (i - 1))}.{queryable.SqlBuilder.GetTranslationColumnName(navColum.DbColumnName)}"; + queryable.AddJoinInfo(item.ThisEntityInfo.DbTableName, shortName, on, JoinType.Inner); + ++i; + index++; + lastShortName = shortName; + formInfo = item; + return lastShortName; + } + + private static string OneToOne(ref ExpressionItems formInfo, ref int i, ISugarQueryable queryable, ref int index, ExpressionItems item) + { + string lastShortName; + var shortName = item.ThisEntityInfo.DbTableName + i; + EntityColumnInfo pkColumn; + EntityColumnInfo navColum; + //if (index == 0) + //{ + // pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name); + // navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + //} + //else + //{ + pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name); + if (item.Nav.Name2.HasValue()) + { + pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name2); + } + //} + Check.ExceptionEasy(pkColumn == null, $"{item.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{item.ThisEntityInfo.EntityName} 缺少主键"); + var on = $" {shortName}.{queryable.SqlBuilder.GetTranslationColumnName(pkColumn.DbColumnName)}={formInfo.ThisEntityInfo.DbTableName + (i - 1)}.{queryable.SqlBuilder.GetTranslationColumnName(navColum.DbColumnName)}"; + queryable.AddJoinInfo(item.ThisEntityInfo.DbTableName, shortName, on, JoinType.Inner); + ++i; + index++; + lastShortName = shortName; + formInfo = item; + return lastShortName; + } + + + private string ManyToMany(ref ExpressionItems formInfo, ref int i, ISugarQueryable queryable, ref int index, ExpressionItems item) + { + string lastShortName; + var bshortName = item.ThisEntityInfo.DbTableName + i; + EntityColumnInfo AidColumn; + EntityColumnInfo BidColumn; + + BidColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + AidColumn = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + + var abEntity = this.context.EntityMaintenance.GetEntityInfo(item.Nav.MappingType); + var Ab_Aid = abEntity.Columns.FirstOrDefault(it => item.Nav.MappingAId == it.PropertyName); + var Ab_Bid = abEntity.Columns.FirstOrDefault(it => item.Nav.MappingBId == it.PropertyName); + + Check.ExceptionEasy(AidColumn == null, $" {AidColumn.EntityName} need primary key ", $"{AidColumn.EntityName}需要主键"); + Check.ExceptionEasy(AidColumn == null, $" {BidColumn.EntityName} need primary key ", $"{BidColumn.EntityName}需要主键"); + + var abShort = abEntity.EntityName + "_1"; + var abOn = $" {queryable.SqlBuilder.GetTranslationColumnName(abShort)}.{queryable.SqlBuilder.GetTranslationColumnName(Ab_Aid.DbColumnName)}={formInfo.ThisEntityInfo.DbTableName + (i - 1)}.{queryable.SqlBuilder.GetTranslationColumnName(AidColumn.DbColumnName)}"; + queryable.AddJoinInfo(abEntity.DbTableName, abShort, abOn, JoinType.Inner); + var On = $" {bshortName}.{queryable.SqlBuilder.GetTranslationColumnName(BidColumn.DbColumnName)}={abShort}.{queryable.SqlBuilder.GetTranslationColumnName(Ab_Bid.DbColumnName)}"; + queryable.AddJoinInfo(BidColumn.DbTableName, bshortName, On, JoinType.Inner); + ++i; + index++; + lastShortName = bshortName; + formInfo = item; + return lastShortName; + } + + #region Helper + private string GetWhereSql1(string wheresql, string lastShortName, List joinInfos, ISqlBuilder sqlBuilder) + { + var sql = wheresql; + if (sql == null) return sql; + joinInfos.Last().ThisEntityInfo.Columns.ForEach(it => + { + if (it.DbColumnName != null) + { + if (this.whereSql.Contains("." + sqlBuilder.GetTranslationColumnName(it.DbColumnName))) + { + var regex = @"\w+\." + sqlBuilder.GetTranslationColumnName(it.DbColumnName) + .Replace(sqlBuilder.SqlTranslationLeft, "\\" + sqlBuilder.SqlTranslationLeft) + .Replace(sqlBuilder.SqlTranslationRight, "\\" + sqlBuilder.SqlTranslationRight) + .Replace("\\\\", "\\"); + + if (!regex.IsMatch(this.whereSql)) + { + regex = $@"\{sqlBuilder.SqlTranslationLeft}\w+\{sqlBuilder.SqlTranslationRight}\." + sqlBuilder.GetTranslationColumnName(it.DbColumnName) + .Replace(sqlBuilder.SqlTranslationLeft, "\\" + sqlBuilder.SqlTranslationLeft) + .Replace(sqlBuilder.SqlTranslationRight, "\\" + sqlBuilder.SqlTranslationRight) + .Replace("\\\\", "\\"); + } + + this.whereSql = Regex.Replace(this.whereSql, regex, + sqlBuilder.GetTranslationColumnName(lastShortName) + "." + sqlBuilder.GetTranslationColumnName(it.DbColumnName)); + } + else + { + var oldWhere = this.whereSql; + var newWhere = this.whereSql.Replace(sqlBuilder.GetTranslationColumnName(it.DbColumnName), + sqlBuilder.GetTranslationColumnName(lastShortName) + "." + sqlBuilder.GetTranslationColumnName(it.DbColumnName)); + if (oldWhere != newWhere && !oldWhere.Contains($" {sqlBuilder.GetTranslationColumnName(it.DbColumnName)}")) + { + + } + else + { + this.whereSql = newWhere; + } + } + } + }); + return this.whereSql; + } + + private string GetWhereSql(MethodCallExpression memberExp) + { + var whereExp = memberExp.Arguments[1]; + var result = this.methodCallExpressionResolve.GetNewExpressionValue(whereExp); + return result; + } + private static bool IsParameter(Expression child2Expression) + { + return child2Expression.Type.IsClass() && child2Expression is ParameterExpression; + } + + private static Expression GetMemberExpression(Expression child2Expression) + { + return (child2Expression as MemberExpression).Expression; + } + + private static bool IsClass(Expression child2Expression) + { + return child2Expression.Type.IsClass() && child2Expression is MemberExpression; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToOneNavgateExpression.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToOneNavgateExpression.cs new file mode 100644 index 000000000..d69c341e0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToOneNavgateExpression.cs @@ -0,0 +1,203 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + internal class OneToOneNavgateExpression + { + public ExpressionContext ExpContext; + private SqlSugarProvider context; + internal EntityInfo EntityInfo; + internal EntityInfo ProPertyEntity; + private Navigate Navigat; + public string ShorName; + internal string MemberName; + private MemberExpressionResolve _memberExpressionResolve; + public OneToOneNavgateExpression(SqlSugarProvider context, MemberExpressionResolve memberExpressionResolve) + { + this.context = context; + _memberExpressionResolve = memberExpressionResolve; + } + + internal bool IsNavgate(Expression expression) + { + var result = false; + var exp = expression; + if (exp is UnaryExpression) + { + exp = (exp as UnaryExpression).Operand; + } + if (exp is MemberExpression) + { + var memberExp = exp as MemberExpression; + var childExpression = memberExp.Expression; + result = ValidateNav(result, memberExp, childExpression); + } + return result; + } + + private bool ValidateNav(bool result, MemberExpression memberExp, Expression childExpression) + { + if (childExpression != null && childExpression is MemberExpression) + { + var child2Expression = (childExpression as MemberExpression).Expression; + if (child2Expression == null) + { + return false; + } + if (child2Expression.Type.IsClass() && child2Expression is ParameterExpression) + { + var entity = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type); + if (entity.Columns.Any(x => x.PropertyName == (childExpression as MemberExpression).Member.Name && x.Navigat != null)) + { + EntityInfo = entity; + ShorName = child2Expression.ToString(); + MemberName = memberExp.Member.Name; + ProPertyEntity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type); + Navigat = entity.Columns.FirstOrDefault(x => x.PropertyName == (childExpression as MemberExpression).Member.Name).Navigat; + result = true; + } + } + } + + return result; + } + + internal MapperSql GetSql() + { + if (this.ProPertyEntity.Type.Name.StartsWith("List`")) + { + Check.ExceptionEasy(true, " expression error ", "导航查询出错,比如.Count要改成 .Count()"); + } + else if (Navigat.NavigatType == NavigateType.Dynamic) + { + return NavigatDynamicSql(); + } + var pk = this.ProPertyEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true)?.DbColumnName; + if (Navigat.Name2.HasValue()) + { + pk = this.ProPertyEntity.Columns.FirstOrDefault(it => it.PropertyName == Navigat.Name2)?.DbColumnName; + } + if (pk == null) + { + Check.ExceptionEasy( + true, + $"{this.ProPertyEntity.EntityName} naviate config error", + $"{this.ProPertyEntity.EntityName} 导航配置错误"); + } + var name = this.EntityInfo.Columns.First(it => it.PropertyName == Navigat.Name).DbColumnName; + var selectName = this.ProPertyEntity.Columns.First(it => it.PropertyName == MemberName).DbColumnName; + MapperSql mapper = new MapperSql(); + var queryable = this.context.Queryable(); + pk = queryable.QueryBuilder.Builder.GetTranslationColumnName(pk); + name = queryable.QueryBuilder.Builder.GetTranslationColumnName(name); + selectName = queryable.QueryBuilder.Builder.GetTranslationColumnName(selectName); + var tableName = this.ProPertyEntity.DbTableName; + if (ExpContext?.SugarContext?.QueryBuilder?.IsCrossQueryWithAttr == true) + { + var attr = this.ProPertyEntity.Type.GetCustomAttribute(); + var configId = ((object)this.context.CurrentConnectionConfig.ConfigId).ObjToString(); + if (attr != null && configId != attr.configId.ObjToString()) + { + var context = this.context.Root.GetConnection(attr.configId); + var dbName = context.Ado.Connection.Database; + if (context.CurrentConnectionConfig.DbLinkName.HasValue()) + { + tableName = UtilMethods.GetTableByDbLink(context, tableName, tableName, attr); + } + else + { + tableName = queryable.QueryBuilder.LambdaExpressions.DbMehtods.GetTableWithDataBase + (queryable.QueryBuilder.Builder.GetTranslationColumnName(dbName), queryable.QueryBuilder.Builder.GetTranslationColumnName(tableName)); + } + } + } + Type[] clearTypes = null; + var isClearFilter = false; + if (this._memberExpressionResolve?.Context?.SugarContext?.QueryBuilder != null) + { + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500 + this._memberExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex; + this._memberExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex++; + isClearFilter = this._memberExpressionResolve.Context.SugarContext.QueryBuilder.IsDisabledGobalFilter; + clearTypes = this._memberExpressionResolve.Context.SugarContext.QueryBuilder.RemoveFilters; + } + var type = this.ProPertyEntity.Columns.Count(it => it.IsPrimarykey) > 1 ? this.ProPertyEntity.Type : null; + if (isClearFilter) + { + type = null; + } + var sqlObj = queryable + .AS(tableName) + .ClearFilter(clearTypes) + .Filter(type) + .WhereIF(Navigat.WhereSql.HasValue(), Navigat.WhereSql) + .Where($" {queryable.SqlBuilder.GetTranslationColumnName(ShorName)}.{name}={pk} ").Select(selectName).ToSql(); + mapper.Sql = sqlObj.Key; + mapper.Sql = $" ({mapper.Sql}) "; + + if (type != null & sqlObj.Value?.Count > 0) + { + foreach (var item in sqlObj.Value) + { + if (!this._memberExpressionResolve.Context.Parameters.Any(it => it.ParameterName == item.ParameterName)) + { + this._memberExpressionResolve.Context.Parameters.Add(item); + } + } + } + + return mapper; + } + + private MapperSql NavigatDynamicSql() + { + if (Navigat.Name == null) + { + Check.ExceptionEasy( + true, + " NavigateType.Dynamic User-defined navigation objects need to be configured with json to be used in expressions . " + this.ProPertyEntity.Type.Name, + " NavigateType.Dynamic 自定义导航对象需要配置json才能在表达式中使用。 " + this.ProPertyEntity.Type.Name); + } + MapperSql mapperSql = new MapperSql(); + //var name = this.EntityInfo.Columns.First(it => it.PropertyName == Navigat.Name).DbColumnName; + var selectName = this.ProPertyEntity.Columns.First(it => it.PropertyName == MemberName).DbColumnName; + MapperSql mapper = new MapperSql(); + var queryable = this.context.Queryable(); + var tableName = this.ProPertyEntity.DbTableName; + Type[] clearTypes = null; + var isClearFilter = false; + if (this._memberExpressionResolve?.Context?.SugarContext?.QueryBuilder != null) + { + queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500 + this._memberExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex; + this._memberExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex++; + isClearFilter = this._memberExpressionResolve.Context.SugarContext.QueryBuilder.IsDisabledGobalFilter; + clearTypes = this._memberExpressionResolve.Context.SugarContext.QueryBuilder.RemoveFilters; + } + var type = this.ProPertyEntity.Columns.Count(it => it.IsPrimarykey) > 1 ? this.ProPertyEntity.Type : null; + if (isClearFilter) + { + type = null; + } + queryable + .AS(tableName) + .Take(1) + .ClearFilter(clearTypes) + .Filter(type) + .WhereIF(Navigat.WhereSql.HasValue(), Navigat.WhereSql) + .Select(selectName); + var json = Newtonsoft.Json.Linq.JArray.Parse(Navigat.Name); + foreach (var item in json) + { + string m = item["m"] + ""; + string c = item["c"] + ""; + var leftName = this.EntityInfo.Columns.First(it => it.PropertyName == m).DbColumnName; + var rightName = this.ProPertyEntity.Columns.First(it => it.PropertyName == c).DbColumnName; + queryable.Where($" {queryable.SqlBuilder.GetTranslationColumnName(ShorName)}.{queryable.SqlBuilder.GetTranslationColumnName(leftName)}={queryable.SqlBuilder.GetTranslationColumnName(rightName)} "); + } + var sqlObj = queryable.ToSql(); + mapper.Sql = sqlObj.Key; + mapper.Sql = $" ({mapper.Sql}) "; + return mapper; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToOneNavgateExpressionN.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToOneNavgateExpressionN.cs new file mode 100644 index 000000000..4c9eea535 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/OneToOneNavgateExpressionN.cs @@ -0,0 +1,187 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal class OneToOneNavgateExpressionN + { + #region Constructor + public string shorName { get; set; } + public EntityInfo entityInfo; + public List items; + public SqlSugarProvider context; + public ISqlBuilder builder; + public OneToOneNavgateExpressionN(SqlSugarProvider context) + { + this.context = context; + } + #endregion + + #region Api&Core + + public bool IsNavgate(Expression expression) + { + if (this.context == null) return false; + var result = false; + var exp = expression; + if (exp is UnaryExpression) + { + exp = (exp as UnaryExpression).Operand; + } + if (exp is MemberExpression) + { + var memberExp = exp as MemberExpression; + var childExpression = memberExp.Expression; + result = ValidateIsJoinMember(result, memberExp, childExpression); + } + return result; + } + public MapperSql GetMemberSql() + { + MapperSql MapperSql = new MapperSql(); + var memberInfo = this.items.Where(it => it.Type == 1).First(); + var subInfos = this.items.Where(it => it.Type == 2).Reverse().ToList(); + var formInfo = subInfos.First(); + var rootWhereSql = formInfo?.Nav?.WhereSql; + var joinInfos = subInfos.Skip(1).ToList(); + var i = 0; + var masterShortName = formInfo.ThisEntityInfo.DbTableName + i; + var queryable = this.context.Queryable(ToShortName(masterShortName)).AS(formInfo.ThisEntityInfo.DbTableName).Filter(null, true); + builder = queryable.SqlBuilder; + i++; + var lastShortName = ""; + foreach (var item in joinInfos) + { + var shortName = item.ThisEntityInfo.DbTableName + i; + var pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + if (item.Nav.Name2.HasValue()) + { + var nav2NameColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name2); + if (nav2NameColumn != null) + { + pkColumn = nav2NameColumn; + } + } + var navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name); + Check.ExceptionEasy(pkColumn == null, $"{item.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{item.ThisEntityInfo.EntityName} 缺少主键"); + var on = $" {ToShortName(shortName)}.{queryable.SqlBuilder.GetTranslationColumnName(pkColumn.DbColumnName)}={ToShortName(formInfo.ThisEntityInfo.DbTableName + (i - 1))}.{queryable.SqlBuilder.GetTranslationColumnName(navColum.DbColumnName)}"; + if (item.Nav.WhereSql.HasValue()) + { + on = (on + " AND " + item.Nav.WhereSql); + } + queryable.AddJoinInfo(item.ThisEntityInfo.DbTableName, ToShortName(shortName), on, JoinType.Inner); + ++i; + lastShortName = shortName; + formInfo = item; + } + var selectProperyInfo = ExpressionTool.GetMemberName(memberInfo.Expression); + var selectColumnInfo = memberInfo.ParentEntityInfo.Columns.First(it => it.PropertyName == selectProperyInfo); + if (rootWhereSql?.HasValue() == true) + { + queryable.Where(rootWhereSql); + } + queryable.Select($" {ToShortName(lastShortName)}.{queryable.SqlBuilder.GetTranslationColumnName(selectColumnInfo.DbColumnName)}"); + var last = subInfos.First(); + var FirstPkColumn = last.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey); + if (last.Nav.Name2.HasValue()) + { + var nav2 = last.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == last.Nav.Name2); + if (nav2 != null) + { + FirstPkColumn = nav2; + } + } + Check.ExceptionEasy(FirstPkColumn == null, $"{last.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{last.ThisEntityInfo.EntityName} 缺少主键"); + var PkColumn = last.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == last.Nav.Name); + Check.ExceptionEasy(PkColumn == null, $"{last.ParentEntityInfo.EntityName} no found {last.Nav.Name}", $"{last.ParentEntityInfo.EntityName} 不存在 {last.Nav.Name}"); + queryable.Where($" {ToShortName(this.shorName)}.{queryable.SqlBuilder.GetTranslationColumnName(PkColumn.DbColumnName)} = {ToShortName(masterShortName)}.{queryable.SqlBuilder.GetTranslationColumnName(FirstPkColumn.DbColumnName)} "); + MapperSql.Sql = "( " + queryable.ToSql().Key + " ) "; + return MapperSql; + } + private bool ValidateIsJoinMember(bool result, MemberExpression memberExp, Expression childExpression) + { + if (childExpression != null && childExpression is MemberExpression) + { + var oldChildExpression = childExpression; + var child2Expression = (childExpression as MemberExpression).Expression; + if (child2Expression == null || (child2Expression is ConstantExpression)) + { + return false; + } + items = new List(); + items.Add(new ExpressionItems() { Type = 1, Expression = memberExp, ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(oldChildExpression.Type) }); + items.Add(new ExpressionItems() { Type = 2, Expression = oldChildExpression, ThisEntityInfo = this.context.EntityMaintenance.GetEntityInfo(oldChildExpression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type) }); + if (items.Any(it => it.Type == 2 && it.Nav == null)) + { + return false; + } + while (child2Expression != null) + { + if (IsClass(child2Expression)) + { + items.Add(new ExpressionItems() { Type = 2, Expression = child2Expression, ThisEntityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(GetMemberExpression(child2Expression).Type) }); + child2Expression = GetMemberExpression(child2Expression); + + } + else if (IsParameter(child2Expression)) + { + shorName = child2Expression.ToString(); + entityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type); + break; + } + else + { + break; + } + } + if (!items.Any(it => it.Type == 2 && it.Nav == null)) + { + return true; + } + } + return result; + } + #endregion + + #region Helper + private string ToShortName(string name) + { + var result = ""; + if (name.ObjToString().Contains('.')) + { + if (this.context != null) + { + var sqlBuilder = this.context.Queryable().SqlBuilder; + result = sqlBuilder.SqlTranslationLeft + name.Replace(".", "_") + sqlBuilder.SqlTranslationRight; + return result; + } + else + { + result = name.Replace(".", "_"); + } + } + else + { + result = name; + } + if (builder == null) return name; + return builder.GetTranslationColumnName(name); + } + + private static bool IsParameter(Expression child2Expression) + { + return child2Expression.Type.IsClass() && child2Expression is ParameterExpression; + } + + private static Expression GetMemberExpression(Expression child2Expression) + { + return (child2Expression as MemberExpression).Expression; + } + + private static bool IsClass(Expression child2Expression) + { + return child2Expression.Type.IsClass() && child2Expression is MemberExpression; + } + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/TypeParameterExpressionReolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/TypeParameterExpressionReolve.cs new file mode 100644 index 000000000..b309898b4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/TypeParameterExpressionReolve.cs @@ -0,0 +1,48 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class TypeParameterExpressionReolve : BaseResolve + { + public TypeParameterExpressionReolve(ExpressionParameter parameter) : base(parameter) + { + var expression = (ParameterExpression)base.Expression; + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + break; + case ResolveExpressType.WhereMultiple: + break; + case ResolveExpressType.Update: + parameter.BaseParameter.CommonTempData = expression.Name; + break; + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + if (parameter.BaseParameter != null && parameter.BaseParameter.CurrentExpression.NodeType == ExpressionType.Lambda) + { + //if (this.Context.PgSqlIsAutoToLower == false&&this.Context is PostgreSQLExpressionContext) + //{ + this.Context.Result.Append(this.Context.GetTranslationColumnName(expression.Name) + ".*"); + //} + //else + //{ + // this.Context.Result.Append(expression.Name + ".*"); + //} + } + else + { + parameter.BaseParameter.CommonTempData = expression.Name; + } + break; + case ResolveExpressType.FieldSingle: + break; + case ResolveExpressType.FieldMultiple: + break; + case ResolveExpressType.Join: + break; + default: + break; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/UnaryExpressionResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/UnaryExpressionResolve.cs new file mode 100644 index 000000000..69cb3f89a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/ResolveItems/UnaryExpressionResolve.cs @@ -0,0 +1,190 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class UnaryExpressionResolve : BaseResolve + { + public UnaryExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + var oldExpression = base.Expression; + var expression = base.Expression as UnaryExpression; + var baseParameter = parameter.BaseParameter; + switch (this.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.ArraySingle: + case ResolveExpressType.ArrayMultiple: + case ResolveExpressType.Update: + var nodeType = expression.NodeType; + base.Expression = expression.Operand; + var isMember = expression.Operand is MemberExpression; + var isConst = expression.Operand is ConstantExpression; + var offsetIsNull = (parameter.OppsiteExpression is ConstantExpression) + && (parameter.OppsiteExpression as ConstantExpression).Value == null + && ExpressionTool.IsComparisonOperator(expression.Operand); + if (isMember && offsetIsNull) + { + Append(parameter, nodeType); + } + else if (baseParameter.CurrentExpression is NewArrayExpression) + { + Result(parameter, nodeType); + } + else if (baseParameter.OperatorValue == "=" && IsNotMember(oldExpression)) + { + AppendNotMember(parameter, nodeType); + } + else if (baseParameter.OperatorValue == "=" && IsNotParameter(oldExpression)) + { + AppendNotParameter(parameter, nodeType); + } + else if (base.Expression is BinaryExpression || parameter.BaseExpression is BinaryExpression || baseParameter.CommonTempData.ObjToString() == CommonTempDataType.Append.ToString()) + { + Append(parameter, nodeType); + } + else if (isMember) + { + MemberLogic(parameter, baseParameter, nodeType); + } + else if (isConst) + { + Result(parameter, nodeType); + } + else + { + Append(parameter, nodeType); + } + break; + default: + break; + } + } + + private void MemberLogic(ExpressionParameter parameter, ExpressionParameter baseParameter, ExpressionType nodeType) + { + var memberExpression = (base.Expression as MemberExpression); + var isLogicOperator = ExpressionTool.IsLogicOperator(baseParameter.OperatorValue) || baseParameter.OperatorValue.IsNullOrEmpty(); + var isHasValue = isLogicOperator && memberExpression.Member.Name == "HasValue" && memberExpression.Expression != null && memberExpression.NodeType == ExpressionType.MemberAccess; + if (isHasValue) + { + var member = memberExpression.Expression as MemberExpression; + parameter.CommonTempData = CommonTempDataType.Result; + var isConst = member.Expression != null && member.Expression is ConstantExpression; + if (isConst) + { + var paramterValue = ExpressionTool.DynamicInvoke(member); + var paramterName = base.AppendParameter(paramterValue); + var result = this.Context.DbMehtods.HasValue(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs() { IsMember=false, MemberName=paramterName, MemberValue=paramterValue } } + }); + this.Context.Result.Append(result); + } + else + { + this.Expression = isConst ? member.Expression : member; + this.Start(); + var methodParamter = isConst ? new MethodCallExpressionArgs() { IsMember = false } : new MethodCallExpressionArgs() { IsMember = true, MemberName = parameter.CommonTempData, MemberValue = null }; + var result = this.Context.DbMehtods.HasValue(new MethodCallExpressionModel() + { + Args = new List() { + methodParamter + } + }); + if (nodeType == ExpressionType.Not && memberExpression.Member.Name == "HasValue") + { + this.Context.Result.Append("NOT" + result); + } + else + { + this.Context.Result.Append(result); + } + parameter.CommonTempData = null; + } + } + else if (memberExpression.Type == UtilConstants.BoolType && isLogicOperator) + { + Append(parameter, nodeType); + } + else + { + Result(parameter, nodeType); + } + } + + private void Result(ExpressionParameter parameter, ExpressionType nodeType) + { + BaseParameter.ChildExpression = base.Expression; + parameter.CommonTempData = CommonTempDataType.Result; + if (nodeType == ExpressionType.Not) + AppendNot(parameter.CommonTempData); + base.Start(); + parameter.BaseParameter.CommonTempData = parameter.CommonTempData; + if (nodeType == ExpressionType.Negate && parameter.BaseParameter.CommonTempData is int) + parameter.BaseParameter.CommonTempData = Convert.ToInt32(parameter.BaseParameter.CommonTempData) * -1; + parameter.BaseParameter.ChildExpression = base.Expression; + parameter.CommonTempData = null; + } + + private void Append(ExpressionParameter parameter, ExpressionType nodeType) + { + BaseParameter.ChildExpression = base.Expression; + this.IsLeft = parameter.IsLeft; + parameter.CommonTempData = CommonTempDataType.Append; + if (nodeType == ExpressionType.Not) + AppendNot(parameter.CommonTempData); + if (nodeType == ExpressionType.Negate) + AppendNegate(parameter.CommonTempData); + base.Start(); + parameter.BaseParameter.CommonTempData = parameter.CommonTempData; + parameter.BaseParameter.ChildExpression = base.Expression; + parameter.CommonTempData = null; + } + + + private void AppendNotMember(ExpressionParameter parameter, ExpressionType nodeType) + { + BaseParameter.ChildExpression = base.Expression; + this.IsLeft = parameter.IsLeft; + parameter.CommonTempData = CommonTempDataType.Result; + base.Start(); + var result = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=parameter.CommonTempData.ObjToString()+"=1",Type=UtilConstants.BoolType }, + new MethodCallExpressionArgs(){ IsMember=true,MemberName=AppendParameter(0) }, + new MethodCallExpressionArgs(){ IsMember=true, MemberName=AppendParameter(1) } + } + }); + this.Context.Result.Append(result); + parameter.BaseParameter.ChildExpression = base.Expression; + parameter.CommonTempData = null; + } + + + private void AppendNotParameter(ExpressionParameter parameter, ExpressionType nodeType) + { + BaseParameter.ChildExpression = base.Expression; + this.IsLeft = parameter.IsLeft; + parameter.CommonTempData = CommonTempDataType.Result; + base.Start(); + var result = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs(){ IsMember=true, MemberName=AppendParameter(parameter.CommonTempData)+"=1" }, + new MethodCallExpressionArgs(){ IsMember=true,MemberName=AppendParameter(0) }, + new MethodCallExpressionArgs(){ IsMember=true, MemberName=AppendParameter(1) } + } + }); + this.Context.Result.Append(result); + parameter.BaseParameter.ChildExpression = base.Expression; + parameter.CommonTempData = null; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/ISubOperation.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/ISubOperation.cs new file mode 100644 index 000000000..d26a1e291 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/ISubOperation.cs @@ -0,0 +1,14 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public interface ISubOperation + { + ExpressionContext Context { get; set; } + string Name { get; } + string GetValue(Expression expression); + int Sort { get; } + Expression Expression { get; set; } + bool HasWhere { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAnd.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAnd.cs new file mode 100644 index 000000000..d6485aeb7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAnd.cs @@ -0,0 +1,112 @@ +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SubAnd : ISubOperation + { + public string Name + { + get { return "And"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 401; + } + } + + public ExpressionContext Context + { + get; set; + } + + public bool HasWhere + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var copyContext = this.Context; + + var pars = ExpressionTool.GetParameters(expression).Distinct(); + if (this.Context.JoinIndex > 0 || pars.Count() > 1) + { + copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + } + if (ExpressionTool.GetMethodName(argExp) == "ToExpression") + { + argExp = ExpressionTool.DynamicInvoke(argExp) as Expression; + } + var result = "AND " + SubTools.GetMethodValue(copyContext, argExp, ResolveExpressType.WhereMultiple); + if (argExp.Type == typeof(List)) + { + var p = this.Context.Parameters.Last(); + this.Context.Parameters.Remove(p); + var cols = p.Value as List; + var sqlObj = this.Context.SugarContext.QueryBuilder.Builder.ConditionalModelToSql(cols, this.Context.ParameterIndex * 100); + this.Context.ParameterIndex = this.Context.ParameterIndex + this.Context.ParameterIndex * 100; + result = "AND " + sqlObj.Key; + this.Context.Parameters.AddRange(sqlObj.Value); + return result; + } + if (this.Context.JoinIndex > 0 || pars.Count() > 1) + { + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + } + + var regex = @"^AND (\@Const\d+) $"; + if (this.Context is OracleExpressionContext) + { + regex = @"^AND (\:Const\d+) $"; + } + if (this.Context is DmExpressionContext) + { + regex = @"^AND (\:Const\d+) $"; + } + if (Regex.IsMatch(result, regex)) + { + var value = GetValue(result, regex); + if (value is Expression) + { + var p = this.Context.Parameters.First(it => it.ParameterName == Regex.Match(result, regex).Groups[1].Value); + result = "AND " + SubTools.GetMethodValue(Context, value as Expression, ResolveExpressType.WhereMultiple); + argExp = value as Expression; + this.Context.Parameters.Remove(p); + } + else + { + result = "AND " + value; + return result; + } + } + + var selfParameterName = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0 && result.Contains(" FROM ")) + { + this.Context.CurrentShortName = selfParameterName.TrimEnd('.'); + } + else if (this.Context.JoinIndex == 0 && this.Context.CurrentShortName != selfParameterName.TrimEnd('.')) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + + private object GetValue(string result, string regex) + { + return this.Context.Parameters.First(it => it.ParameterName == Regex.Match(result, regex).Groups[1].Value).Value; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAndIF.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAndIF.cs new file mode 100644 index 000000000..587056d1f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAndIF.cs @@ -0,0 +1,74 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubAndIF : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "WhereIF"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 400; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + object value = null; + try + { + value = ExpressionTool.DynamicInvoke(exp.Arguments[0]); + } + catch + { + Check.Exception(true, ErrorMessage.WhereIFCheck, exp.Arguments[0].ToString()); + } + var isWhere = Convert.ToBoolean(value); + if (!Convert.ToBoolean(isWhere)) + { + return ""; + } + var argExp = exp.Arguments[1]; + var copyContext = this.Context; + if (this.Context.JoinIndex > 0) + { + copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + } + var result = "AND " + SubTools.GetMethodValue(copyContext, argExp, ResolveExpressType.WhereMultiple); ; + if (this.Context.JoinIndex > 0) + { + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + } + var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + { + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAny.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAny.cs new file mode 100644 index 000000000..28b667d8a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAny.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubAny : ISubOperation + { + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Any"; + } + } + + public int Sort + { + get + { + return 0; + } + } + + public string GetValue(Expression expression) + { + return "EXISTS"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAs.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAs.cs new file mode 100644 index 000000000..24f520586 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAs.cs @@ -0,0 +1,52 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubAs : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "AS"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + var arg = exp.Arguments[0]; + if (arg is MethodCallExpression) + { + arg = Expression.Constant(ExpressionTool.DynamicInvoke(arg)); + } + var expString = SubTools.GetMethodValue(this.Context, arg, ResolveExpressType.WhereSingle)?.Trim(); + var result = this.Context.Parameters.First(it => it.ParameterName == expString).Value + ""; + return "$SubAs:" + result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAsWithAttr.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAsWithAttr.cs new file mode 100644 index 000000000..785835315 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAsWithAttr.cs @@ -0,0 +1,51 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubAsWithAttr : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "AsWithAttr"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + var type = exp.Type.GetGenericArguments()[0]; + var db = this.Context.SugarContext.Context; + var entityInfo = db.EntityMaintenance.GetEntityInfo(type); + var tableName = entityInfo.DbTableName; + var queryable = ((QueryableProvider)(db.Queryable())); + var expString = queryable.GetTableName(entityInfo, tableName); + return "$SubAs:" + expString; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAvg.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAvg.cs new file mode 100644 index 000000000..628746acf --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubAvg.cs @@ -0,0 +1,45 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubAvg : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Avg"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + return "AVG(" + SubTools.GetMethodValue(this.Context, exp.Arguments[0], ResolveExpressType.FieldSingle) + ")"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubBegin.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubBegin.cs new file mode 100644 index 000000000..8a737deee --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubBegin.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubBegin : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Begin"; + } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 100; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + return "SELECT"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubCount.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubCount.cs new file mode 100644 index 000000000..81ec7a819 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubCount.cs @@ -0,0 +1,44 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubCount : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Count"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + return "COUNT(*)"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubDistinctCount.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubDistinctCount.cs new file mode 100644 index 000000000..1b28bf993 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubDistinctCount.cs @@ -0,0 +1,77 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubDistinctCount : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "DistinctCount"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + InitType(exp); + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + if (this.Context.InitMappingInfo != null && argLambda?.Parameters.Count > 0) + { + foreach (var item in argLambda.Parameters) + { + this.Context.InitMappingInfo(item.Type); + } + this.Context.RefreshMapping(); + } + var result = "COUNT(DISTINCT " + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple) + ")"; + var selfParameterName = Context.GetTranslationColumnName(parametres.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + private void InitType(MethodCallExpression exp) + { + foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(arg.Type); + this.Context.RefreshMapping(); + } + } + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubEnableTableFilter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubEnableTableFilter.cs new file mode 100644 index 000000000..ab0abc7ac --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubEnableTableFilter.cs @@ -0,0 +1,72 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public class SubEnableTableFilter : ISubOperation + { + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "EnableTableFilter"; + } + } + + public int Sort + { + get + { + return 402; + } + } + + public string GetValue(Expression expression) + { + var result = ""; + if (this.Context.SugarContext != null) + { + var db = this.Context.SugarContext.Context; + BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; + Type type = this.Context.SubTableType; + var isWhere = HasWhere; + if (db.QueryFilter.GetFilterList != null) + { + foreach (var item in db.QueryFilter.GetFilterList) + { + PropertyInfo field = item.GetType().GetProperty("exp", flag); + if (field != null) + { + Type ChildType = item.GetType().GetProperty("type", flag).GetValue(item, null) as Type; + if (ChildType == type || (ChildType.IsInterface && type.GetInterfaces().Contains(ChildType))) + { + var entityInfo = db.EntityMaintenance.GetEntityInfo(ChildType); + this.Context.InitMappingInfo(ChildType); + var exp = field.GetValue(item, null) as Expression; + var whereStr = isWhere ? " AND " : " WHERE "; + isWhere = true; + result += (whereStr + SubTools.GetMethodValue(Context, exp, ResolveExpressType.WhereSingle)); + } + } + } + } + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubFirst.cs new file mode 100644 index 000000000..398dfccf0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubFirst.cs @@ -0,0 +1,195 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubFirst : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "First"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + if (IsAutoGeneric(exp)) return GetValueByAuto(exp); + if (IsAutoSelect(exp)) return GetValueByAuto(exp); + InitType(exp); + var type = expression.Type; + if (type.FullName.IsCollectionsList() + && exp.Arguments.Count == 0 && type.GenericTypeArguments.Length > 0 + && this.Context.SugarContext?.QueryBuilder.IsSelectNoAll == true) + { + var entity = type.GenericTypeArguments[0]; + var columnNames = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(entity).Columns; + var columnsString = string.Join(",", columnNames + .Where(it => it.IsIgnore == false) + .Where(it => it.DbColumnName.HasValue()) + .Select(it => this.Context.GetTranslationColumnName(it.DbColumnName))); + return $"{columnsString},@sugarIndex as sugarIndex"; + } + else if (exp.Arguments.Count == 0) + { + return "*,@sugarIndex as sugarIndex"; + } + var argExp = exp.Arguments[0]; + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + var copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.Resolve(argLambda, ResolveExpressType.SelectMultiple); + var select = copyContext.Result.GetString(); + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + SetShortName(exp, null); + return select + ",@sugarIndex as sugarIndex"; + } + + private void InitType(MethodCallExpression exp) + { + if (exp.Arguments.Count > 0) + { + foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(arg.Type); + this.Context.RefreshMapping(); + } + } + } + } + + public void SetShortName(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count != 0 && exp.Arguments[0] is LambdaExpression) + { + var parameters = (exp.Arguments[0] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + public void SetShortNameNext(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression) + { + var parameters = (exp.Arguments[1] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + + private string GetValueByAuto(MethodCallExpression exp) + { + var selectExp = exp.Arguments.FirstOrDefault(); + if (selectExp == null) + { + var type = exp.Type; + var parameter = Expression.Parameter(type, "it"); + + // 构造返回值表达式 + var body = Expression.MemberInit(Expression.New(type)); + + // 将返回值表达式作为lambda表达式的主体 + selectExp = Expression.Lambda(body, parameter); + + } + var bodyExp = ExpressionTool.GetLambdaExpressionBody(selectExp); + var newMemExp = (bodyExp as MemberInitExpression); + var parameters = ExpressionTool.GetParameters(exp); + InitType(exp); + if (parameters.Count != 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters.FirstOrDefault().Name); + } + Check.ExceptionEasy(newMemExp == null, $"Subquery ToList(exp,true) expression {exp.ToString()} can only be it=>new class(){{Id = it.id}}", $"子查询ToList(exp,true)表达式{exp.ToString()}只能是it=>new class(){{ id=it.Id}}"); + var dic = ExpressionTool.GetMemberBindingItemList(newMemExp.Bindings); + var db = this.Context.SugarContext.Context; + var builder = this.Context.SugarContext.QueryBuilder.Builder; + var columnInfos = db.EntityMaintenance.GetEntityInfo(bodyExp.Type); + var autoColumns = columnInfos.Columns + .Where(it => !dic.ContainsKey(it.PropertyName)) + .Where(it => it.IsIgnore == false) + .ToList(); + List appendColumns = new List(); + List completeColumnColumns = new List(); + foreach (var item in autoColumns) + { + + foreach (var parameter in parameters) + { + var parameterColumns = db.EntityMaintenance.GetEntityInfo(parameter.Type).Columns; + if (!completeColumnColumns.Any(it => it.EqualCase(item.PropertyName)) && parameterColumns.Any(it => it.PropertyName.EqualCase(item.PropertyName))) + { + var completeColumn = parameterColumns.First(it => it.PropertyName == item.PropertyName); + var shortName = builder.GetTranslationColumnName(parameter.Name); + var columnName = builder.GetTranslationColumnName(completeColumn.DbColumnName); + var asName = builder.SqlTranslationLeft + item.PropertyName + builder.SqlTranslationRight; + appendColumns.Add($"{shortName}.{columnName} as {asName}"); + completeColumnColumns.Add(completeColumn.PropertyName); + } + } + } + var copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.Resolve(bodyExp, ResolveExpressType.SelectMultiple); + var select = copyContext.Result.GetString(); + if (dic.Count > 0 && appendColumns.Count == 0) + { + return select + ",@sugarIndex as sugarIndex"; ; + } + else if (dic.Count > 0 && appendColumns.Count > 0) + { + return select + "," + string.Join(",", appendColumns) + ",@sugarIndex as sugarIndex"; ; + } + else + { + return string.Join(",", appendColumns) + ",@sugarIndex as sugarIndex"; + } + } + private static bool IsAutoSelect(MethodCallExpression exp) + { + return exp.Arguments.Count == 2 && exp.Arguments.Last().Type == UtilConstants.BoolType; + } + private static bool IsAutoGeneric(MethodCallExpression exp) + { + return exp.Arguments.Count == 0 && exp.Method.GetGenericArguments().Length == 1; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubFromTable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubFromTable.cs new file mode 100644 index 000000000..2d97adb4e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubFromTable.cs @@ -0,0 +1,58 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubFromTable : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Subqueryable"; + } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 300; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var resType = exp.Method.ReturnType; + var entityType = resType.GetGenericArguments().First(); + this.Context.SubTableType = entityType; + var name = entityType.Name; + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(entityType); + this.Context.RefreshMapping(); + } + var result = "FROM " + this.Context.GetTranslationTableName(name, true); + if (this.Context.SubQueryIndex > 0) + { + result += " subTableIndex" + this.Context.SubQueryIndex; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubGroupBy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubGroupBy.cs new file mode 100644 index 000000000..f4ad58c2c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubGroupBy.cs @@ -0,0 +1,76 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubGroupBy : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "GroupBy"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 479; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var type = ResolveExpressType.FieldSingle; + if ((argExp as LambdaExpression).Body is NewExpression) + { + type = ResolveExpressType.ArraySingle; + } + var result = "GROUP BY "; + if (this.Context.JoinIndex == 0) + { + result = result + SubTools.GetMethodValue(this.Context, argExp, type); + } + else + { + if (type == ResolveExpressType.ArraySingle) + { + type = ResolveExpressType.ArrayMultiple; + } + else if (type == ResolveExpressType.FieldSingle) + { + type = ResolveExpressType.FieldMultiple; + } + else if (type == ResolveExpressType.WhereSingle) + { + type = ResolveExpressType.WhereMultiple; + } + result = result + SubTools.GetMethodValueSubJoin(this.Context, argExp, type); + } + result = result.TrimEnd(','); + var selfParameterName = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + if (this.Context.CurrentShortName == null) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(ExpressionTool.GetParameters(exp).FirstOrDefault().Name); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubHaving.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubHaving.cs new file mode 100644 index 000000000..44e0a7e47 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubHaving.cs @@ -0,0 +1,46 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubHaving : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "Having"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 480; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var result = "Having " + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple); + var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubInnerJoin.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubInnerJoin.cs new file mode 100644 index 000000000..11d2532fe --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubInnerJoin.cs @@ -0,0 +1,75 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubInnerJoin : ISubOperation + { + + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "InnerJoin"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 302; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var name = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters[0].Name); + var parameter = (argExp as LambdaExpression).Parameters.Last(); + foreach (var item in (argExp as LambdaExpression).Parameters) + { + Context.InitMappingInfo(item.Type); + } + this.Context.RefreshMapping(); + var tableName = Context.GetTranslationTableName(parameter.Type.Name, true); + if (this.Context.IsAsAttr == true) + { + var db = this.Context.SugarContext.Context; + var entityInfo = db.EntityMaintenance.GetEntityInfo(parameter.Type); + var queryable = ((QueryableProvider)(db.Queryable())); + tableName = queryable.GetTableName(entityInfo, tableName); + } + if (exp.Arguments.Count == 2 && exp.Arguments.Last().HasValue()) + { + tableName = Context.GetTranslationTableName(ExpressionTool.DynamicInvoke(exp.Arguments.Last()) + ""); + } + var joinString = string.Format(" {2} INNER JOIN {1} {0} ", + this.Context.GetTranslationColumnName(parameter.Name), + tableName, + null); + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.DbType == DbType.SqlServer && this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsWithNoLockSubquery == true) + { + joinString = $"{joinString} {SqlWith.NoLock} "; + } + var result = joinString + "ON " + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple); + //var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + this.Context.JoinIndex++; + new SubSelect() { Context = this.Context }.SetShortName(exp, "+"); + //result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubLeftBracket.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubLeftBracket.cs new file mode 100644 index 000000000..2fa0c9f32 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubLeftBracket.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubLeftBracket : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "LeftBracket"; + } + } + + public int Sort + { + get + { + return 50; + } + } + + public string GetValue(Expression expression) + { + return "("; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubLeftJoin.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubLeftJoin.cs new file mode 100644 index 000000000..3c2e71e90 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubLeftJoin.cs @@ -0,0 +1,75 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubLeftJoin : ISubOperation + { + + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "LeftJoin"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 302; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var name = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters[0].Name); + var parameter = (argExp as LambdaExpression).Parameters.Last(); + foreach (var item in (argExp as LambdaExpression).Parameters) + { + Context.InitMappingInfo(item.Type); + } + this.Context.RefreshMapping(); + var tableName = Context.GetTranslationTableName(parameter.Type.Name, true); + if (this.Context.IsAsAttr == true) + { + var db = this.Context.SugarContext.Context; + var entityInfo = db.EntityMaintenance.GetEntityInfo(parameter.Type); + var queryable = ((QueryableProvider)(db.Queryable())); + tableName = queryable.GetTableName(entityInfo, tableName); + } + if (exp.Arguments.Count == 2 && exp.Arguments.Last().HasValue()) + { + tableName = Context.GetTranslationTableName(ExpressionTool.DynamicInvoke(exp.Arguments.Last()) + ""); + } + var joinString = string.Format(" {2} LEFT JOIN {1} {0} ", + this.Context.GetTranslationColumnName(parameter.Name), + tableName, + null); + if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.DbType == DbType.SqlServer && this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsWithNoLockSubquery == true) + { + joinString = $"{joinString} {SqlWith.NoLock} "; + } + var result = joinString + "ON " + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple); + //var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + this.Context.JoinIndex++; + new SubSelect() { Context = this.Context }.SetShortName(exp, "+"); + //result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubMax.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubMax.cs new file mode 100644 index 000000000..e0d9c4324 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubMax.cs @@ -0,0 +1,64 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubMax : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Max"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + if (this.Context.InitMappingInfo != null && argLambda?.Parameters.Count > 0) + { + foreach (var item in argLambda.Parameters) + { + this.Context.InitMappingInfo(item.Type); + } + this.Context.RefreshMapping(); + } + var result = "MAX(" + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple) + ")"; + var selfParameterName = Context.GetTranslationColumnName(parametres.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubMin.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubMin.cs new file mode 100644 index 000000000..eb7a058bb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubMin.cs @@ -0,0 +1,64 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubMin : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Min"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + if (this.Context.InitMappingInfo != null && argLambda?.Parameters.Count > 0) + { + foreach (var item in argLambda.Parameters) + { + this.Context.InitMappingInfo(item.Type); + } + this.Context.RefreshMapping(); + } + var result = "MIN(" + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple) + ")"; + var selfParameterName = Context.GetTranslationColumnName(parametres.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubNotAny.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubNotAny.cs new file mode 100644 index 000000000..a99d4949a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubNotAny.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubNotAny : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "NotAny"; + } + } + + public int Sort + { + get + { + return 0; + } + } + + public string GetValue(Expression expression) + { + return "NOT EXISTS"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubOrderBy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubOrderBy.cs new file mode 100644 index 000000000..a6ab0986f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubOrderBy.cs @@ -0,0 +1,113 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubOrderBy : ISubOperation + { + public int OrderIndex { get; set; } = 0; + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "OrderBy"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 480 + OrderIndex; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + if (this.Context is OracleExpressionContext) + { + throw new Exception("Oracle Subquery can't OrderBy"); + } + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var result = ""; + if (this.Context.JoinIndex == 0) + { + result = (OrderIndex == 0 ? "ORDER BY " : ",") + SubTools.GetMethodValue(this.Context, argExp, ResolveExpressType.FieldSingle); + } + else + { + result = (OrderIndex == 0 ? "ORDER BY " : ",") + SubTools.GetMethodValueSubJoin(this.Context, argExp, ResolveExpressType.FieldMultiple); + } + var selfParameterName = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + { + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + } + return result; + } + } + public class SubOrderByDesc : ISubOperation + { + public int OrderIndex { get; set; } = 0; + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "OrderByDesc"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 480 + OrderIndex; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var result = ""; + if (this.Context.JoinIndex == 0) + { + result = (OrderIndex == 0 ? "ORDER BY " : ",") + SubTools.GetMethodValue(this.Context, argExp, ResolveExpressType.FieldSingle) + " DESC"; + } + else + { + result = (OrderIndex == 0 ? "ORDER BY " : ",") + SubTools.GetMethodValueSubJoin(this.Context, argExp, ResolveExpressType.FieldMultiple) + " DESC"; + } + var selfParameterName = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + { + result = result.Replace(selfParameterName, string.Empty); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubRightBracket.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubRightBracket.cs new file mode 100644 index 000000000..9eac6ea92 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubRightBracket.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubRightBracket : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "RightBracket"; + } + } + + public int Sort + { + get + { + return 500; + } + } + + public string GetValue(Expression expression) + { + return ")"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelect.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelect.cs new file mode 100644 index 000000000..8bbc71e9b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelect.cs @@ -0,0 +1,92 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubSelect : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Select"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + InitType(exp); + var result = ""; + + var oldIsSingle = this.Context.IsSingle; + this.Context.IsSingle = false; + result = SubTools.GetMethodValue(this.Context, exp.Arguments[0], ResolveExpressType.FieldMultiple); + this.Context.IsSingle = oldIsSingle; + + SetShortName(exp, result); + + return result; + } + + private void InitType(MethodCallExpression exp) + { + foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(arg.Type); + this.Context.RefreshMapping(); + } + } + } + + public void SetShortName(MethodCallExpression exp, string result) + { + if (exp.Arguments[0] is LambdaExpression) + { + var parameters = (exp.Arguments[0] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + public void SetShortNameNext(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression) + { + var parameters = (exp.Arguments[1] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelectDefault.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelectDefault.cs new file mode 100644 index 000000000..3fb9acac1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelectDefault.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubSelectDefault : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "SelectDefault"; + } + } + + public int Sort + { + get + { + return 250; + } + } + + public string GetValue(Expression expression) + { + return "*"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelectStringJoin.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelectStringJoin.cs new file mode 100644 index 000000000..8615a7dae --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSelectStringJoin.cs @@ -0,0 +1,104 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public class SubSelectStringJoin : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "SelectStringJoin"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + //var entityType = (exp.Arguments[0] as LambdaExpression).Parameters[0].Type; + //if (this.Context.InitMappingInfo != null) + //{ + // this.Context.InitMappingInfo(entityType); + // this.Context.RefreshMapping(); + //} + InitType(exp); + var result = ""; + if (this.Context.JoinIndex == 0) + result = SubTools.GetMethodValue(this.Context, exp.Arguments[0], ResolveExpressType.FieldSingle); + else + result = SubTools.GetMethodValueSubJoin(this.Context, exp.Arguments[0], ResolveExpressType.FieldMultiple); + + SetShortName(exp, result); + + if (result == null && ExpressionTool.GetLambdaExpressionBody(exp.Arguments[0]) is ConstantExpression) + { + var constant = ExpressionTool.GetLambdaExpressionBody(exp.Arguments[0]) as ConstantExpression; + if (constant.Value?.ToString()?.Contains(',') == true) + { + result = string.Join(",", (constant.Value + "").Split(',').Select(it => this.Context.GetTranslationTableName(it))); + } + } + result = this.Context.DbMehtods.GetStringJoinSelector(result, ExpressionTool.GetExpressionValue(exp.Arguments[1]) + ""); + + return result; + } + private void InitType(MethodCallExpression exp) + { + foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(arg.Type); + this.Context.RefreshMapping(); + } + } + } + public void SetShortName(MethodCallExpression exp, string result) + { + if (exp.Arguments[0] is LambdaExpression) + { + var parameters = (exp.Arguments[0] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + public void SetShortNameNext(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression) + { + var parameters = (exp.Arguments[1] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSum.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSum.cs new file mode 100644 index 000000000..c7b290edc --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubSum.cs @@ -0,0 +1,64 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubSum : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "Sum"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + if (this.Context.InitMappingInfo != null && argLambda?.Parameters.Count > 0) + { + foreach (var item in argLambda.Parameters) + { + this.Context.InitMappingInfo(item.Type); + } + this.Context.RefreshMapping(); + } + var result = "SUM(" + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple) + ")"; + var selfParameterName = Context.GetTranslationColumnName(parametres.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubTake.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubTake.cs new file mode 100644 index 000000000..a5c6cc2e5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubTake.cs @@ -0,0 +1,89 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubTake : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "Take"; + } + } + + public int Sort + { + get + { + if (this.Context is SqlServerExpressionContext || this.Context.GetType().Name.Contains("Access")) + { + return 150; + } + else if (this.Context is OracleExpressionContext) + { + + return 401; + } + else + { + return 490; + } + } + } + + + public string GetValue(Expression expression) + { + var numExp = (expression as MethodCallExpression).Arguments[0]; + var num = 1; + if (ExpressionTool.GetParameters(numExp).Count != 0) + { + var copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + copyContext.Resolve(numExp, ResolveExpressType.WhereMultiple); + copyContext.Result.GetString(); + } + else + { + num = ExpressionTool.DynamicInvoke(numExp).ObjToInt(); + } + var take = (expression as MethodCallExpression); + if (this.Context is SqlServerExpressionContext || this.Context.GetType().Name.Contains("Access")) + { + return "TOP " + num; + } + else if (this.Context is OracleExpressionContext) + { + return (HasWhere ? "AND" : "WHERE") + " ROWNUM<=" + num; + } + else if (this.Context is PostgreSQLExpressionContext || this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.PostgreSQL) + { + return "limit " + num; + } + else if (this.Context.GetLimit() != null) + { + return this.Context.GetLimit(); + } + else + { + return "limit " + num; + } + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubToList.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubToList.cs new file mode 100644 index 000000000..e9ce548f6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubToList.cs @@ -0,0 +1,210 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubToList : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "ToList"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + var exp = expression as MethodCallExpression; + if (IsAutoGeneric(exp)) return GetValueByAuto(exp); + if (IsAutoSelect(exp)) return GetValueByAuto(exp); + InitType(exp); + var type = expression.Type; + if (type.FullName.IsCollectionsList() + && exp.Arguments.Count == 0 && type.GenericTypeArguments.Length > 0 + && this.Context.SugarContext?.QueryBuilder.IsSelectNoAll == true) + { + var entity = type.GenericTypeArguments[0]; + var columnNames = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(entity).Columns.Where(it => it.IsIgnore == false); + var columnsString = string.Join(",", columnNames + .Where(it => it.IsIgnore == false) + .Where(it => it.DbColumnName.HasValue()) + .Select(it => this.Context.GetTranslationColumnName(it.DbColumnName))); + return $"{columnsString},@sugarIndex as sugarIndex"; + } + else if (exp.Arguments.Count == 0) + { + return "*,@sugarIndex as sugarIndex"; + } + var argExp = exp.Arguments[0]; + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + var copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + copyContext.Resolve(argLambda, ResolveExpressType.SelectMultiple); + var select = copyContext.Result.GetString(); + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + SetShortName(exp, null); + return select + ",@sugarIndex as sugarIndex"; + } + + private void InitType(MethodCallExpression exp) + { + if (exp.Arguments.Count > 0) + { + foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(arg.Type); + this.Context.RefreshMapping(); + } + } + } + } + + public void SetShortName(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count != 0 && exp.Arguments[0] is LambdaExpression) + { + var parameters = (exp.Arguments[0] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + public void SetShortNameNext(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression) + { + var parameters = (exp.Arguments[1] as LambdaExpression).Parameters; + if (parameters?.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + + private string GetValueByAuto(MethodCallExpression exp) + { + var selectExp = exp.Arguments.FirstOrDefault(); + if (selectExp == null) + { + var type = exp.Type.GenericTypeArguments[0]; + var parameter = Expression.Parameter(type, "it"); + + // 构造返回值表达式 + var body = Expression.MemberInit(Expression.New(type)); + + // 将返回值表达式作为lambda表达式的主体 + selectExp = Expression.Lambda(body, parameter); + + } + var bodyExp = ExpressionTool.GetLambdaExpressionBody(selectExp); + var newMemExp = (bodyExp as MemberInitExpression); + var parameters = ExpressionTool.GetParameters(exp); + InitType(exp); + if (parameters.Count != 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters.FirstOrDefault().Name); + } + Check.ExceptionEasy(newMemExp == null, $"Subquery ToList(exp,true) expression {exp.ToString()} can only be it=>new class(){{Id = it.id}}", $"子查询ToList(exp,true)表达式{exp.ToString()}只能是it=>new class(){{ id=it.Id}}"); + var dic = ExpressionTool.GetMemberBindingItemList(newMemExp.Bindings); + var db = this.Context.SugarContext.Context; + var builder = this.Context.SugarContext.QueryBuilder.Builder; + var columnInfos = db.EntityMaintenance.GetEntityInfo(bodyExp.Type); + var autoColumns = columnInfos.Columns + .Where(it => !dic.ContainsKey(it.PropertyName)) + .Where(it => it.IsIgnore == false) + .ToList(); + List appendColumns = new List(); + List completeColumnColumns = new List(); + foreach (var item in autoColumns) + { + + foreach (var parameter in parameters) + { + var parameterColumns = db.EntityMaintenance.GetEntityInfo(parameter.Type).Columns.Where(it => it.IsIgnore == false); + if (!completeColumnColumns.Any(it => it.EqualCase(item.PropertyName)) && parameterColumns.Any(it => it.PropertyName.EqualCase(item.PropertyName))) + { + var completeColumn = parameterColumns.First(it => it.PropertyName.EqualCase(item.PropertyName)); + var shortName = builder.GetTranslationColumnName(parameter.Name); + var columnName = builder.GetTranslationColumnName(completeColumn.DbColumnName); + var asName = builder.SqlTranslationLeft + item.PropertyName + builder.SqlTranslationRight; + appendColumns.Add($"{shortName}.{columnName} as {asName}"); + completeColumnColumns.Add(completeColumn.PropertyName); + } + } + } + var copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + copyContext.Resolve(bodyExp, ResolveExpressType.SelectMultiple); + var select = copyContext.Result.GetString(); + if (dic.Count > 0 && appendColumns.Count == 0) + { + select = AppendParameter(copyContext, select); + return select + ",@sugarIndex as sugarIndex"; ; + } + else if (dic.Count > 0 && appendColumns.Count > 0) + { + select = AppendParameter(copyContext, select); + return select + "," + string.Join(",", appendColumns) + ",@sugarIndex as sugarIndex"; ; + } + else + { + return string.Join(",", appendColumns) + ",@sugarIndex as sugarIndex"; + } + } + + private string AppendParameter(ExpressionContext copyContext, string select) + { + if (copyContext.Parameters?.Count > 0) + { + this.Context.Parameters.AddRange(copyContext.Parameters); + select = select.Replace("), AS", ") AS"); + } + return select; + } + + private static bool IsAutoSelect(MethodCallExpression exp) + { + return exp.Arguments.Count == 2 && exp.Arguments.Last().Type == UtilConstants.BoolType; + } + private static bool IsAutoGeneric(MethodCallExpression exp) + { + return exp.Arguments.Count == 0 && exp.Method.GetGenericArguments().Length == 1; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubTop.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubTop.cs new file mode 100644 index 000000000..892da2092 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubTop.cs @@ -0,0 +1,75 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubTop : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "Top"; + } + } + + public int Sort + { + get + { + if (this.Context is SqlServerExpressionContext || this.Context.GetType().Name.Contains("Access")) + { + return 150; + } + else if (this.Context is OracleExpressionContext) + { + + return 401; + } + else + { + return 490; + } + } + } + + + public string GetValue(Expression expression) + { + if (this.Context is SqlServerExpressionContext || this.Context.GetType().Name.Contains("Access")) + { + return "TOP 1"; + } + else if (this.Context is OracleExpressionContext) + { + return (HasWhere ? "AND" : "WHERE") + " ROWNUM=1"; + } + else if (this.Context is PostgreSQLExpressionContext || this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.PostgreSQL) + { + return "limit 1"; + } + else if (this.Context.GetLimit() != null) + { + return this.Context.GetLimit(); + } + else + { + return "limit 0,1"; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWhere.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWhere.cs new file mode 100644 index 000000000..e62eba212 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWhere.cs @@ -0,0 +1,128 @@ +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SubWhere : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "Where"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 400; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + if (Regex.Matches(expression.ToString(), "Subqueryable").Count >= 2) + { + new SubSelect() { Context = this.Context }.SetShortName(exp, "+"); + } + var argExp = exp.Arguments[0]; + if (ExpressionTool.GetMethodName(argExp) == "ToExpression") + { + argExp = ExpressionTool.DynamicInvoke(argExp) as Expression; + } + var copyContext = this.Context; + var pars = ExpressionTool.GetParameters(expression).Distinct(); + if (this.Context.JoinIndex > 0 || pars.Count() > 1) + { + copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + } + var result = "WHERE " + SubTools.GetMethodValue(copyContext, argExp, ResolveExpressType.WhereMultiple); + if (argExp.Type == typeof(List) && this.Context.Parameters.Count != 0) + { + var p = this.Context.Parameters.Last(); + this.Context.Parameters.Remove(p); + var cols = p.Value as List; + var sqlObj = this.Context.SugarContext.QueryBuilder.Builder.ConditionalModelToSql(cols, this.Context.ParameterIndex * 100); + this.Context.ParameterIndex = this.Context.ParameterIndex + this.Context.ParameterIndex * 100; + result = "WHERE " + sqlObj.Key; + this.Context.Parameters.AddRange(sqlObj.Value); + return result; + } + else if (argExp.Type == typeof(List) && this.Context.Parameters.Count == 0) + { + var cols = ExpressionTool.DynamicInvoke(((expression as MethodCallExpression).Arguments[0])) as List; + var sqlObj = this.Context.SugarContext.QueryBuilder.Builder.ConditionalModelToSql(cols, this.Context.ParameterIndex * 100); + this.Context.ParameterIndex = this.Context.ParameterIndex + this.Context.ParameterIndex * 100; + result = "WHERE " + sqlObj.Key; + this.Context.Parameters.AddRange(sqlObj.Value); + return result; + } + if (this.Context.JoinIndex > 0 || pars.Count() > 1) + { + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + } + + var regex = @"^WHERE (\@Const\d+) $"; + if (this.Context is OracleExpressionContext) + { + regex = @"^WHERE (\:Const\d+) $"; + } + if (this.Context is DmExpressionContext) + { + regex = @"^WHERE (\:Const\d+) $"; + } + if (Regex.IsMatch(result, regex)) + { + var value = GetValue(result, regex); + if (value is Expression) + { + var p = this.Context.Parameters.First(it => it.ParameterName == Regex.Match(result, regex).Groups[1].Value); + result = "WHERE " + SubTools.GetMethodValue(Context, value as Expression, ResolveExpressType.WhereMultiple); + argExp = value as Expression; + this.Context.Parameters.Remove(p); + } + else + { + result = "WHERE " + value; + return result; + } + } + + var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0 && result.Contains(" FROM ")) + { + this.Context.CurrentShortName = selfParameterName.ObjToString().TrimEnd('.'); + } + else if (this.Context.JoinIndex == 0 && this.Context.CurrentShortName != selfParameterName.TrimEnd('.')) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + if (!string.IsNullOrEmpty(selfParameterName) && this.Context.IsSingle && this.Context.JoinIndex == 0) + { + this.Context.CurrentShortName = selfParameterName.TrimEnd('.'); + } + return result; + } + + private object GetValue(string result, string regex) + { + return this.Context.Parameters.First(it => it.ParameterName == Regex.Match(result, regex).Groups[1].Value).Value; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWhereIF.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWhereIF.cs new file mode 100644 index 000000000..736690d2d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWhereIF.cs @@ -0,0 +1,81 @@ +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SubWhereIF : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get { return "WhereIF"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 400; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + object value = null; + try + { + value = ExpressionTool.DynamicInvoke(exp.Arguments[0]); + } + catch + { + Check.Exception(true, ErrorMessage.WhereIFCheck, exp.Arguments[0].ToString()); + } + if (Regex.Matches(expression.ToString(), "Subqueryable").Count >= 2) + { + new SubSelect() { Context = this.Context }.SetShortNameNext(exp, "+"); + } + var isWhere = Convert.ToBoolean(value); + if (!Convert.ToBoolean(isWhere)) + { + return "WHERE 1=1 "; + } + var argExp = exp.Arguments[1]; + var copyContext = this.Context; + if (this.Context.JoinIndex > 0) + { + copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.IsSingle = false; + } + var result = "WHERE " + SubTools.GetMethodValue(copyContext, argExp, ResolveExpressType.WhereMultiple); + if (this.Context.JoinIndex > 0) + { + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + } + var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + if (this.Context.JoinIndex == 0) + result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context)); + if (!string.IsNullOrEmpty(selfParameterName) && this.Context.IsSingle && this.Context.JoinIndex == 0) + { + this.Context.CurrentShortName = selfParameterName.TrimEnd('.'); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWithNoLock.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWithNoLock.cs new file mode 100644 index 000000000..9222972a2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Items/SubWithNoLock.cs @@ -0,0 +1,50 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SubWithNolock : ISubOperation + { + public ExpressionContext Context + { + get; set; + } + + public Expression Expression + { + get; set; + } + + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "WithNoLock"; + } + } + + public int Sort + { + get + { + return 301; + } + } + + public string GetValue(Expression expression) + { + if (Context is SqlServerExpressionContext) + { + return SqlWith.NoLock; + } + else + { + return ""; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubResolve.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubResolve.cs new file mode 100644 index 000000000..ea98fbcfd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubResolve.cs @@ -0,0 +1,326 @@ +using System.Linq.Expressions; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + /// + /// ** description:Get subquery sql + /// ** author:sunkaixuan + /// ** date:2017/9/17 + /// ** email:610262374@qq.com + /// + public class SubResolve + { + List allMethods = new List(); + private ExpressionContext context = null; + private string subKey = "$SubAs:"; + private bool hasWhere; + private bool isXmlPath = false; + private bool isAsAttr = false; + public SubResolve(MethodCallExpression expression, ExpressionContext context, Expression oppsiteExpression) + { + this.context = context; + var currentExpression = expression; + allMethods.Add(currentExpression); + if (context.IsSingle && oppsiteExpression != null && oppsiteExpression is MemberExpression) + { + var childExpression = (oppsiteExpression as MemberExpression).Expression; + if (childExpression is ParameterExpression) + this.context.SingleTableNameSubqueryShortName = (childExpression as ParameterExpression).Name; + else + { + this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name; + } + } + else if (context.IsSingle && ExpressionTool.GetMethodName(currentExpression) != "ToList") + { + if (context.Expression is LambdaExpression) + { + this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name; + } + else if (context.Expression is MethodCallExpression) + { + var expArgs = ((context.Expression as MethodCallExpression).Object as MethodCallExpression).Arguments; + if (expArgs != null && expArgs.Count != 0) + { + var meExp = expArgs[0] as LambdaExpression; + if (meExp != null) + { + var selfParameterName = meExp.Parameters.First().Name; + if ((meExp.Body is BinaryExpression)) + { + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Left as MemberExpression)?.Expression as ParameterExpression)?.Name; + } + if (ExpressionTool.GetMethodName(context.Expression).IsContainsIn("ToList") && meExp.Parameters.Any(it => it.Name == selfParameterName)) + { + if (meExp.Body is BinaryExpression) + { + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Right as MemberExpression)?.Expression as ParameterExpression)?.Name; + } + } + if (context.SingleTableNameSubqueryShortName == selfParameterName) + { + if (meExp.Body is BinaryExpression) + { + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Right as MemberExpression)?.Expression as ParameterExpression)?.Name; + } + } + } + } + } + else if (context.Expression.GetType().Name == "MethodBinaryExpression") + { + + var subExp = (context.Expression as BinaryExpression).Left is MethodCallExpression ? (context.Expression as BinaryExpression).Left : (context.Expression as BinaryExpression).Right; + if (subExp is MethodCallExpression) + { + var meExp = ((subExp as MethodCallExpression).Object as MethodCallExpression).Arguments[0] as LambdaExpression; + var selfParameterName = meExp.Parameters.First().Name; + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Left as MemberExpression).Expression as ParameterExpression).Name; + if (context.SingleTableNameSubqueryShortName == selfParameterName) + { + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Right as MemberExpression).Expression as ParameterExpression).Name; + } + } + } + else if (context.RootExpression != null && context.Expression.GetType().Name == "SimpleBinaryExpression") + { + var name = (this.context.RootExpression as LambdaExpression).Parameters[0].Name; + context.SingleTableNameSubqueryShortName = name; + } + else if (context.Expression is BinaryExpression) + { + var subExp = (context.Expression as BinaryExpression).Left is MethodCallExpression ? (context.Expression as BinaryExpression).Left : (context.Expression as BinaryExpression).Right; + if (subExp is MethodCallExpression) + { + var argus = ((subExp as MethodCallExpression).Object as MethodCallExpression).Arguments; + if (argus.Count > 0) + { + var meExp = argus[0] as LambdaExpression; + var selfParameterName = meExp.Parameters.First().Name; + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Left as MemberExpression)?.Expression as ParameterExpression)?.Name; + if (context.SingleTableNameSubqueryShortName == selfParameterName) + { + context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Right as MemberExpression).Expression as ParameterExpression).Name; + } + } + } + } + else if (context.Expression is MemberInitExpression memberInitExpression) + { + var getParameters = ExpressionTool.GetParameters(context.Expression).Select(it => it.Name).Distinct().ToList(); + if (getParameters?.Count > 1) + { + context.SingleTableNameSubqueryShortName = getParameters.First(); + } + } + else + { + Check.ExceptionEasy("I'm sorry I can't parse the current expression", "不支持当前表达式"); + } + } + var subIndex = this.context.SubQueryIndex; + while (currentExpression != null) + { + var addItem = currentExpression.Object as MethodCallExpression; + if (addItem != null) + allMethods.Add(addItem); + if (subIndex == this.context.SubQueryIndex && addItem?.Arguments.HasValue() == true && addItem.Arguments.Any(it => it.ToString().Contains("Subqueryable()"))) + { + this.context.SubQueryIndex++; + } + currentExpression = addItem; + } + } + public string GetSql() + { + List subItems = GetSubItems(); + var sqlItems = subItems.Where(it => !it.StartsWith(subKey)).ToList(); + var asItems = subItems.Where(it => it.StartsWith(subKey)).ToList(); + if (asItems.Count != 0) + { + GetSubAs(sqlItems, asItems); + } + if (this.context.CurrentShortName.HasValue()) + { + GetShortName(sqlItems); + } + var sql = ""; + + if (sqlItems.Count(it => IsJoin(it)) > 1) + { + var index = sqlItems.IndexOf(sqlItems.First(x => IsJoin(x))); + var joinitems = sqlItems.Where(it => IsJoin(it)).ToList(); + joinitems.Reverse(); + var items = sqlItems.Where(it => !IsJoin(it)).ToList(); + items.InsertRange(index, joinitems); + sql = string.Join(UtilConstants.Space, items); + } + else + { + sql = string.Join(UtilConstants.Space, sqlItems); + } + if (isXmlPath) + { + var xmlPath = context.DbMehtods.GetForXmlPath(); + if (xmlPath.HasValue()) + { + sql = sql + xmlPath; + } + } + return this.context.DbMehtods.Pack(sql); + } + + private static bool IsJoin(string it) + { + return it.StartsWith(" INNER JOIN") || it.StartsWith(" LEFT JOIN"); + } + + private void GetSubAs(List sqlItems, List asItems) + { + for (int i = 0; i < sqlItems.Count; i++) + { + if (sqlItems[i].StartsWith("FROM " + this.context.SqlTranslationLeft)) + { + var asName = this.context.GetTranslationTableName(asItems.First().Replace(subKey, ""), false); + var repKey = $"\\{this.context.SqlTranslationLeft}.+\\{this.context.SqlTranslationRight}"; + if (this.context.IsSingle && this.context.JoinIndex == 0 && this.context.CurrentShortName.HasValue() && isAsAttr && !asName.Contains(this.context.CurrentShortName)) + { + asName = asName + " " + this.context.CurrentShortName + " "; + } + sqlItems[i] = Regex.Replace(sqlItems[i], repKey, asName); + } + } + } + private void GetShortName(List sqlItems) + { + for (int i = 0; i < sqlItems.Count; i++) + { + if (sqlItems[i].StartsWith("FROM " + this.context.SqlTranslationLeft)) + { + if (isAsAttr && sqlItems[i].EndsWith(this.context.CurrentShortName + " ")) + { + } + else + { + sqlItems[i] = sqlItems[i] + " " + this.context.CurrentShortName + " "; + } + } + } + } + + private List GetSubItems() + { + var isSubSubQuery = this.allMethods.Select(it => it.ToString()).Any(it => Regex.Matches(it, "Subquery").Count > 1); + var isubList = this.allMethods.Select(exp => + { + if (isSubSubQuery) + { + this.context.JoinIndex = 1; + this.context.SubQueryIndex = 0; + } + var methodName = exp.Method.Name; + var items = SubTools.SubItems(this.context); + var item = items.First(s => s.Name == methodName); + if (item is SubWhere && hasWhere == false) + { + hasWhere = true; + } + else if (item is SubWhere) + { + item = items.First(s => s is SubAnd); + } + + if (item is SubWhereIF && hasWhere == false) + { + hasWhere = true; + } + else if (item is SubWhereIF) + { + item = items.First(s => s is SubAndIF); + } + else if (item is SubSelectStringJoin) + { + isXmlPath = true; + } + else if (item is SubAsWithAttr) + { + isAsAttr = true; + } + + item.Context = this.context; + item.Expression = exp; + return item; + }).ToList(); + SetOrderByIndex(isubList); + isubList.Insert(0, new SubBegin()); + if (isubList.Any(it => it is SubSelect || it is SubFirst)) + { + isubList.Add(new SubTop() { Context = this.context }); + } + if (isubList.Any(it => it is SubAny || it is SubNotAny)) + { + isubList.Add(new SubLeftBracket()); + isubList.Add(new SubRightBracket()); + isubList.Add(new SubSelectDefault()); + } + var db = this.context?.SugarContext?.Context; + if (db != null && db?.CurrentConnectionConfig?.DbType == DbType.SqlServer) + { + if (db.CurrentConnectionConfig?.MoreSettings?.IsWithNoLockSubquery == true) + { + if (!isubList.Any(it => it is SubWithNolock)) + { + isubList.Add(new SubWithNolock() { Context = this.context }); + } + } + } + isubList = isubList.OrderBy(it => it.Sort).ToList(); + var isHasWhere = isubList.Where(it => it is SubWhere).Any(); + var isJoin = isubList.Any(it => it is SubInnerJoin || it is SubLeftJoin); + if (isJoin) + { + this.context.JoinIndex++; + } + if (isAsAttr) + { + this.context.IsAsAttr = true; + } + if (isubList.Any(it => it is SubSelect) && isubList.Any(it => it is SubTake)) + { + isubList.RemoveAll(it => it is SubTake); + } + List result = isubList.Select(it => + { + it.HasWhere = isHasWhere; + return it.GetValue(it.Expression); + }).ToList(); + this.context.JoinIndex = 0; + this.context.IsAsAttr = false; + return result; + } + + private static void SetOrderByIndex(List isubList) + { + var orderByIndex = 0; + var orderByList = isubList.Where(it => it is SubOrderBy || it is SubOrderByDesc).ToList(); + if (orderByList.Count > 1) + { + orderByList.Reverse(); + foreach (var item in orderByList) + { + if (item is SubOrderBy) + { + (item as SubOrderBy).OrderIndex = orderByIndex; + orderByIndex++; + } + else if (item is SubOrderByDesc) + { + (item as SubOrderByDesc).OrderIndex = orderByIndex; + orderByIndex++; + } + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubTemplate.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubTemplate.cs new file mode 100644 index 000000000..9f59b55cb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubTemplate.cs @@ -0,0 +1,40 @@ +//@{ +// var count = 9; +// var T = ""; +// var Tn = ""; +// for (int i = 0; i < count; i++) +// { +// T += "T" + (i + 1) + ","; +// } +// Tn = T + "JoinType"; +// T = T.TrimEnd(','); +//} +//public class Subqueryable<@T> : Subqueryable where T1 : class, new() +//{ +// public Subqueryable<@Tn> InnerJoin(Func<@Tn, bool> expression) +// { +// return new Subqueryable<@Tn>(); +// } +// public Subqueryable<@Tn> LeftJoin(Func<@Tn, bool> expression) +// { +// return new Subqueryable<@Tn>(); +// } +// @for(int i = 0; i Where(Func<@wtn, bool> expression) +// @:{ +// @:return this; +// @:} + +//} +//} + diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubTools.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubTools.cs new file mode 100644 index 000000000..0cccecf90 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubTools.cs @@ -0,0 +1,91 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public static class SubTools + { + public static List SubItems(ExpressionContext Context) + { + + return new List() + { + new SubSelect() { Context=Context }, + new SubWhere(){ Context=Context }, + new SubWhereIF(){ Context=Context }, + new SubLeftJoin(){ Context=Context }, + new SubInnerJoin(){ Context=Context }, + new SubAnd(){ Context=Context }, + new SubAndIF(){ Context=Context }, + new SubAny(){ Context=Context }, + new SubNotAny(){ Context=Context }, + new SubBegin(){ Context=Context }, + new SubFromTable(){ Context=Context }, + new SubCount(){ Context=Context }, + new SubMax(){ Context=Context }, + new SubMin(){ Context=Context }, + new SubSum(){ Context=Context }, + new SubAvg(){ Context=Context }, + new SubOrderBy(){ Context=Context }, + new SubOrderByDesc(){ Context=Context }, + new SubGroupBy(){ Context=Context}, + new SubAs(){Context=Context}, + new SubHaving(){ Context=Context}, + new SubWithNolock(){ Context=Context }, + new SubEnableTableFilter(){ Context=Context }, + new SubSelectStringJoin{ Context=Context }, + new SubDistinctCount{ Context=Context }, + new SubToList{ Context=Context}, + new SubFirst(){ Context=Context }, + new SubAsWithAttr(){ Context=Context }, + new SubTake(){ Context=Context } + }; + } + + public static string GetSubReplace(ExpressionContext context) + { + if (context.SubQueryIndex == 0) + return string.Empty; + else + return "subTableIndex" + context.SubQueryIndex + "."; + } + + public static List SubItemsConst = SubItems(null); + + public static string GetMethodValue(ExpressionContext context, Expression item, ResolveExpressType type) + { + var newContext = context.GetCopyContext(); + newContext.MappingColumns = context.MappingColumns; + newContext.MappingTables = context.MappingTables; + newContext.InitMappingInfo = context.InitMappingInfo; + newContext.RefreshMapping = context.RefreshMapping; + newContext.IgnoreComumnList = context.IgnoreComumnList; + newContext.SqlFuncServices = context.SqlFuncServices; + newContext.Resolve(item, type); + context.Index = newContext.Index; + context.ParameterIndex = newContext.ParameterIndex; + if (newContext.Parameters.HasValue()) + context.Parameters.AddRange(newContext.Parameters); + return newContext.Result.GetResultString(); + } + public static string GetMethodValueSubJoin(ExpressionContext context, Expression item, ResolveExpressType type) + { + var newContext = context.GetCopyContext(); + newContext.MappingColumns = context.MappingColumns; + newContext.MappingTables = context.MappingTables; + newContext.InitMappingInfo = context.InitMappingInfo; + newContext.RefreshMapping = context.RefreshMapping; + newContext.IgnoreComumnList = context.IgnoreComumnList; + newContext.SqlFuncServices = context.SqlFuncServices; + if (type == ResolveExpressType.WhereMultiple || type == ResolveExpressType.FieldMultiple) + { + newContext.IsSingle = false; + } + newContext.Resolve(item, type); + context.Index = newContext.Index; + context.ParameterIndex = newContext.ParameterIndex; + if (newContext.Parameters.HasValue()) + context.Parameters.AddRange(newContext.Parameters); + return newContext.Result.GetResultString(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Subquerable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Subquerable.cs new file mode 100644 index 000000000..7d62a74be --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/Subquerable.cs @@ -0,0 +1,229 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class Subqueryable where T : class, new() + { + + public Subqueryable AS(string tableName) + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + + + public Subqueryable Where(string where) + { + return this; + } + public Subqueryable Where(List conditionals) + { + return this; + } + public Subqueryable Where(Expression exp) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Having(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable WhereIF(bool isWhere, Func expression) + { + return this; + } + public Subqueryable OrderBy(Func expression) + { + return this; + } + public Subqueryable GroupBy(Func expression) + { + return this; + } + public Subqueryable OrderByDesc(Func expression) + { + return this; + } + + public TResult Select(Func expression) + { + return default(TResult); + } + public Byte[] Select(Func expression) + { + return null; + } + public string Select(Func expression) + { + return default(string); + } + + public string SelectStringJoin(Func expression, string separator) + { + return default(string); + } + + public TResult Max(Func expression) + { + return default(TResult); + } + public Byte[] Max(Func expression) + { + return null; + } + public string Max(Func expression) + { + return default(string); + } + + public string Min(Func expression) + { + return default(string); + } + public TResult Min(Func expression) + { + return default(TResult); + } + public Byte[] Min(Func expression) + { + return null; + } + + + public string Sum(Func expression) + { + return default(string); + } + + public int DistinctCount(Func expression) + { + return default(int); + } + public TResult Sum(Func expression) + { + return default(TResult); + } + public Byte[] Sum(Func expression) + { + return null; + } + + public string Avg(Func expression) + { + return default(string); + } + public TResult Avg(Func expression) where TResult : struct + { + return default(TResult); + } + public Byte[] Avg(Func expression) + { + return null; + } + + public bool Any() + { + return default(bool); + } + + public bool NotAny() + { + return default(bool); + } + + public int Count() + { + return default(int); + } + + public Subqueryable WithNoLock() + { + return this; + } + public Subqueryable EnableTableFilter() + { + return this; + } + + public List ToList() + { + return new List(); + } + public List ToList(Func selector) + { + return null; + } + public List ToList() + { + return null; + } + public List ToList(Func selector, bool isAutoDto) where TResult : class, new() + { + return null; + } + public T First() + { + return default(T); + } + public TResult First(Func selector) where TResult : class, new() + { + return default(TResult); + } + public TResult First(Func selector, bool isAutoDto) where TResult : class, new() + { + return default(TResult); + } + public TResult First() where TResult : class, new() + { + return default(TResult); + } + + public Subqueryable AsWithAttr() + { + return this; + } + + public Subqueryable Take(int takeNum) + { + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubqueryableN.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubqueryableN.cs new file mode 100644 index 000000000..25a43bfc4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExpressionsToSql/Subquery/SubqueryableN.cs @@ -0,0 +1,695 @@ +namespace SqlSugar +{ + public class Subqueryable : Subqueryable where T1 : class, new() + { } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public new Subqueryable AsWithAttr() + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public List ToList(Func selector) + { + return null; + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public new Subqueryable AsWithAttr() + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public List ToList(Func selector) + { + return null; + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public new Subqueryable AsWithAttr() + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public List ToList(Func selector) + { + return null; + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public string SelectStringJoin(Func expression, string separator) + { + return default(string); + } + public new Subqueryable AsWithAttr() + { + return this; + } + public new Subqueryable Where(List conditionals) + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public List ToList(Func selector) + { + return null; + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public string SelectStringJoin(Func expression, string separator) + { + return default(string); + } + public new Subqueryable AsWithAttr() + { + return this; + } + public new Subqueryable Where(List conditionals) + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public List ToList(Func selector) + { + return null; + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public new Subqueryable AsWithAttr() + { + return this; + } + public new Subqueryable Where(List conditionals) + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable WhereIF(bool isWhere, Func expression) + { + return this; + } + public TResult Select(Func expression) where TResult : struct + { + return default(TResult); + } + public string Select(Func expression) + { + return default(string); + } + public Subqueryable OrderBy(Func expression) + { + return this; + } + public Subqueryable OrderByDesc(Func expression) + { + return this; + } + public Subqueryable GroupBy(Func expression) + { + return this; + } + public string SelectStringJoin(Func expression, string separator) + { + return default(string); + } + public List ToList(Func selector) + { + return null; + } + public List ToList(Func selector, bool isAutoDto) where TResult : class, new() + { + return null; + } + public TResult First(Func selector, bool isAutoDto) where TResult : class, new() + { + return default(TResult); + } + public TResult Max(Func expression) + { + return default(TResult); + } + public Byte[] Max(Func expression) + { + return null; + } + public string Max(Func expression) + { + return default(string); + } + + public string Min(Func expression) + { + return default(string); + } + public TResult Min(Func expression) + { + return default(TResult); + } + public Byte[] Min(Func expression) + { + return null; + } + public string Sum(Func expression) + { + return default(string); + } + public TResult Sum(Func expression) + { + return default(TResult); + } + + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public new Subqueryable AsWithAttr() + { + return this; + } + public new Subqueryable Where(List conditionals) + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable WhereIF(bool isWhere, Func expression) + { + return this; + } + public Subqueryable OrderBy(Func expression) + { + return this; + } + public Subqueryable OrderBy(Func expression) + { + return this; + } + public new Subqueryable OrderBy(Func expression) + { + return this; + } + public Subqueryable OrderByDesc(Func expression) + { + return this; + } + public Subqueryable OrderByDesc(Func expression) + { + return this; + } + public new Subqueryable OrderByDesc(Func expression) + { + return this; + } + public Subqueryable GroupBy(Func expression) + { + return this; + } + public Subqueryable GroupBy(Func expression) + { + return this; + } + public new Subqueryable GroupBy(Func expression) + { + return this; + } + public TResult Select(Func expression) where TResult : struct + { + return default(TResult); + } + public string Select(Func expression) + { + return default(string); + } + public string SelectStringJoin(Func expression, string separator) + { + return default(string); + } + public List ToList(Func selector) + { + return null; + } + public List ToList(Func selector, bool isAutoDto) where TResult : class, new() + { + return null; + } + public TResult First(Func selector, bool isAutoDto) where TResult : class, new() + { + return default(TResult); + } + public TResult Max(Func expression) + { + return default(TResult); + } + public Byte[] Max(Func expression) + { + return null; + } + public string Max(Func expression) + { + return default(string); + } + + public string Min(Func expression) + { + return default(string); + } + public TResult Min(Func expression) + { + return default(TResult); + } + public Byte[] Min(Func expression) + { + return null; + } + public string Sum(Func expression) + { + return default(string); + } + public TResult Sum(Func expression) + { + return default(TResult); + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } + public class Subqueryable : Subqueryable where T1 : class, new() + { + public new Subqueryable AsWithAttr() + { + return this; + } + public new Subqueryable Where(List conditionals) + { + return this; + } + public Subqueryable InnerJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression) + { + return new Subqueryable(); + } + public Subqueryable InnerJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public Subqueryable LeftJoin(Func expression, string tableName) + { + return new Subqueryable(); + } + public new Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable Where(Func expression) + { + return this; + } + public Subqueryable OrderBy(Func expression) + { + return this; + } + public new Subqueryable OrderBy(Func expression) + { + return this; + } + public Subqueryable OrderByDesc(Func expression) + { + return this; + } + public new Subqueryable OrderByDesc(Func expression) + { + return this; + } + public Subqueryable GroupBy(Func expression) + { + return this; + } + public new Subqueryable GroupBy(Func expression) + { + return this; + } + public Subqueryable WhereIF(bool isWhere, Func expression) + { + return this; + } + public TResult Select(Func expression) where TResult : struct + { + return default(TResult); + } + public string Select(Func expression) + { + return default(string); + } + public string SelectStringJoin(Func expression, string separator) + { + return default(string); + } + public List ToList(Func selector) + { + return null; + } + public List ToList(Func selector, bool isAutoDto) where TResult : class, new() + { + return null; + } + public TResult First(Func selector, bool isAutoDto) where TResult : class, new() + { + return default(TResult); + } + public TResult Max(Func expression) + { + return default(TResult); + } + public Byte[] Max(Func expression) + { + return null; + } + public string Max(Func expression) + { + return default(string); + } + + public string Min(Func expression) + { + return default(string); + } + public TResult Min(Func expression) + { + return default(TResult); + } + public Byte[] Min(Func expression) + { + return null; + } + public string Sum(Func expression) + { + return default(string); + } + public TResult Sum(Func expression) + { + return default(TResult); + } + public new Subqueryable Take(int takeNum) + { + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ICacheService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ICacheService.cs new file mode 100644 index 000000000..753a8a801 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ICacheService.cs @@ -0,0 +1,13 @@ +namespace SqlSugar +{ + public interface ICacheService + { + void Add(string key, V value); + void Add(string key, V value, int cacheDurationInSeconds); + bool ContainsKey(string key); + V Get(string key); + IEnumerable GetAllKey(); + void Remove(string key); + V GetOrCreate(string cacheKey, Func create, int cacheDurationInSeconds = int.MaxValue); + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/IRazorService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/IRazorService.cs new file mode 100644 index 000000000..7f79bbad5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/IRazorService.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public interface IRazorService + { + List> GetClassStringList(string razorTemplate, List model); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ISerializeService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ISerializeService.cs new file mode 100644 index 000000000..c86448bf8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ISerializeService.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public interface ISerializeService + { + string SerializeObject(object value); + string SugarSerializeObject(object value); + T DeserializeObject(string value); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ISplitTableService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ISplitTableService.cs new file mode 100644 index 000000000..1cfcd9e48 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/ExternalServiceInterface/ISplitTableService.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + public interface ISplitTableService + { + List GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List tableInfos); + string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo); + string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo, SplitType type); + string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue); + object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/ContextMethods.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/ContextMethods.cs new file mode 100644 index 000000000..4471ade7d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/ContextMethods.cs @@ -0,0 +1,1282 @@ +using Newtonsoft.Json.Linq; + +using System.Collections; +using System.Data; +using System.Data.Common; +using System.Dynamic; +using System.Linq.Expressions; +using System.Reflection; +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public partial class ContextMethods : IContextMethods + { + public SqlSugarProvider Context { get; set; } + public QueryBuilder QueryBuilder { get; set; } + + #region DataReader + public List DataReaderToValueTupleType(IDataReader reader) + { + var result = new List(); + + // Get the property names and types dynamically + var propertyNames = Enumerable.Range(0, reader.FieldCount) + .Select(reader.GetName).ToList(); + var propertyTypes = Enumerable.Range(0, reader.FieldCount) + .Select(reader.GetFieldType).ToList(); + + using (reader) + { + while (reader.Read()) + { + // Create a new instance of the tuple type using the property types + var tupleType = typeof(T); + var tupleInstance = Activator.CreateInstance(tupleType); + + // Set the property values dynamically + for (int i = 0; i < reader.FieldCount; i++) + { + var propertyName = propertyNames[i]; + var propertyValue = reader.GetValue(i); + var propertyType = propertyTypes[i]; + + var propertyInfo = tupleType.GetFields()[i]; + propertyInfo.SetValue(tupleInstance, UtilMethods.ChangeType2(propertyValue, propertyInfo.FieldType)); + } + + // Add the tuple instance to the result list + result.Add((T)tupleInstance); + } + } + return result; + } + public async Task> DataReaderToValueTupleTypeAsync(IDataReader reader) + { + var result = new List(); + + // Get the property names and types dynamically + var propertyNames = Enumerable.Range(0, reader.FieldCount) + .Select(reader.GetName).ToList(); + var propertyTypes = Enumerable.Range(0, reader.FieldCount) + .Select(reader.GetFieldType).ToList(); + + using (reader) + { + while (await ((DbDataReader)reader).ReadAsync().ConfigureAwait(false)) + { + // Create a new instance of the tuple type using the property types + var tupleType = typeof(T); + var tupleInstance = Activator.CreateInstance(tupleType); + + // Set the property values dynamically + for (int i = 0; i < reader.FieldCount; i++) + { + var propertyName = propertyNames[i]; + var propertyValue = reader.GetValue(i); + var propertyType = propertyTypes[i]; + + var propertyInfo = tupleType.GetFields()[i]; + propertyInfo.SetValue(tupleInstance, Convert.ChangeType(propertyValue, propertyType)); + } + + // Add the tuple instance to the result list + result.Add((T)tupleInstance); + } + } + return result; + } + + + /// + ///DataReader to Dynamic + /// + /// + /// + public ExpandoObject DataReaderToExpandoObject(IDataReader reader) + { + ExpandoObject result = new ExpandoObject(); + var dic = ((IDictionary)result); + for (int i = 0; i < reader.FieldCount; i++) + { + try + { + var addItem = reader.GetValue(i); + if (addItem == DBNull.Value) + addItem = null; + dic.Add(reader.GetName(i), addItem); + } + catch + { + dic.Add(reader.GetName(i), null); + } + } + return result; + } + + /// + ///DataReader to Dynamic List + /// + /// + /// + public List DataReaderToExpandoObjectList(IDataReader reader) + { + using (reader) + { + List result = new List(); + if (reader?.IsClosed == false) + { + while (reader.Read()) + { + result.Add(DataReaderToExpandoObject(reader)); + } + } + return result; + } + } + /// + ///DataReader to Dynamic List + /// + /// + /// + public async Task> DataReaderToExpandoObjectListAsync(IDataReader reader) + { + using (reader) + { + List result = new List(); + if (reader?.IsClosed == false) + { + while (await ((DbDataReader)reader).ReadAsync().ConfigureAwait(false)) + { + result.Add(DataReaderToExpandoObject(reader)); + } + } + return result; + } + } + + + /// + ///DataReader to Dynamic List + /// + /// + /// + public List DataReaderToExpandoObjectListNoUsing(IDataReader reader) + { + List result = new List(); + if (reader?.IsClosed == false) + { + while (reader.Read()) + { + result.Add(DataReaderToExpandoObject(reader)); + } + } + return result; + } + + /// + ///DataReader to Dynamic List + /// + /// + /// + public async Task> DataReaderToExpandoObjectListAsyncNoUsing(IDataReader reader) + { + List result = new List(); + if (reader?.IsClosed == false) + { + while (await ((DbDataReader)reader).ReadAsync().ConfigureAwait(false)) + { + result.Add(DataReaderToExpandoObject(reader)); + } + } + return result; + } + + + /// + ///DataReader to DataReaderToDictionary + /// + /// + /// + public Dictionary DataReaderToDictionary(IDataReader reader) + { + Dictionary result = new Dictionary(); + for (int i = 0; i < reader.FieldCount; i++) + { + try + { + var addItem = reader.GetValue(i); + if (addItem == DBNull.Value) + addItem = null; + result.Add(reader.GetName(i), addItem); + } + catch + { + result.Add(reader.GetName(i), null); + } + } + return result; + } + + /// + ///DataReader to DataReaderToDictionary + /// + /// + /// + /// + public Dictionary DataReaderToDictionary(IDataReader reader, Type type) + { + Dictionary result = new Dictionary(); + for (int i = 0; i < reader.FieldCount; i++) + { + string name = reader.GetName(i); + try + { + name = this.Context.EntityMaintenance.GetPropertyName(name, type); + var addItem = reader.GetValue(i); + if (addItem == DBNull.Value) + addItem = null; + result.Add(name, addItem); + } + catch + { + if (!result.ContainsKey(name)) + { + result.Add(name, null); + } + } + } + return result; + } + + /// + /// DataReaderToList + /// + /// + /// + /// + public List DataReaderToList(IDataReader reader) + { + using (reader) + { + var tType = typeof(T); + var classProperties = tType.GetProperties() + .Where(p => p.GetIndexParameters().Length == 0).ToList(); + var reval = new List(); + if (reader?.IsClosed == false) + { + while (reader.Read()) + { + Dictionary result = DataReaderToList(reader, tType, classProperties, reval); + var stringValue = SerializeObject(result); + reval.Add((T)DeserializeObject(stringValue)); + SetAppendColumns(reader); + } + } + return reval; + } + } + + + public List DataReaderToSelectJsonList(IDataReader dataReader) + { + List result = new List(); + using (dataReader) + { + while (dataReader.Read()) + { + var value = dataReader.GetValue(0); + if (value == null || value == DBNull.Value) + { + result.Add(default(T)); + } + else + { + result.Add(Context.Utilities.DeserializeObject(value.ToString())); + } + } + } + + return result; + } + + public List DataReaderToSelectArrayList(IDataReader dataReader) + { + List result = new List(); + using (dataReader) + { + while (dataReader.Read()) + { + var value = dataReader.GetValue(0); + if (value == null || value == DBNull.Value) + { + result.Add(default(T)); + } + else + { + result.Add((T)value); + } + } + } + + return result; + } + /// + /// DataReaderToList + /// + /// + /// + /// + public List DataReaderToListNoUsing(IDataReader reader) + { + var tType = typeof(T); + var classProperties = tType.GetProperties() + .Where(p => p.GetIndexParameters().Length == 0).ToList(); + var reval = new List(); + if (reader?.IsClosed == false) + { + while (reader.Read()) + { + Dictionary result = DataReaderToList(reader, tType, classProperties, reval); + var stringValue = SerializeObject(result); + reval.Add((T)DeserializeObject(stringValue)); + SetAppendColumns(reader); + } + } + return reval; + } + /// + /// DataReaderToList + /// + /// + /// + /// + public async Task> DataReaderToListAsync(IDataReader reader) + { + using (reader) + { + var tType = typeof(T); + var classProperties = tType.GetProperties().Where(p => p.GetIndexParameters().Length == 0).ToList(); + var reval = new List(); + if (reader?.IsClosed == false) + { + while (await ((DbDataReader)reader).ReadAsync().ConfigureAwait(false)) + { + Dictionary result = DataReaderToList(reader, tType, classProperties, reval); + var stringValue = SerializeObject(result); + reval.Add((T)DeserializeObject(stringValue)); + SetAppendColumns(reader); + } + } + return reval; + } + } + + + public async Task> DataReaderToSelectJsonListAsync(IDataReader dataReader) + { + List result = new List(); + using (dataReader) + { + while (await ((DbDataReader)dataReader).ReadAsync().ConfigureAwait(false)) + { + var value = dataReader.GetValue(0); + if (value == null || value == DBNull.Value) + { + result.Add(default(T)); + } + else + { + result.Add(Context.Utilities.DeserializeObject(value.ToString())); + } + } + } + return result; + } + public async Task> DataReaderToSelectArrayListAsync(IDataReader dataReader) + { + List result = new List(); + using (dataReader) + { + while (await ((DbDataReader)dataReader).ReadAsync().ConfigureAwait(false)) + { + var value = dataReader.GetValue(0); + if (value == null || value == DBNull.Value) + { + result.Add(default(T)); + } + else + { + result.Add((T)value); + } + } + } + return result; + } + + /// + /// DataReaderToList + /// + /// + /// + /// + public async Task> DataReaderToListAsyncNoUsing(IDataReader reader) + { + var tType = typeof(T); + var classProperties = tType.GetProperties().Where(p => p.GetIndexParameters().Length == 0).ToList(); + var reval = new List(); + if (reader?.IsClosed == false) + { + while (await ((DbDataReader)reader).ReadAsync().ConfigureAwait(false)) + { + Dictionary result = DataReaderToList(reader, tType, classProperties, reval); + var stringValue = SerializeObject(result); + reval.Add((T)DeserializeObject(stringValue)); + } + } + return reval; + } + + private Dictionary DataReaderToList(IDataReader reader, Type tType, List classProperties, List reval) + { + var readerValues = DataReaderToDictionary(reader, tType); + var mappingKeys = this.QueryBuilder?.MappingKeys; + var result = new Dictionary(); + if (UtilMethods.IsTuple(tType, classProperties)) + { + var index = 0; + foreach (var item in classProperties) + { + result.Add("Item" + (index + 1), reader.GetValue(index)); + index++; + } + return result; + } + foreach (var item in classProperties) + { + var name = item.Name; + var typeName = tType.Name; + if (item.PropertyType.IsClass()) + { + if (item.PropertyType.FullName == "Newtonsoft.Json.Linq.JObject") + { + result.Add(name, DeserializeObject(readerValues[item.Name].ToString())); + } + else if (IsJsonItem(readerValues, name)) + { + result.Add(name, DeserializeObject>(readerValues.First(it => it.Key.EqualCase(name)).Value.ObjToString())); + } + else if (IsJsonList(readerValues, item)) + { + var json = readerValues.First(y => y.Key.EqualCase(item.Name)).Value.ToString(); + result.Add(name, DeserializeObject>>(json)); + } + else if (IsBytes(readerValues, item)) + { + result.Add(name, (byte[])readerValues[item.Name.ToLower()]); + } + else if (StaticConfig.EnableAot && tType == typeof(DbColumnInfo) && item.PropertyType == typeof(object)) + { + //No add + } + else if (item.PropertyType == typeof(object)) + { + result.Add(name, readerValues[item.Name.ToLower()]); + } + else if (IsArrayItem(readerValues, item)) + { + var json = readerValues.First(y => y.Key.EqualCase(item.Name)).Value + ""; + if (json.StartsWith("[{")) + { + result.Add(name, DeserializeObject(json)); + } + else + { + result.Add(name, DeserializeObject(json)); + } + } + else if (item.PropertyType?.IsArray == true && readerValues?.Any(y => y.Key.EqualCase(item.Name)) == true && readerValues?.FirstOrDefault(y => y.Key.EqualCase(item.Name)).Value is Array value) + { + result.Add(name, value); + } + else if (StaticConfig.EnableAot && item.PropertyType == typeof(Type)) + { + //No Add + } + else + { + List ignorePropertyNames = null; + if (this.QueryBuilder?.SelectNewIgnoreColumns?.Count > 0) + { + var ignoreColumns = this.QueryBuilder.SelectNewIgnoreColumns.Where(it => it.Value == item.PropertyType.Name).ToList(); + if (ignoreColumns.Count != 0) + { + ignorePropertyNames = ignoreColumns.Select(it => it.Key).ToList(); + } + } + result.Add(name, DataReaderToDynamicList_Part(readerValues, item, reval, mappingKeys, ignorePropertyNames)); + } + } + else + { + if (readerValues.Any(it => it.Key.Equals(name, StringComparison.CurrentCultureIgnoreCase))) + { + var addValue = readerValues.TryGetValue(name, out object? value) ? value : readerValues.First(it => it.Key.Equals(name, StringComparison.CurrentCultureIgnoreCase)).Value; + if (addValue != null && this.QueryBuilder?.QueryableFormats?.Any(it => it.PropertyName == name) == true) + { + var valueFomatInfo = this.QueryBuilder?.QueryableFormats?.First(it => it.PropertyName == name); + addValue = UtilMethods.GetFormatValue(addValue, valueFomatInfo); + + } + var type = UtilMethods.GetUnderType(item.PropertyType); + if (addValue == DBNull.Value || addValue == null) + { + if (item.PropertyType.IsIn(UtilConstants.IntType, UtilConstants.LongType, UtilConstants.DecType, UtilConstants.DobType, UtilConstants.ByteType)) + { + addValue = 0; + } + else if (item.PropertyType == UtilConstants.GuidType) + { + addValue = Guid.Empty; + } + else if (item.PropertyType == UtilConstants.DateType) + { + addValue = DateTime.MinValue; + } + else if (item.PropertyType == UtilConstants.StringType) + { + addValue = null; + } + else + { + addValue = null; + } + } + else if (type == UtilConstants.IntType) + { + addValue = Convert.ToInt32(addValue); + } + else if (type == UtilConstants.LongType) + { + addValue = Convert.ToInt64(addValue); + } + else if (type.IsEnum() && addValue is decimal) + { + addValue = Convert.ToInt64(addValue); + } + else if (type.FullName == "System.DateOnly") + { + addValue = Convert.ToDateTime(addValue).ToString("yyyy-MM-dd"); + } + result.Add(name, addValue); + } + } + } + + return result; + } + + + private void SetAppendColumns(IDataReader dataReader) + { + if (QueryBuilder?.AppendColumns != null && QueryBuilder.AppendColumns.Count != 0) + { + if (QueryBuilder.AppendValues == null) + QueryBuilder.AppendValues = new List>(); + List addItems = new List(); + foreach (var item in QueryBuilder.AppendColumns) + { + var vi = dataReader.GetOrdinal(item.AsName); + var value = dataReader.GetValue(vi); + addItems.Add(new QueryableAppendColumn() + { + Name = item.Name, + AsName = item.AsName, + Value = value + }); + } + QueryBuilder.AppendValues.Add(addItems); + } + if (QueryBuilder?.AppendNavInfo != null) + { + var navResult = new AppendNavResult(); + foreach (var item in QueryBuilder?.AppendNavInfo.AppendProperties) + { + var vi = dataReader.GetOrdinal("SugarNav_" + item.Key); + var value = dataReader.GetValue(vi); + navResult.result.Add("SugarNav_" + item.Key, value); + } + QueryBuilder?.AppendNavInfo.Result.Add(navResult); + } + } + private static bool IsBytes(Dictionary readerValues, PropertyInfo item) + { + return item.PropertyType == UtilConstants.ByteArrayType && + readerValues.ContainsKey(item.Name.ToLower()) && + (readerValues[item.Name.ToLower()] == null || + readerValues[item.Name.ToLower()].GetType() == UtilConstants.ByteArrayType); + } + + private static bool IsJsonItem(Dictionary readerValuesOld, string name) + { + Dictionary readerValues = new Dictionary(); + if (readerValuesOld.Any(it => it.Key.EqualCase(name))) + { + var data = readerValuesOld.First(it => it.Key.EqualCase(name)); + readerValues.Add(data.Key, data.Value); + } + return readerValues?.Count == 1 && + readerValues.First().Key == name && + readerValues.First().Value != null && + readerValues.First().Value.GetType() == UtilConstants.StringType && + Regex.IsMatch(readerValues.First().Value.ObjToString(), @"^\{.+\}$"); + } + + + private static bool IsArrayItem(Dictionary readerValues, PropertyInfo item) + { + var isArray = item.PropertyType.IsArray && readerValues.Any(y => y.Key.EqualCase(item.Name)) && readerValues.FirstOrDefault(y => y.Key.EqualCase(item.Name)).Value is string; + var isListItem = item.PropertyType.FullName.IsCollectionsList() && + item.PropertyType.GenericTypeArguments.Length == 1 && + item.PropertyType.GenericTypeArguments.First().IsClass() == false && readerValues.FirstOrDefault(y => y.Key.EqualCase(item.Name)).Value is string; + return isArray || isListItem; + } + + private static bool IsJsonList(Dictionary readerValues, PropertyInfo item) + { + return item.PropertyType.FullName.IsCollectionsList() && + readerValues.Any(y => y.Key.EqualCase(item.Name)) && + readerValues.First(y => y.Key.EqualCase(item.Name)).Value != null && + readerValues.First(y => y.Key.EqualCase(item.Name)).Value.GetType() == UtilConstants.StringType && + Regex.IsMatch(readerValues.First(y => y.Key.EqualCase(item.Name)).Value.ToString(), @"^\[{.+\}]$"); + } + + private Dictionary DataReaderToDynamicList_Part(Dictionary readerValues, PropertyInfo item, List reval, Dictionary mappingKeys = null, List ignoreColumns = null) + { + Dictionary result = new Dictionary(); + var type = item.PropertyType; + if (UtilConstants.SugarType == type) + { + return result; + } + if (type.FullName.IsCollectionsList()) + { + return null; + } + if (type == typeof(string[])) + { + return null; + } + var classProperties = type.GetProperties().ToList(); + if (type.Name.StartsWith("Dictionary`")) + { + return null; + } + var columns = this.Context.EntityMaintenance.GetEntityInfo(type).Columns; + foreach (var prop in classProperties) + { + var name = prop.Name; + var typeName = type.Name; + if (prop.PropertyType.IsClass()) + { + if (ignoreColumns?.Contains(name) == true) + { + continue; + } + var suagrColumn = prop.GetCustomAttribute(); + if (suagrColumn?.IsJson == true) + { + + if (mappingKeys != null && mappingKeys.TryGetValue(item.Name, out string? key)) + { + Json(readerValues, result, name, typeName, key, item); + } + else + { + Json(readerValues, result, name, typeName, item); + } + } + else if (columns.Any(it => it.IsJson)) + { + var column = columns.FirstOrDefault(it => it.PropertyName == name); + if (column?.IsJson == true) + { + Json(readerValues, result, name, typeName); + } + } + else + { + result.Add(name, DataReaderToDynamicList_Part(readerValues, prop, reval)); + } + } + else + { + var key = typeName + "." + name; + var info = readerValues.Select(it => it.Key).FirstOrDefault(it => it.Equals(key, StringComparison.CurrentCultureIgnoreCase)); + if (info == null) + { + key = item.Name + "." + name; + info = readerValues.Select(it => it.Key).FirstOrDefault(it => it.Equals(key, StringComparison.CurrentCultureIgnoreCase)); + if (info == null) + { + info = readerValues.Select(it => it.Key).FirstOrDefault(it => it.ToLower().EndsWith("." + key.ToLower())); + } + } + var oldInfo = info; + if (mappingKeys != null && mappingKeys.TryGetValue(item.Name, out string? value)) + { + key = value + "." + typeName + "." + name; + info = readerValues.Select(it => it.Key).FirstOrDefault(it => it.Equals(key, StringComparison.CurrentCultureIgnoreCase)); + if (info == null) + { + var key2 = item.Name + "." + name; + info = readerValues.Select(it => it.Key).FirstOrDefault(it => it.Equals(key2, StringComparison.CurrentCultureIgnoreCase)); + } + } + else if (mappingKeys?.ContainsKey("Single_" + name) == true) + { + key = mappingKeys["Single_" + name]; + info = readerValues.Select(it => it.Key).FirstOrDefault(it => it.Equals(key, StringComparison.CurrentCultureIgnoreCase)); + } + if (info == null && oldInfo != null) + { + info = oldInfo; + } + if (info != null) + { + var addItem = readerValues[info]; + if (addItem == DBNull.Value) + addItem = null; + var underType = UtilMethods.GetUnderType(prop.PropertyType); + if (prop.PropertyType == UtilConstants.IntType) + { + addItem = addItem.ObjToInt(); + } + else if (prop.PropertyType == UtilConstants.ShortType) + { + addItem = Convert.ToInt16(addItem); + } + else if (prop.PropertyType == UtilConstants.LongType) + { + addItem = Convert.ToInt64(addItem); + } + else if (UtilMethods.GetUnderType(prop.PropertyType) == UtilConstants.IntType && addItem != null) + { + addItem = addItem.ObjToInt(); + } + else if (addItem != null && underType?.FullName == "System.DateOnly") + { + addItem = Convert.ToDateTime(addItem).ToString("yyyy-MM-dd"); + } + else if (UtilMethods.GetUnderType(prop.PropertyType).IsEnum() && addItem is decimal) + { + if (prop.PropertyType.IsEnum() == false && addItem == null) + { + //Future + } + else + { + addItem = Convert.ToInt64(addItem); + } + } + result.Add(name, addItem); + } + } + } + return result; + } + + private void Json(Dictionary readerValues, Dictionary result, string name, string typeName, string shortName = null, PropertyInfo item = null) + { + var key = (typeName + "." + name).ToLower(); + if (readerValues.Any(it => it.Key.EqualCase(key))) + { + var jsonString = readerValues.First(it => it.Key.EqualCase(key)).Value; + AddJson(result, name, jsonString); + } + else + { + key = (shortName + "." + typeName + "." + name).ToLower(); + if (readerValues.Any(it => it.Key.EqualCase(key))) + { + var jsonString = readerValues.First(it => it.Key.EqualCase(key)).Value; + AddJson(result, name, jsonString); + } + else if (item != null) + { + if (readerValues.Any(it => it.Key.EqualCase(item.Name + "." + name))) + { + var jsonString = readerValues.First(it => it.Key.EqualCase(item.Name + "." + name)).Value; + AddJson(result, name, jsonString); + + } + } + } + } + private void Json(Dictionary readerValues, Dictionary result, string name, string typeName, PropertyInfo item) + { + var key = (typeName + "." + name).ToLower(); + if (readerValues.Any(it => it.Key.EqualCase(key))) + { + var jsonString = readerValues.First(it => it.Key.EqualCase(key)).Value; + AddJson(result, name, jsonString); + } + else + { + key = (item.Name + "." + name).ToLower(); + if (readerValues.Any(it => it.Key.EqualCase(key))) + { + var jsonString = readerValues.First(it => it.Key.EqualCase(key)).Value; + AddJson(result, name, jsonString); + } + } + } + + private void AddJson(Dictionary result, string name, object jsonString) + { + if (jsonString != null) + { + if (jsonString.ToString().First() == '{' && jsonString.ToString().Last() == '}') + { + result.Add(name, this.DeserializeObject>(jsonString + "")); + } + else if (jsonString.ToString().Replace(" ", "") != "[]" && !jsonString.ToString().Contains('{') && !jsonString.ToString().Contains('}')) + { + result.Add(name, this.DeserializeObject(jsonString + "")); + } + else + { + result.Add(name, this.DeserializeObject>>(jsonString + "")); + + } + } + } + #endregion + + #region Serialize + /// + /// Serialize Object + /// + /// + /// + public string SerializeObject(object value) + { + DependencyManagement.TryJsonNet(); + return Context.CurrentConnectionConfig.ConfigureExternalServices.SerializeService.SerializeObject(value); + } + public string SerializeObject(object value, Type type) + { + DependencyManagement.TryJsonNet(); + if (type.IsAnonymousType()) + { + return Context.CurrentConnectionConfig.ConfigureExternalServices.SerializeService.SerializeObject(value); + } + else + { + var isSugar = this.Context.EntityMaintenance.GetEntityInfo(type).Columns.Any(it => it.NoSerialize || it.SerializeDateTimeFormat.HasValue()); + if (isSugar) + { + return Context.CurrentConnectionConfig.ConfigureExternalServices.SerializeService.SugarSerializeObject(value); + } + else + { + return Context.CurrentConnectionConfig.ConfigureExternalServices.SerializeService.SerializeObject(value); + } + } + } + + + /// + /// Serialize Object + /// + /// + /// + public T DeserializeObject(string value) + { + DependencyManagement.TryJsonNet(); + return Context.CurrentConnectionConfig.ConfigureExternalServices.SerializeService.DeserializeObject(value); + } + #endregion + + #region Copy Object + /// + /// Copy new Object + /// + /// + /// + /// + public T TranslateCopy(T sourceObject) + { + if (sourceObject == null) return default(T); + else + { + var jsonString = SerializeObject(sourceObject); + return DeserializeObject(jsonString); + } + } + public SqlSugarProvider CopyContext(bool isCopyEvents = false) + { + var newClient = new SqlSugarProvider(this.TranslateCopy(Context.CurrentConnectionConfig)); + newClient.CurrentConnectionConfig.ConfigureExternalServices = Context.CurrentConnectionConfig.ConfigureExternalServices; + newClient.MappingColumns = this.TranslateCopy(Context.MappingColumns); + newClient.MappingTables = this.TranslateCopy(Context.MappingTables); + newClient.IgnoreColumns = this.TranslateCopy(Context.IgnoreColumns); + newClient.IgnoreInsertColumns = this.TranslateCopy(Context.IgnoreInsertColumns); + if (isCopyEvents) + { + newClient.QueryFilter = Context.QueryFilter; + newClient.CurrentConnectionConfig.AopEvents = Context.CurrentConnectionConfig.AopEvents; + } + return newClient; + } + #endregion + + #region DataTable + public DataTable DictionaryListToDataTable(List> list) + { + DataTable result = new DataTable(); + if (list.Count == 0) + return result; + + var columnNames = list.First(); + foreach (var item in columnNames) + { + result.Columns.Add(item.Key, item.Value == null ? typeof(object) : item.Value.GetType()); + } + foreach (var item in list) + { + var row = result.NewRow(); + foreach (var key in item.Keys) + { + if (item[key] == null) + { + row[key] = DBNull.Value; + } + else + { + row[key] = item[key]; + } + } + + result.Rows.Add(row); + } + + return result; + } + public dynamic DataTableToDynamic(DataTable table) + { + List> deserializeObject = new List>(); + Dictionary childRow; + foreach (DataRow row in table.Rows) + { + childRow = new Dictionary(); + foreach (DataColumn col in table.Columns) + { + var addItem = row[col]; + if (addItem == DBNull.Value) + addItem = null; + childRow.Add(col.ColumnName, addItem); + } + deserializeObject.Add(childRow); + } + return this.DeserializeObject(this.SerializeObject(deserializeObject)); + + } + public List DataTableToList(DataTable table) + { + List> deserializeObject = new List>(); + Dictionary childRow; + foreach (DataRow row in table.Rows) + { + childRow = new Dictionary(); + foreach (DataColumn col in table.Columns) + { + var addItem = row[col]; + if (addItem == DBNull.Value) + addItem = null; + childRow.Add(col.ColumnName, addItem); + } + deserializeObject.Add(childRow); + } + return this.DeserializeObject>(this.SerializeObject(deserializeObject)); + } + public DataTable ListToDataTable(List list) + { + DataTable result = new DataTable(); + if (list?.Count > 0) + { + PropertyInfo[] propertys = list[0].GetType().GetProperties(); + foreach (PropertyInfo pi in propertys) + { + //获取类型 + Type colType = pi.PropertyType; + //当类型为Nullable<>时 + if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) + { + colType = colType.GetGenericArguments()[0]; + } + result.Columns.Add(pi.Name, colType); + } + for (int i = 0; i < list.Count; i++) + { + ArrayList tempList = new ArrayList(); + foreach (PropertyInfo pi in propertys) + { + object obj = pi.GetValue(list[i], null); + tempList.Add(obj); + } + object[] array = tempList.ToArray(); + result.LoadDataRow(array, true); + } + } + return result; + } + + public DataTable ListToDataTableWithAttr(List list) + { + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(); + DataTable result = new DataTable(); + result.TableName = entityInfo.DbTableName; + if (list?.Count > 0) + { + var colimnInfos = entityInfo.Columns.Where(it => it.IsIgnore == false); + foreach (var pi in colimnInfos) + { + //获取类型 + Type colType = pi.PropertyInfo.PropertyType; + //当类型为Nullable<>时 + if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) + { + colType = colType.GetGenericArguments()[0]; + } + result.Columns.Add(pi.DbColumnName, colType); + } + for (int i = 0; i < list.Count; i++) + { + ArrayList tempList = new ArrayList(); + foreach (var pi in colimnInfos) + { + object obj = pi.PropertyInfo.GetValue(list[i], null); + tempList.Add(obj); + } + object[] array = tempList.ToArray(); + result.LoadDataRow(array, true); + } + } + return result; + } + public Dictionary DataTableToDictionary(DataTable table) + { + return table.Rows.Cast().ToDictionary(x => x[0].ToString(), x => x[1]); + } + + public List> DataTableToDictionaryList(DataTable dt) + { + List> result = new List>(); + if (dt?.Rows.Count > 0) + { + foreach (DataRow dr in dt.Rows) + { + Dictionary dic = new Dictionary(); + for (int i = 0; i < dr.Table.Columns.Count; i++) + { + var value = dr[dr.Table.Columns[i].ColumnName]; + if (value == DBNull.Value) + { + value = null; + } + dic.Add(dr.Table.Columns[i].ColumnName.ToString(), value); + } + result.Add(dic); + } + } + return result; + } + + #endregion + + #region Cache + public ICacheService GetReflectionInoCacheInstance() + { + return Context.CurrentConnectionConfig.ConfigureExternalServices.ReflectionInoCacheService; + } + + public void RemoveCacheAll() + { + ReflectionInoHelper.RemoveAllCache(); + InstanceFactory.RemoveCache(); + } + + public void RemoveCacheAll() + { + ReflectionInoCore.GetInstance().RemoveAllCache(); + } + + public void RemoveCache(string key) + { + ReflectionInoCore.GetInstance().Remove(key); + } + public void RemoveCacheByLikeKey(string key) + { + foreach (var item in ReflectionInoCore.GetInstance().GetAllKey()) + { + if (item != null && key != null && item.Contains(key)) + { + ReflectionInoCore.GetInstance().Remove(item); + } + } + } + #endregion + + #region Page Each + public void PageEach(IEnumerable pageItems, int pageSize, Action> action) + { + if (pageItems?.Any() == true) + { + int totalRecord = pageItems.Count(); + int pageCount = (totalRecord + pageSize - 1) / pageSize; + for (int i = 1; i <= pageCount; i++) + { + var list = pageItems.Skip((i - 1) * pageSize).Take(pageSize).ToList(); + action(list); + } + } + } + + public async Task PageEachAsync(IEnumerable pageItems, int pageSize, Func, Task> action) + { + if (pageItems?.Any() == true) + { + int totalRecord = pageItems.Count(); + int pageCount = (totalRecord + pageSize - 1) / pageSize; + for (int i = 1; i <= pageCount; i++) + { + var list = pageItems.Skip((i - 1) * pageSize).Take(pageSize).ToList(); + await action(list).ConfigureAwait(false); + } + } + } + public async Task PageEachAsync(IEnumerable pageItems, int pageSize, Func, Task> action) + { + if (pageItems?.Any() == true) + { + int totalRecord = pageItems.Count(); + int pageCount = (totalRecord + pageSize - 1) / pageSize; + for (int i = 1; i <= pageCount; i++) + { + var list = pageItems.Skip((i - 1) * pageSize).Take(pageSize).ToList(); + await action(list).ConfigureAwait(false); + } + } + } + + #endregion + + #region Conditional + public KeyValuePair ConditionalModelsToSql(List conditionalModels, int beginIndex = 0) + { + var sqlBuilder = InstanceFactory.GetSqlBuilderWithContext(this.Context); + var result = sqlBuilder.ConditionalModelToSql(conditionalModels, beginIndex); + return result; + } + public List JsonToConditionalModels(string json) + { + List conditionalModels = new List(); + var jarray = this.Context.Utilities.DeserializeObject(json); + foreach (var item in jarray) + { + + if (item.Any()) + { + if (item.ToString().Contains("ConditionalList")) + { + IConditionalModel model = new ConditionalTree() + { + ConditionalList = GetConditionalList(item) + }; + conditionalModels.Add(model); + } + else + { + var typeValue = item["ConditionalType"].Value(); + + ConditionalModel conditionalModel = new ConditionalModel() + { + // ConditionalType = (ConditionalType)Convert.ToInt32(), + FieldName = item["FieldName"] + "", + CSharpTypeName = item["CSharpTypeName"].ObjToString().IsNullOrEmpty() ? null : item["CSharpTypeName"].ObjToString(), + FieldValue = item["FieldValue"].Value() == null ? null : item["FieldValue"].ToString() + }; + if (typeValue.IsInt()) + { + conditionalModel.ConditionalType = (ConditionalType)Convert.ToInt32(typeValue); + } + else + { + conditionalModel.ConditionalType = (ConditionalType)Enum.Parse(typeof(ConditionalType), typeValue.ObjToString()); + } + conditionalModels.Add(conditionalModel); + } + } + } + return conditionalModels; + } + private static List> GetConditionalList(JToken item) + { + List> result = new List>(); + var values = item.Values().First(); + foreach (var jToken in values) + { + WhereType type = (WhereType)Convert.ToInt32(jToken["Key"].Value()); + IConditionalModel conditionalModel = null; + var value = jToken["Value"]; + if (value.ToString().Contains("ConditionalList")) + { + conditionalModel = new ConditionalTree() + { + ConditionalList = GetConditionalList(value) + }; + } + else + { + conditionalModel = new ConditionalModel() + { + ConditionalType = GetConditionalType(value), + FieldName = value["FieldName"] + "", + CSharpTypeName = value["CSharpTypeName"].ObjToString().IsNullOrEmpty() ? null : value["CSharpTypeName"].ObjToString(), + FieldValue = value["FieldValue"].Value() == null ? null : value["FieldValue"].ToString() + }; + } + result.Add(new KeyValuePair(type, conditionalModel)); + } + return result; + } + private static ConditionalType GetConditionalType(JToken value) + { + if (value["ConditionalType"].Type == JTokenType.String) + { + var stringValue = value["ConditionalType"].Value(); + if (!stringValue.IsInt()) + { + return (ConditionalType)Enum.Parse(typeof(ConditionalType), stringValue); + } + } + return (ConditionalType)Convert.ToInt32(value["ConditionalType"].Value()); + } + #endregion + + #region Tree + public List ToTree(List list, Expression>> childListExpression, Expression> parentIdExpression, Expression> pkExpression, object rootValue) + { + var pk = ExpressionTool.GetMemberName(pkExpression); + return (this.Context.Queryable() as QueryableProvider).GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); + } + #endregion + + #region Other + public string EscapeLikeValue(string value, char wildcard = '%') + { + return UtilMethods.EscapeLikeValue(this.Context, value, wildcard); + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/DependencyManagement.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/DependencyManagement.cs new file mode 100644 index 000000000..050029e88 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/DependencyManagement.cs @@ -0,0 +1,166 @@ +namespace SqlSugar +{ + internal static class DependencyManagement + { + private static bool IsTryJsonNet = false; + private static bool IsTryMySqlData = false; + private static bool IsTrySqlite = false; + private static bool IsTryOracle = false; + private static bool IsTryPgSql = false; + private static bool IsTryDm = false; + private static bool IsTryKd = false; + private static bool IsTryOscar = false; + public static void TryJsonNet() + { + if (!IsTryJsonNet) + { + try + { + new SerializeService().SerializeObject(new { }); + IsTryJsonNet = true; + } + catch + { + var message = ErrorMessage.GetThrowMessage( + " SqlSugar Some functions are used in newtonsoft ,Nuget references Newtonsoft.Json 9.0.0.1 + .", + " SqlSugar 部分功能用到Newtonsoft.Json.dll,需要在Nuget上安装 Newtonsoft.Json 9.0.0.1及以上版本,如果有版本兼容问题请先删除原有引用"); + throw new Exception(message); + } + } + } + + public static void TryMySqlData() + { + if (!IsTryMySqlData) + { + try + { + MySqlProvider db = new MySqlProvider(); + var conn = db.GetAdapter(); + IsTryMySqlData = true; + } + catch + { + var message = ErrorMessage.GetThrowMessage( + "You need to refer to MySql.Data.dll", + "需要引用MySql.Data.dll,请在Nuget安装最新稳定版本,如果有版本兼容问题请先删除原有引用"); + throw new Exception(message); + } + } + } + + public static void TryPostgreSQL() + { + if (!IsTryPgSql) + { + try + { + PostgreSQLProvider db = new PostgreSQLProvider(); + var conn = db.GetAdapter(); + IsTryPgSql = true; + } + catch + { + var message = ErrorMessage.GetThrowMessage( + "You need to refer to Npgsql 3.2.7", + "你需要引用 Npgsql 3.2.7及以上版本"); + throw new Exception(message); + } + } + } + + public static void TryOracle() + { + if (!IsTryOracle) + { + try + { + OracleProvider db = new OracleProvider(); + var conn = db.GetAdapter(); + IsTryOracle = true; + } + catch + { + var message = ErrorMessage.GetThrowMessage( + "You need to refer to Oracle.ManagedDataAccess.Core", + "你需要引用 Oracle.ManagedDataAccess.Core"); + throw new Exception(message); + } + } + } + + public static void TrySqlite() + { + if (!IsTrySqlite) + { + try + { + SqliteProvider db = new SqliteProvider(); + var conn = db.GetAdapter(); + IsTrySqlite = true; + } + catch (Exception ex) + { + var message = ErrorMessage.GetThrowMessage( + "You need to refer to Microsoft.Data.Sqlite." + ex.Message, + "你需要引用Microsoft.Data.Sqlite,如果有版本兼容问题请先删除原有引用"); + throw new Exception(message); + } + } + } + + public static void TryKdbndb() + { + if (!IsTryKd) + { + try + { + KdbndpProvider db = new KdbndpProvider(); + var conn = db.GetAdapter(); + IsTryKd = true; + } + catch + { + var message = "需要引用Kdbndp.dll,Github搜索sqlsugar源码里面有"; + throw new Exception(message); + } + } + } + + public static void TryDm() + { + if (!IsTryDm) + { + try + { + DmProvider db = new DmProvider(); + var conn = db.GetAdapter(); + IsTryDm = true; + } + catch + { + var message = "需要引用DmProvider.dll,Github搜索sqlsugar源码里面有"; + throw new Exception(message); + } + } + } + + public static void TryOscar() + { + if (!IsTryOscar) + { + try + { + OscarProvider db = new OscarProvider(); + db.GetAdapter(); + IsTryOscar = true; + } + catch + { + var message = "需要引用Oscar.Data.SqlClient.dll,Github搜索sqlsugar源码里面有"; + throw new Exception(message); + } + } + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/InstanceFactory.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/InstanceFactory.cs new file mode 100644 index 000000000..b1e70f1e3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/InstanceFactory.cs @@ -0,0 +1,823 @@ +using System.Reflection; +namespace SqlSugar +{ + + public static class InstanceFactory + { + static Assembly assembly = Assembly.GetExecutingAssembly(); + static Dictionary typeCache = new Dictionary(); + private static string _CustomDllName = ""; + private static List CustomDlls = new List(); + public static Assembly[] CustomAssemblies = Array.Empty(); + public static string CustomDllName + { + get { return _CustomDllName; } + set + { + if (!CustomDlls.Contains(value)) + { + CustomDlls.Add(value); + } + _CustomDllName = value; + } + } + public static string CustomDbName = ""; + public static string CustomNamespace = ""; + public static bool NoCache = false; + public static void RemoveCache() + { + typeCache = new Dictionary(); + } + + #region Queryable + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerQueryable(); + } + else if (currentConnectionConfig.DbType == DbType.MySql) + { + return new MySqlQueryable(); + } + else if (currentConnectionConfig.DbType == DbType.Sqlite) + { + return new SqliteQueryable(); + } + else if (currentConnectionConfig.DbType == DbType.PostgreSQL) + { + return new PostgreSQLQueryable(); + } + else + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerQueryable(); + } + else + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerQueryable(); + } + else + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + + #region 9-12 + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) + { + string className = "Queryable"; + className = GetClassName(currentConnectionConfig.DbType.ToString(), className); + ISugarQueryable result = CreateInstance>(className); + return result; + } + #endregion + + #endregion + + public static QueryBuilder GetQueryBuilderWithContext(ISqlSugarClient db) + { + if (db is SqlSugarClient) + { + db = (db as SqlSugarClient).Context; + } + else if (db is SqlSugarScope) + { + db = (db as SqlSugarScope).ScopedContext.Context; + } + if (!(db is SqlSugarProvider)) + { + db = new SqlSugarClient(db.CurrentConnectionConfig).Context; + } + var QueryBuilder = InstanceFactory.GetQueryBuilder(db.CurrentConnectionConfig); + QueryBuilder.Context = (SqlSugarProvider)db; + QueryBuilder.Builder = InstanceFactory.GetSqlbuilder(db.CurrentConnectionConfig); + QueryBuilder.Builder.Context = (SqlSugarProvider)db; + return QueryBuilder; + } + + public static QueryBuilder GetQueryBuilder(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerQueryBuilder(); + } + else if (currentConnectionConfig.DbType == DbType.MySql) + { + return new MySqlQueryBuilder(); + } + else + { + QueryBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "QueryBuilder")); + return result; + } + } + public static InsertBuilder GetInsertBuilder(ConnectionConfig currentConnectionConfig) + { + InsertBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "InsertBuilder")); + return result; + } + public static UpdateBuilder GetUpdateBuilder(ConnectionConfig currentConnectionConfig) + { + UpdateBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "UpdateBuilder")); + return result; + } + public static DeleteBuilder GetDeleteBuilder(ConnectionConfig currentConnectionConfig) + { + DeleteBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DeleteBuilder")); + return result; + } + + public static ILambdaExpressions GetLambdaExpressions(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerExpressionContext(); + } + else if (currentConnectionConfig.DbType == DbType.MySql) + { + return new MySqlExpressionContext(); + } + else + { + ILambdaExpressions result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "ExpressionContext")); + return result; + } + } + public static ISqlBuilder GetSqlBuilderWithContext(ISqlSugarClient db) + { + var result = GetQueryBuilderWithContext(db).Builder; + return result; + } + public static ISqlBuilder GetSqlbuilder(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerBuilder(); + } + else if (currentConnectionConfig.DbType == DbType.MySql) + { + return new MySqlBuilder(); + } + else + { + ISqlBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "Builder")); + return result; + } + } + + public static UpdateableProvider GetUpdateableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() + { + if (currentConnectionConfig.DbType == DbType.Oracle) + { + return new OracleUpdateable(); + } + else if (IsCustomDb(currentConnectionConfig)) + { + var name = + "SqlSugar." + currentConnectionConfig.DbType + + "." + currentConnectionConfig.DbType + + "Updateable`1"; + var type = GetCustomTypeByClass(name); + if (type == null) + { + name = + InstanceFactory.CustomNamespace + + "." + InstanceFactory.CustomDbName + + "Updateable`1"; + type = GetCustomTypeByClass(name); + } + if (type == null) + { + return new UpdateableProvider(); + } + else + { + return (UpdateableProvider)Activator.CreateInstance(type, true); + } + } + else + { + return new UpdateableProvider(); + } + } + + public static DeleteableProvider GetDeleteableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() + { + if (currentConnectionConfig.DbType == DbType.Oracle) + { + return new OracleDeleteable(); + } + else if (IsCustomDb(currentConnectionConfig)) + { + var name = + "SqlSugar." + currentConnectionConfig.DbType + + "." + currentConnectionConfig.DbType + + "Deleteable`1"; + var type = GetCustomTypeByClass(name); + if (type == null) + { + name = + InstanceFactory.CustomNamespace + + "." + InstanceFactory.CustomDbName + + "Deleteable`1"; + type = GetCustomTypeByClass(name); + } + if (type == null) + { + return new DeleteableProvider(); + } + else + { + return (DeleteableProvider)Activator.CreateInstance(type, true); + } + } + else + { + return new DeleteableProvider(); + } + } + + public static InsertableProvider GetInsertableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() + { + if (currentConnectionConfig.DbType == DbType.Oracle) + { + return new OracleInsertable(); + } + else if (currentConnectionConfig.DbType == DbType.PostgreSQL) + { + return new PostgreSQLInserttable(); + } + else if (currentConnectionConfig.DbType == DbType.Kdbndp) + { + return new KdbndpInserttable(); + } + else if (currentConnectionConfig.DbType == DbType.Oscar) + { + return new KdbndpInserttable(); + } + else if (IsCustomDb(currentConnectionConfig)) + { + var name = + "SqlSugar." + currentConnectionConfig.DbType + + "." + currentConnectionConfig.DbType + + "Insertable`1"; + var type = GetCustomTypeByClass(name); + if (type == null) + { + name = + InstanceFactory.CustomNamespace + + "." + InstanceFactory.CustomDbName + + "Insertable`1"; + type = GetCustomTypeByClass(name); + } + if (type == null) + { + return new InsertableProvider(); + } + else + { + return (InsertableProvider)Activator.CreateInstance(type, true); + } + } + else + { + return new InsertableProvider(); + } + } + + private static bool IsCustomDb(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.Custom) + { + return true; + } + return currentConnectionConfig.DbType != DbType.SqlServer && + currentConnectionConfig.DbType != DbType.Dm && + currentConnectionConfig.DbType != DbType.Oscar && + currentConnectionConfig.DbType != DbType.Access && + currentConnectionConfig.DbType != DbType.QuestDB && + currentConnectionConfig.DbType != DbType.MySql && + currentConnectionConfig.DbType != DbType.Oracle && + currentConnectionConfig.DbType != DbType.PostgreSQL && + currentConnectionConfig.DbType != DbType.ClickHouse && + currentConnectionConfig.DbType != DbType.GBase && + currentConnectionConfig.DbType != DbType.Sqlite && + GetCustomTypeByClass("SqlSugar." + currentConnectionConfig.DbType + "." + currentConnectionConfig.DbType + "Provider") != null; + + } + + public static IDbBind GetDbBind(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerDbBind(); + } + else if (currentConnectionConfig.DbType == DbType.MySql) + { + return new MySqlDbBind(); + } + else + { + IDbBind result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DbBind")); + return result; + } + } + + public static IDbMaintenance GetDbMaintenance(ConnectionConfig currentConnectionConfig) + { + IDbMaintenance result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DbMaintenance")); + return result; + } + + public static IDbFirst GetDbFirst(ConnectionConfig currentConnectionConfig) + { + IDbFirst result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DbFirst")); + return result; + } + + public static ICodeFirst GetCodeFirst(ConnectionConfig currentConnectionConfig) + { + ICodeFirst result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "CodeFirst")); + return result; + } + + public static IAdo GetAdo(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.DbType == DbType.SqlServer) + { + return new SqlServerProvider(); + } + else + { + IAdo result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "Provider")); + return result; + } + } + + private static string GetClassName(string type, string name) + { + if (type == "MySqlConnector") + { + return "SqlSugar.MySqlConnector.MySql" + name; + } + else if (type == "Access") + { + return "SqlSugar.Access.Access" + name; + } + else if (type == "ClickHouse") + { + return "SqlSugar.ClickHouse.ClickHouse" + name; + } + else if (type == "GBase") + { + return "SqlSugar.GBase.GBase" + name; + } + else if (type == "Odbc") + { + return "SqlSugar.Odbc.Odbc" + name; + } + else if (type == "Custom") + { + return CustomNamespace + "." + CustomDbName + name; + } + else if (type == "HANA") + { + return InstanceFactory.CustomDllName + "." + type + name; + } + else if (type == "DB2") + { + return "SqlSugar.DB2." + type + name; + } + else if (type == "GaussDBNative") + { + return "SqlSugar.GaussDB.GaussDB" + name; + } + else + { + //if (!string.IsNullOrEmpty(CustomDllName)) + //{ + // type = CustomDllName; + //} + return UtilConstants.AssemblyName + "." + type + name; + } + } + + #region CreateInstance + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8)); + } + + #region 9-12 + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11)); + } + private static Restult CreateInstance(string className) + { + return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12)); + } + #endregion + + private static Restult CreateInstance(string className, params Type[] types) + { + try + { + if (NoCache) + { + return NoCacheGetCacheInstance(className, types); + } + else + { + return GetCacheInstance(className, types); + } + } + catch + { + NoCache = true; + return NoCacheGetCacheInstance(className, types); + } + } + + private static Restult GetCacheInstance(string className, Type[] types) + { + var cacheKey = className + string.Join(",", types.Select(it => it.FullName)); + Type type = null; + if (typeCache.TryGetValue(cacheKey, out Type? value)) + { + type = value; + } + else + { + lock (typeCache) + { + if (string.IsNullOrEmpty(CustomDllName)) + { + type = Type.GetType(className + '`' + types.Length, true).MakeGenericType(types); + } + else + { + var custom = GetCustomTypeByClass(className + '`' + types.Length); + if (custom != null) + { + type = custom.MakeGenericType(types); + } + if (type == null) + { + type = Type.GetType(className + '`' + types.Length, true).MakeGenericType(types); + } + } + Check.ArgumentNullException(type, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, className)); + typeCache.TryAdd(cacheKey, type); + } + } + var result = (Restult)Activator.CreateInstance(type, true); + return result; + } + private static Restult NoCacheGetCacheInstance(string className, Type[] types) + { + + Type type = null; + if (string.IsNullOrEmpty(CustomDllName)) + { + type = Type.GetType(className + '`' + types.Length, true).MakeGenericType(types); + } + else + { + var custom = GetCustomTypeByClass(className + '`' + types.Length); + if (custom != null) + { + type = custom.MakeGenericType(types); + } + if (type == null) + { + type = Type.GetType(className + '`' + types.Length)?.MakeGenericType(types); + if (type == null) + { + type = GetCustomDbType(className + '`' + types.Length, type).MakeGenericType(types); + } + } + } + var result = (Restult)Activator.CreateInstance(type, true); + return result; + } + + public static T CreateInstance(string className) + { + try + { + if (NoCache) + { + return NoCacheGetCacheInstance(className); + } + else + { + return GetCacheInstance(className); + } + } + catch + { + return NoCacheGetCacheInstance(className); + } + } + + private static T GetCacheInstance(string className) + { + Type type; + if (typeCache.TryGetValue(className, out Type? value)) + { + type = value; + } + else + { + lock (typeCache) + { + if (string.IsNullOrEmpty(CustomDllName)) + { + type = assembly.GetType(className); + } + else + { + type = GetCustomTypeByClass(className); + if (type == null) + { + type = assembly.GetType(className); + } + } + if (type == null) + { + type = GetCustomDbType(className, type); + } + Check.ArgumentNullException(type, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, className)); + typeCache.TryAdd(className, type); + } + } + var result = (T)Activator.CreateInstance(type, true); + return result; + } + private static T NoCacheGetCacheInstance(string className) + { + Type type = null; + if (string.IsNullOrEmpty(CustomDllName)) + { + type = assembly.GetType(className); + } + else + { + type = GetCustomTypeByClass(className); + } + if (type == null) + { + type = GetCustomDbType(className, type); + } + var result = (T)Activator.CreateInstance(type, true); + return result; + } + + private static Type GetCustomDbType(string className, Type type) + { + if (className.Replace(".", "").Length + 1 == className.Length) + { + var array = className.Split('.'); + foreach (var item in UtilMethods.EnumToDictionary()) + { + if (array.Last().StartsWith(item.Value.ToString())) + { + + var newName = array.First() + "." + item.Value.ToString() + "." + array.Last(); + type = GetCustomTypeByClass(newName); + break; + } + } + + } + + return type; + } + + internal static Type GetCustomTypeByClass(string className) + { + Type type = null; + foreach (var item in CustomDlls.ToArray()) + { + if (type == null) + { + type = GetCustomTypeByClass(className, item); + } + if (type != null) + { + break; + } + } + return type; + } + internal static Type GetCustomTypeByClass(string className, string customDllName) + { + var key = "Assembly_" + customDllName + assembly.GetHashCode(); + var newAssembly = new ReflectionInoCacheService().GetOrCreate(key, () => + { + try + { + if (CustomAssemblies?.Any(it => it.FullName.StartsWith(customDllName)) == true) + { + return CustomAssemblies?.First(it => it.FullName.StartsWith(customDllName)); + } + var path = Assembly.GetExecutingAssembly().Location; + if (path.HasValue()) + { + path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), customDllName + ".dll"); + } + if (path.HasValue() && FileHelper.IsExistFile(path)) + { + return Assembly.LoadFrom(path); + } + else + { + return Assembly.LoadFrom(customDllName + ".dll"); + } + } + catch + { + var message = "Not Found " + customDllName + ".dll"; + Check.Exception(true, message); + return null; + } + }); + Type type = newAssembly.GetType(className); + if (type == null) + { + type = assembly.GetType(className); + } + return type; + } + internal static Type GetCustomTypeByClass(string className) + { + Type type = null; + foreach (var item in CustomDlls.ToArray()) + { + if (type == null) + { + type = GetCustomTypeByClass(className, item); + } + if (type != null) + { + break; + } + } + return type; + } + internal static Type GetCustomTypeByClass(string className, string customDllName) + { + var key = "Assembly_" + customDllName + assembly.GetHashCode(); + var newAssembly = new ReflectionInoCacheService().GetOrCreate(key, () => + { + try + { + if (CustomAssemblies?.Any(it => it.FullName.StartsWith(customDllName)) == true) + { + return CustomAssemblies?.First(it => it.FullName.StartsWith(customDllName)); + } + var path = Assembly.GetExecutingAssembly().Location; + if (path.HasValue()) + { + path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), customDllName + ".dll"); + } + if (path.HasValue() && FileHelper.IsExistFile(path)) + { + return Assembly.LoadFrom(path); + } + else + { + return Assembly.LoadFrom(customDllName + ".dll"); + } + } + catch + { + var message = "Not Found " + customDllName + ".dll"; + Check.Exception(true, message); + return null; + } + }); + Type typeArgument = typeof(T); + string fullTypeName = className + "[[" + typeArgument.FullName + "," + typeArgument.Assembly.FullName + "]]"; + Type type = newAssembly.GetType(fullTypeName); + return type; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/Mapper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/Mapper.cs new file mode 100644 index 000000000..05c07ade7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/Mapper.cs @@ -0,0 +1,73 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public class SugarMapper + { + private ISqlSugarClient _context; + public SugarMapper(ISqlSugarClient context) + { + _context = context; + } + + public string GetSelectValue(QueryBuilder queryBuilder) + { + string result = string.Empty; + var veiwModel = _context.EntityMaintenance.GetEntityInfo(); + var exp = (queryBuilder.JoinExpression as LambdaExpression); + List> selectItems = new List>(); + var exParsmeters = exp.Parameters.Select(it => new { shortName = it.Name, type = it.Type }).ToList(); + foreach (var viewColumns in veiwModel.Columns) + { + var isbreak = false; + foreach (var expPars in exParsmeters) + { + if (isbreak) + { + break; + } + var entityInfo = _context.EntityMaintenance.GetEntityInfo(expPars.type); + var columns = entityInfo.Columns.Where(it => it.IsIgnore == false); + var list = columns.Select(it => + { + var array = new string[] + { + it.PropertyName, + it.DbColumnName, + + expPars.type.Name+it.PropertyName, + expPars.type.Name+it.DbColumnName, + + expPars.type.Name+"_"+it.PropertyName, + expPars.type.Name+"_"+it.DbColumnName, + + expPars.shortName+it.PropertyName, + expPars.shortName+it.DbColumnName, + }; + return new { it, array }; + }).ToList(); + var columnInfo = list.FirstOrDefault(y => y.array.Select(z => z.ToLower()).Contains(viewColumns.PropertyName.ToLower())); + if (columnInfo != null) + { + JoinMapper joinMapper = new JoinMapper() + { + AsName = viewColumns.PropertyName, + DbName = columnInfo.it.DbColumnName + }; + //var isNoPgAuto = queryBuilder.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLower == false; + //var isNoUpper = this._context.CurrentConnectionConfig?.MoreSettings?.IsAutoToUpper == false; + var shortName = queryBuilder.Builder.GetTranslationColumnName(expPars.shortName); + selectItems.Add(new KeyValuePair(shortName, joinMapper)); + isbreak = true; + } + } + } + result = queryBuilder.GetSelectByItems(selectItems); + //if (_context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + //{ + // result = result.ToLower(); + //} + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/StaticConfig.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/StaticConfig.cs new file mode 100644 index 000000000..4346c089c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Infrastructure/StaticConfig.cs @@ -0,0 +1,38 @@ +namespace SqlSugar +{ + public static class StaticConfig + { + public static bool EnableAot { get; set; } + public static Func Encode { get; set; } + public static Func Decode { get; set; } + public static bool AppContext_ConvertInfinityDateTime { get; set; } + + public const string CodeFirst_BigString = "varcharmax,longtext,text,clob"; + public static string CodeFirst_MySqlCollate { get; set; } + public static string CodeFirst_MySqlTableEngine { get; set; } + public static Type Backup_MySqlBackupType { get; set; } + + public static Func CustomSnowFlakeFunc; + public static Func CustomSnowFlakeTimeErrorFunc; + public static Func CustomGuidFunc; + public static Func CustomGuidByValueFunc; + + public static Action CompleteQueryableFunc; + public static Action CompleteInsertableFunc; + public static Action CompleteUpdateableFunc; + public static Action CompleteDeleteableFunc; + public static Action CompleteDbFunc; + + public static Func> SplitTableGetTablesFunc; + public static Action SplitTableCreateTableFunc; + + public static bool Check_StringIdentity = true; + public static bool EnableAllWhereIF = false; + public static Func Check_FieldFunc; + public static Type DynamicExpressionParserType; + public static object DynamicExpressionParsingConfig; + public static Action CacheRemoveByLikeStringFunc { get; set; } + public static Guid TableQuerySqlKey { get; set; } + public static string BulkCopy_MySqlCsvPath { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/CacheService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/CacheService.cs new file mode 100644 index 000000000..3fa84aee8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/CacheService.cs @@ -0,0 +1,139 @@ +namespace SqlSugar +{ + public class ReflectionInoCacheService : ICacheService + { + public void Add(string key, V value) + { + ReflectionInoCore.GetInstance().Add(key, value); + } + public void Add(string key, V value, int cacheDurationInSeconds) + { + ReflectionInoCore.GetInstance().Add(key, value, cacheDurationInSeconds); + } + + public bool ContainsKey(string key) + { + return ReflectionInoCore.GetInstance().ContainsKey(key); + } + + public V Get(string key) + { + return ReflectionInoCore.GetInstance().Get(key); + } + + public IEnumerable GetAllKey() + { + return ReflectionInoCore.GetInstance().GetAllKey(); + } + + public V GetOrCreate(string cacheKey, Func create, int cacheDurationInSeconds = int.MaxValue) + { + return ReflectionInoCore.GetInstance().GetOrCreate(cacheKey, create); + } + + public void Remove(string key) + { + ReflectionInoCore.GetInstance().Remove(key); + } + } + public class ReflectionInoCore + { + readonly System.Collections.Concurrent.ConcurrentDictionary InstanceCache = new System.Collections.Concurrent.ConcurrentDictionary(); + private static ReflectionInoCore _instance = null; + private static readonly object _instanceLock = new object(); + private ReflectionInoCore() { } + + public V this[string key] + { + get + { + return this.Get(key); + } + } + + public bool ContainsKey(string key) + { + return this.InstanceCache.ContainsKey(key); + } + + public V Get(string key) + { + if (this.ContainsKey(key)) + return this.InstanceCache[key]; + else + return default(V); + } + + public static ReflectionInoCore GetInstance() + { + if (_instance == null) + lock (_instanceLock) + if (_instance == null) + { + _instance = new ReflectionInoCore(); + Action addItem = () => { ReflectionInoCore.GetInstance().RemoveAllCache(); }; + ReflectionInoHelper.AddRemoveFunc(addItem); + } + return _instance; + } + + public void Add(string key, V value) + { + this.InstanceCache.GetOrAdd(key, value); + } + + public void Add(string key, V value, int cacheDurationInSeconds) + { + Check.ThrowNotSupportedException("ReflectionInoCache.Add(string key, V value, int cacheDurationInSeconds)"); + } + + public void Remove(string key) + { + V val; + this.InstanceCache.TryRemove(key, out val); + } + + public void RemoveAllCache() + { + foreach (var key in GetAllKey()) + { + this.Remove(key); + } + } + + public IEnumerable GetAllKey() + { + return this.InstanceCache.Keys; + } + + public V GetOrCreate(string cacheKey, Func create) + { + if (this.ContainsKey(cacheKey)) return Get(cacheKey); + else + { + var reval = create(); + this.Add(cacheKey, reval); + return reval; + } + } + } + internal static class ReflectionInoHelper + { + private static List removeActions = new List(); + internal static void AddRemoveFunc(Action removeAction) + { + removeActions.Add(removeAction); + } + + public static void RemoveAllCache() + { + lock (removeActions) + { + foreach (var item in removeActions) + { + item(); + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/SerializeService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/SerializeService.cs new file mode 100644 index 000000000..d1f152321 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/SerializeService.cs @@ -0,0 +1,105 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace SqlSugar +{ + public class SerializeService : ISerializeService + { + public string SerializeObject(object value) + { + if (value?.GetType().FullName.StartsWith("System.Text.Json.") == true) + { + // 动态创建一个 JsonSerializer 实例 + Type serializerType = value.GetType().Assembly.GetType("System.Text.Json.JsonSerializer"); + + var methods = serializerType + .GetMyMethod("Serialize", 2); + + // 调用 SerializeObject 方法序列化对象 + string json = (string)methods.MakeGenericMethod(value.GetType()) + .Invoke(null, new object[] { value, null }); + return json; + } + return JsonConvert.SerializeObject(value); + } + + public string SugarSerializeObject(object value) + { + return JsonConvert.SerializeObject(value, new JsonSerializerSettings() + { + ContractResolver = new MyContractResolver() + }); + } + + public T DeserializeObject(string value) + { + if (typeof(T).FullName.StartsWith("System.Text.Json.")) + { + // 动态创建一个 JsonSerializer 实例 + Type serializerType = typeof(T).Assembly.GetType("System.Text.Json.JsonSerializer"); + + var methods = serializerType + .GetMethods().Where(it => it.Name == "Deserialize") + .Where(it => it.GetParameters().Any(z => z.ParameterType == typeof(string))).First(); + + // 调用 SerializeObject 方法序列化对象 + T json = (T)methods.MakeGenericMethod(typeof(T)) + .Invoke(null, new object[] { value, null }); + return json; + } + var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + return JsonConvert.DeserializeObject(value, jSetting); + } + } + public class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver + { + + + public MyContractResolver() + { + + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + if (type.IsAnonymousType() || type == UtilConstants.ObjType || type.Namespace == "SqlSugar" || type.IsClass() == false) + { + return base.CreateProperties(type, memberSerialization); + } + else + { + var list = type.GetProperties() + .Where(x => !x.GetCustomAttributes(true).Any(a => (a is SugarColumn) && ((SugarColumn)a).NoSerialize == true)) + .Select(p => new JsonProperty() + { + PropertyName = p.Name, + PropertyType = p.PropertyType, + Readable = true, + Writable = true, + ValueProvider = base.CreateMemberValueProvider(p) + }).ToList(); + foreach (var item in list) + { + if (UtilMethods.GetUnderType(item.PropertyType) == UtilConstants.DateType) + { + CreateDateProperty(type, item); + } + } + return list; + } + } + + private static void CreateDateProperty(Type type, JsonProperty item) + { + var property = type.GetProperties().Where(it => it.Name == item.PropertyName).First(); + var itemType = UtilMethods.GetUnderType(property); + if (property.GetCustomAttributes(true).Any(it => it is SugarColumn)) + { + var sugarAttribute = (SugarColumn)property.GetCustomAttributes(true).First(it => it is SugarColumn); + item.Converter = new IsoDateTimeConverter() { DateTimeFormat = sugarAttribute.SerializeDateTimeFormat }; + } + } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/SplitTableService.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/SplitTableService.cs new file mode 100644 index 000000000..ff0aeb7aa --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/IntegrationServices/SplitTableService.cs @@ -0,0 +1,274 @@ +using System.Globalization; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class DateSplitTableService : ISplitTableService + { + #region Core + public virtual List GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List tableInfos) + { + CheckTableName(EntityInfo.DbTableName); + var regex = "^" + EntityInfo.DbTableName.Replace("{year}", "([0-9]{2,4})").Replace("{day}", "([0-9]{1,2})").Replace("{month}", "([0-9]{1,2})"); + var currentTables = tableInfos.Where(it => Regex.IsMatch(it.Name, regex, RegexOptions.IgnoreCase)).Select(it => it.Name).Reverse().ToList(); + List result = new List(); + foreach (var item in currentTables) + { + SplitTableInfo tableInfo = new SplitTableInfo(); + tableInfo.TableName = item; + var math = Regex.Match(item, regex, RegexOptions.IgnoreCase); + var group1 = math.Groups[1].Value; + var group2 = math.Groups[2].Value; + var group3 = math.Groups[3].Value; + tableInfo.Date = GetDate(group1, group2, group3, EntityInfo.DbTableName); + //tableInfo.String = null; Time table, it doesn't work + //tableInfo.Long = null; Time table, it doesn't work + result.Add(tableInfo); + } + result = result.OrderByDescending(it => it.Date).ToList(); + return result; + } + public virtual string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo) + { + var splitTableAttribute = EntityInfo.Type.GetCustomAttribute(); + if (splitTableAttribute != null) + { + var type = (splitTableAttribute as SplitTableAttribute).SplitType; + return GetTableName(db, EntityInfo, type); + } + else + { + return GetTableName(db, EntityInfo, SplitType.Day); + } + } + public virtual string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo, SplitType splitType) + { + var date = db.GetDate(); + return GetTableNameByDate(EntityInfo, splitType, date); + } + public virtual string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue) + { + var value = Convert.ToDateTime(fieldValue); + return GetTableNameByDate(entityInfo, splitType, value); + } + public virtual object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue) + { + var splitColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.GetCustomAttribute() != null); + if (splitColumn == null) + { + return db.GetDate(); + } + else + { + if (entityValue == null) + { + return null; + } + var value = splitColumn.PropertyInfo.GetValue(entityValue, null); + if (value == null) + { + return db.GetDate(); + } + else if (value is DateTimeOffset) + { + return ((DateTimeOffset)value).DateTime; + } + else if (UtilMethods.GetUnderType(value.GetType()) != UtilConstants.DateType) + { + throw new Exception($"DateSplitTableService Split column {splitColumn.PropertyName} not DateTime " + splitType.ToString()); + } + else if (Convert.ToDateTime(value) == DateTime.MinValue) + { + return db.GetDate(); + } + else + { + return value; + } + } + } + public void VerifySplitType(SplitType splitType) + { + switch (splitType) + { + case SplitType.Day: + break; + case SplitType.Week: + break; + case SplitType.Month: + break; + case SplitType.Season: + break; + case SplitType.Year: + break; + case SplitType.Month_6: + break; + default: + throw new Exception("DateSplitTableService no support " + splitType.ToString()); + } + } + + #endregion + + #region Common Helper + private string GetTableNameByDate(EntityInfo EntityInfo, SplitType splitType, DateTime date) + { + date = ConvertDateBySplitType(date, splitType); + return EntityInfo.DbTableName.Replace("{year}", date.Year + "").Replace("{day}", PadLeft2(date.Day + "")).Replace("{month}", PadLeft2(date.Month + "")); + } + + private DateTime GetDate(string group1, string group2, string group3, string dbTableName) + { + var yearIndex = dbTableName.IndexOf("{year}"); + var dayIndex = dbTableName.IndexOf("{day}"); + var monthIndex = dbTableName.IndexOf("{month}"); + List tables = new List(); + tables.Add(new SplitTableSort() { Name = "{year}", Sort = yearIndex }); + tables.Add(new SplitTableSort() { Name = "{day}", Sort = dayIndex }); + tables.Add(new SplitTableSort() { Name = "{month}", Sort = monthIndex }); + tables = tables.OrderBy(it => it.Sort).ToList(); + var year = ""; + var month = ""; + var day = ""; + if (tables[0].Name == "{year}") + { + year = group1; + } + if (tables[1].Name == "{year}") + { + year = group2; + } + if (tables[2].Name == "{year}") + { + year = group3; + } + if (tables[0].Name == "{month}") + { + month = group1; + } + if (tables[1].Name == "{month}") + { + month = group2; + } + if (tables[2].Name == "{month}") + { + month = group3; + } + if (tables[0].Name == "{day}") + { + day = group1; + } + if (tables[1].Name == "{day}") + { + day = group2; + } + if (tables[2].Name == "{day}") + { + day = group3; + } + return Convert.ToDateTime($"{year}-{month}-{day}", CultureInfo.InvariantCulture); + } + + private string PadLeft2(string str) + { + if (str.Length < 2) + { + return str.PadLeft(2, '0'); + } + else + { + return str; + } + } + + private static void CheckTableName(string dbTableName) + { + Check.Exception(!dbTableName.Contains("{year}"), ErrorMessage.GetThrowMessage("table name need {{year}}", "分表表名需要占位符 {{year}}")); + Check.Exception(!dbTableName.Contains("{month}"), ErrorMessage.GetThrowMessage("table name need {{month}}", "分表表名需要占位符 {{month}} ")); + Check.Exception(!dbTableName.Contains("{day}"), ErrorMessage.GetThrowMessage("table name need {{day}}", "分表表名需要占位符{{day}}")); + Check.Exception(Regex.Matches(dbTableName, @"\{year\}").Count > 1, ErrorMessage.GetThrowMessage(" There can only be one {{year}}", " 只能有一个 {{year}}")); + Check.Exception(Regex.Matches(dbTableName, @"\{month\}").Count > 1, ErrorMessage.GetThrowMessage("There can only be one {{month}}", "只能有一个 {{month}} ")); + Check.Exception(Regex.Matches(dbTableName, @"\{day\}").Count > 1, ErrorMessage.GetThrowMessage("There can only be one {{day}}", "只能有一个{{day}}")); + Check.Exception(Regex.IsMatch(dbTableName, @"\d\{|\}\d"), ErrorMessage.GetThrowMessage(" '{{' or '}}' can't be numbers nearby", "占位符相令一位不能是数字,比如 : 1{{day}}2 错误 , 正确: 1_{{day}}_2")); + } + #endregion + + #region Date Helper + private DateTime ConvertDateBySplitType(DateTime time, SplitType type) + { + switch (type) + { + case SplitType.Day: + return Convert.ToDateTime(time.ToString("yyyy-MM-dd")); + case SplitType.Week: + return GetMondayDate(time); + case SplitType.Month: + return Convert.ToDateTime(time.ToString("yyyy-MM-01")); + case SplitType.Season: + if (time.Month <= 3) + { + return Convert.ToDateTime(time.ToString("yyyy-01-01")); + } + else if (time.Month <= 6) + { + return Convert.ToDateTime(time.ToString("yyyy-04-01")); + } + else if (time.Month <= 9) + { + return Convert.ToDateTime(time.ToString("yyyy-07-01")); + } + else + { + return Convert.ToDateTime(time.ToString("yyyy-10-01")); + } + case SplitType.Year: + return Convert.ToDateTime(time.ToString("yyyy-01-01")); + case SplitType.Month_6: + if (time.Month <= 6) + { + return Convert.ToDateTime(time.ToString("yyyy-01-01")); + } + else + { + return Convert.ToDateTime(time.ToString("yyyy-07-01")); + } + default: + throw new Exception($"SplitType parameter error "); + } + } + private DateTime GetMondayDate() + { + return GetMondayDate(DateTime.Now); + } + private DateTime GetSundayDate() + { + return GetSundayDate(DateTime.Now); + } + private DateTime GetMondayDate(DateTime someDate) + { + int i = someDate.DayOfWeek - DayOfWeek.Monday; + if (i == -1) i = 6; + TimeSpan ts = new TimeSpan(i, 0, 0, 0); + return someDate.Subtract(ts); + } + private DateTime GetSundayDate(DateTime someDate) + { + int i = someDate.DayOfWeek - DayOfWeek.Sunday; + if (i != 0) i = 7 - i; + TimeSpan ts = new TimeSpan(i, 0, 0, 0); + return someDate.Add(ts); + } + + #endregion + + #region Private Models + internal class SplitTableSort + { + public string Name { get; set; } + public int Sort { get; set; } + } + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IAdo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IAdo.cs new file mode 100644 index 000000000..b0de6f662 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IAdo.cs @@ -0,0 +1,198 @@ +using System.Data; +using System.Data.Common; +using System.Reflection; + +namespace SqlSugar +{ + public partial interface IAdo + { + string SqlParameterKeyWord { get; } + IDbConnection Connection { get; set; } + IDbTransaction Transaction { get; set; } + IDataParameter[] ToIDbDataParameter(params SugarParameter[] pars); + SugarParameter[] GetParameters(object obj, PropertyInfo[] propertyInfo = null); + SqlSugarProvider Context { get; set; } + void CheckConnectionAfter(IDbConnection Connection); + void CheckConnectionBefore(IDbConnection Connection); + void ExecuteBefore(string sql, SugarParameter[] pars); + void ExecuteAfter(string sql, SugarParameter[] pars); + void GetDataBefore(string sql, SugarParameter[] parameters); + void GetDataAfter(string sql, SugarParameter[] parameters); + bool IsAnyTran(); + bool IsNoTran(); + bool IsEnableLogEvent { get; set; } + StackTraceInfo SqlStackTrace { get; } + IDataParameterCollection DataReaderParameters { get; set; } + CommandType CommandType { get; set; } + CancellationToken? CancellationToken { get; set; } + bool IsDisableMasterSlaveSeparation { get; set; } + bool IsClearParameters { get; set; } + int CommandTimeOut { get; set; } + TimeSpan SqlExecutionTime { get; } + TimeSpan ConnectionExecutionTime { get; } + int SqlExecuteCount { get; } + SugarActionType SqlExecuteType { get; } + IDbBind DbBind { get; } + void SetCommandToAdapter(IDataAdapter adapter, DbCommand command); + IDataAdapter GetAdapter(); + DbCommand GetCommand(string sql, SugarParameter[] parameters); + + + DataTable GetDataTable(string sql, object parameters); + DataTable GetDataTable(string sql, params SugarParameter[] parameters); + DataTable GetDataTable(string sql, List parameters); + + Task GetDataTableAsync(string sql, object parameters); + Task GetDataTableAsync(string sql, params SugarParameter[] parameters); + Task GetDataTableAsync(string sql, List parameters); + + DataSet GetDataSetAll(string sql, object parameters); + DataSet GetDataSetAll(string sql, params SugarParameter[] parameters); + DataSet GetDataSetAll(string sql, List parameters); + + Task GetDataSetAllAsync(string sql, object parameters); + Task GetDataSetAllAsync(string sql, params SugarParameter[] parameters); + Task GetDataSetAllAsync(string sql, List parameters); + + IDataReader GetDataReader(string sql, object parameters); + IDataReader GetDataReader(string sql, params SugarParameter[] parameters); + IDataReader GetDataReader(string sql, List parameters); + + + Task GetDataReaderAsync(string sql, object parameters); + Task GetDataReaderAsync(string sql, params SugarParameter[] parameters); + Task GetDataReaderAsync(string sql, List parameters); + + + object GetScalar(string sql, object parameters); + object GetScalar(string sql, params SugarParameter[] parameters); + object GetScalar(string sql, List parameters); + + Task GetScalarAsync(string sql, object parameters); + Task GetScalarAsync(string sql, params SugarParameter[] parameters); + Task GetScalarAsync(string sql, List parameters); + + int ExecuteCommandWithGo(string sql, params SugarParameter[] parameters); + int ExecuteCommand(string sql, object parameters); + int ExecuteCommand(string sql, params SugarParameter[] parameters); + int ExecuteCommand(string sql, List parameters); + + Task ExecuteCommandAsync(string sql, params SugarParameter[] parameters); + Task ExecuteCommandAsync(string sql, object parameters); + Task ExecuteCommandAsync(string sql, object parameters, CancellationToken cancellationToken); + Task ExecuteCommandAsync(string sql, List parameters); + + string GetString(string sql, object parameters); + string GetString(string sql, params SugarParameter[] parameters); + string GetString(string sql, List parameters); + Task GetStringAsync(string sql, object parameters); + Task GetStringAsync(string sql, params SugarParameter[] parameters); + Task GetStringAsync(string sql, List parameters); + + + int GetInt(string sql, object pars); + int GetInt(string sql, params SugarParameter[] parameters); + int GetInt(string sql, List parameters); + + Task GetIntAsync(string sql, object pars); + Task GetIntAsync(string sql, params SugarParameter[] parameters); + Task GetIntAsync(string sql, List parameters); + + + long GetLong(string sql, object pars = null); + + Task GetLongAsync(string sql, object pars = null); + + + Double GetDouble(string sql, object parameters); + Double GetDouble(string sql, params SugarParameter[] parameters); + Double GetDouble(string sql, List parameters); + + + Task GetDoubleAsync(string sql, object parameters); + Task GetDoubleAsync(string sql, params SugarParameter[] parameters); + Task GetDoubleAsync(string sql, List parameters); + + + decimal GetDecimal(string sql, object parameters); + decimal GetDecimal(string sql, params SugarParameter[] parameters); + decimal GetDecimal(string sql, List parameters); + + Task GetDecimalAsync(string sql, object parameters); + Task GetDecimalAsync(string sql, params SugarParameter[] parameters); + Task GetDecimalAsync(string sql, List parameters); + + + DateTime GetDateTime(string sql, object parameters); + DateTime GetDateTime(string sql, params SugarParameter[] parameters); + DateTime GetDateTime(string sql, List parameters); + + Task GetDateTimeAsync(string sql, object parameters); + Task GetDateTimeAsync(string sql, params SugarParameter[] parameters); + Task GetDateTimeAsync(string sql, List parameters); + + + Tuple, List> SqlQuery(string sql, object parameters = null); + Tuple, List, List> SqlQuery(string sql, object parameters = null); + Tuple, List, List, List> SqlQuery(string sql, object parameters = null); + Tuple, List, List, List, List> SqlQuery(string sql, object parameters = null); + Tuple, List, List, List, List, List> SqlQuery(string sql, object parameters = null); + Tuple, List, List, List, List, List, List> SqlQuery(string sql, object parameters = null); + + Task, List>> SqlQueryAsync(string sql, object parameters = null); + Task, List, List>> SqlQueryAsync(string sql, object parameters = null); + Task, List, List, List>> SqlQueryAsync(string sql, object parameters = null); + Task, List, List, List, List>> SqlQueryAsync(string sql, object parameters = null); + Task, List, List, List, List, List>> SqlQueryAsync(string sql, object parameters = null); + Task, List, List, List, List, List, List>> SqlQueryAsync(string sql, object parameters = null); + + List SqlQuery(string sql, object parameters = null); + List SqlQuery(string sql, params SugarParameter[] parameters); + List SqlQuery(string sql, List parameters); + Task> MasterSqlQueryAasync(string sql, object parameters = null); + List MasterSqlQuery(string sql, object parameters = null); + + Task> SqlQueryAsync(string sql, object parameters = null); + Task> SqlQueryAsync(string sql, object parameters, CancellationToken token); + Task> SqlQueryAsync(string sql, List parameters); + Task> SqlQueryAsync(string sql, params SugarParameter[] parameters); + + T SqlQuerySingle(string sql, object whereObj = null); + T SqlQuerySingle(string sql, params SugarParameter[] parameters); + T SqlQuerySingle(string sql, List parameters); + + Task SqlQuerySingleAsync(string sql, object whereObj = null); + Task SqlQuerySingleAsync(string sql, params SugarParameter[] parameters); + Task SqlQuerySingleAsync(string sql, List parameters); + + void RemoveCancellationToken(); + + void Dispose(); + void Close(); + Task CloseAsync(); + void Open(); + Task OpenAsync(); + SugarConnection OpenAlways(); + bool IsValidConnection(); + bool IsValidConnectionNoClose(); + void CheckConnection(); + + void BeginTran(); + Task BeginTranAsync(); + Task BeginTranAsync(IsolationLevel iso); + void BeginTran(IsolationLevel iso); + void BeginTran(string transactionName); + void BeginTran(IsolationLevel iso, string transactionName); + void RollbackTran(); + Task RollbackTranAsync(); + void CommitTran(); + Task CommitTranAsync(); + SqlSugarTransactionAdo UseTran(); + DbResult UseTran(Action action, Action errorCallBack = null); + DbResult UseTran(Func action, Action errorCallBack = null); + Task> UseTranAsync(Func action, Action errorCallBack = null); + Task> UseTranAsync(Func> action, Action errorCallBack = null); + IAdo UseStoredProcedure(); + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ICodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ICodeFirst.cs new file mode 100644 index 000000000..22132da6e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ICodeFirst.cs @@ -0,0 +1,26 @@ +namespace SqlSugar +{ + public partial interface ICodeFirst + { + SqlSugarProvider Context { get; set; } + ICodeFirst BackupTable(int maxBackupDataRows = int.MaxValue); + ICodeFirst SetStringDefaultLength(int length); + + ICodeFirst As(Type type, string newTableName); + ICodeFirst As(string newTableName); + + void InitTables(string entitiesNamespace); + void InitTables(string[] entitiesNamespaces); + void InitTables(params Type[] entityTypes); + void InitTablesWithAttr(params Type[] entityTypes); + void InitTables(Type entityType); + void InitTables(); + void InitTables(); + void InitTables(); + void InitTables(); + void InitTables(); + SplitCodeFirstProvider SplitTables(); + TableDifferenceProvider GetDifferenceTables(); + TableDifferenceProvider GetDifferenceTables(params Type[] types); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IContextMethods.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IContextMethods.cs new file mode 100644 index 000000000..3384c9163 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IContextMethods.cs @@ -0,0 +1,51 @@ +using System.Data; +using System.Dynamic; +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial interface IContextMethods + { + SqlSugarProvider Context { get; set; } + QueryBuilder QueryBuilder { get; set; } + List DataReaderToValueTupleType(IDataReader reader); + Task> DataReaderToValueTupleTypeAsync(IDataReader reader); + ExpandoObject DataReaderToExpandoObject(IDataReader reader); + List DataReaderToExpandoObjectList(IDataReader reader); + Task> DataReaderToExpandoObjectListAsync(IDataReader dataReader); + List DataReaderToExpandoObjectListNoUsing(IDataReader reader); + Task> DataReaderToExpandoObjectListAsyncNoUsing(IDataReader dataReader); + List DataReaderToList(IDataReader reader); + List DataReaderToSelectJsonList(IDataReader reader); + List DataReaderToSelectArrayList(IDataReader reader); + Task> DataReaderToSelectArrayListAsync(IDataReader reader); + Task> DataReaderToSelectJsonListAsync(IDataReader reader); + List DataReaderToListNoUsing(IDataReader reader); + Task> DataReaderToListAsync(IDataReader dataReader); + Task> DataReaderToListAsyncNoUsing(IDataReader dataReader); + string SerializeObject(object value); + string SerializeObject(object value, Type type); + T DeserializeObject(string value); + T TranslateCopy(T sourceObject); + SqlSugarProvider CopyContext(bool isCopyEvents = false); + dynamic DataTableToDynamic(DataTable table); + List DataTableToList(DataTable table); + DataTable ListToDataTable(List list); + DataTable ListToDataTableWithAttr(List list); + Dictionary DataTableToDictionary(DataTable table); + List> DataTableToDictionaryList(DataTable table); + ICacheService GetReflectionInoCacheInstance(); + void RemoveCacheAll(); + void RemoveCacheAll(); + void RemoveCacheByLikeKey(string key); + void RemoveCache(string key); + void PageEach(IEnumerable pageItems, int pageSize, Action> action); + Task PageEachAsync(IEnumerable pageItems, int pageSize, Func, Task> action); + Task PageEachAsync(IEnumerable pageItems, int pageSize, Func, Task> action); + List JsonToConditionalModels(string json); + DataTable DictionaryListToDataTable(List> dictionaryList); + List ToTree(List list, Expression>> childListExpression, Expression> parentIdExpression, Expression> pkExpression, object rootValue); + KeyValuePair ConditionalModelsToSql(List conditionalModels, int beginIndex = 0); + string EscapeLikeValue(string value, char wildcard = '%'); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ICustomConditionalFunc.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ICustomConditionalFunc.cs new file mode 100644 index 000000000..83065438e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ICustomConditionalFunc.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public interface ICustomConditionalFunc + { + KeyValuePair GetConditionalSql(ConditionalModel json, int index); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDMLBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDMLBuilder.cs new file mode 100644 index 000000000..cfb5f2a6d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDMLBuilder.cs @@ -0,0 +1,14 @@ +using System.Text; + +namespace SqlSugar +{ + public partial interface IDMLBuilder + { + string SqlTemplate { get; } + List Parameters { get; set; } + SqlSugarProvider Context { get; set; } + StringBuilder sql { get; set; } + string ToSqlString(); + void Clear(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbBind.cs new file mode 100644 index 000000000..aabdb9e64 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbBind.cs @@ -0,0 +1,28 @@ +using System.Data; + +namespace SqlSugar +{ + public partial interface IDbBind + { + QueryBuilder QueryBuilder { get; set; } + SqlSugarProvider Context { get; set; } + List GuidThrow { get; } + List IntThrow { get; } + List StringThrow { get; } + List DecimalThrow { get; } + List DoubleThrow { get; } + List DateThrow { get; } + List ShortThrow { get; } + string GetPropertyTypeName(string dbTypeName); + string GetConvertString(string dbTypeName); + string GetDbTypeName(string csharpTypeName); + string GetCsharpTypeName(string dbTypeName); + string GetCsharpTypeNameByDbTypeName(string dbTypeName); + List> MappingTypes { get; } + List DataReaderToList(Type type, IDataReader reader); + Task> DataReaderToListAsync(Type entityType, IDataReader dataReader); + List DataReaderToListNoUsing(Type type, IDataReader reader); + Task> DataReaderToListNoUsingAsync(Type type, IDataReader reader); + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbFirst.cs new file mode 100644 index 000000000..bf3890135 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbFirst.cs @@ -0,0 +1,29 @@ +namespace SqlSugar +{ + public partial interface IDbFirst + { + ISqlSugarClient Context { get; set; } + IDbFirst SettingClassTemplate(Func func); + IDbFirst SettingClassDescriptionTemplate(Func func); + IDbFirst SettingPropertyTemplate(Func func); + IDbFirst SettingPropertyTemplate(Func func); + IDbFirst SettingPropertyDescriptionTemplate(Func func); + IDbFirst SettingConstructorTemplate(Func func); + IDbFirst SettingNamespaceTemplate(Func func); + RazorFirst UseRazorAnalysis(string razorClassString, string classNamespace = "Models"); + IDbFirst IsCreateAttribute(bool isCreateAttribute = true); + IDbFirst IsCreateDefaultValue(bool isCreateDefaultValue = true); + IDbFirst Where(params string[] objectNames); + IDbFirst Where(Func func); + IDbFirst WhereColumns(Func func); + IDbFirst Where(DbObjectType dbObjectType); + void CreateClassFile(string directoryPath, string nameSpace = "Models"); + Dictionary ToClassStringList(string nameSpace = "Models"); + void Init(); + IDbFirst FormatFileName(Func formatFileNameFunc); + IDbFirst FormatClassName(Func formatClassNameFunc); + IDbFirst FormatPropertyName(Func formatPropertyNameFunc); + IDbFirst StringNullable(); + IDbFirst CreatedReplaceClassString(Func replaceClassStringFunc); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbMaintenance.cs new file mode 100644 index 000000000..e047bf591 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDbMaintenance.cs @@ -0,0 +1,113 @@ +namespace SqlSugar +{ + public partial interface IDbMaintenance + { + SqlSugarProvider Context { get; set; } + + #region DML + List GetDataBaseList(SqlSugarClient db); + List GetDataBaseList(); + List GetViewInfoList(bool isCache = true); + List GetTableInfoList(bool isCache = true); + List GetTableInfoList(Func getChangeSqlFunc); + List GetColumnInfosByTableName(string tableName, bool isCache = true); + List GetColumnInfosByTableName(string tableName, Func getChangeSqlFunc); + List GetIsIdentities(string tableName); + List GetPrimaries(string tableName); + List GetProcList(string dbName); + List GetProcList(); + List GetIndexList(string tableName); + List GetFuncList(); + List GetTriggerNames(string tableName); + List GetDbTypes(); + #endregion + + #region Check + bool IsAnyTable(); + bool IsAnyTable(string tableName, bool isCache = true); + bool IsAnyColumn(string tableName, string column, bool isCache = true); + bool IsPrimaryKey(string tableName, string column); + bool IsPrimaryKey(string tableName, string column, bool isCache = true); + bool IsIdentity(string tableName, string column); + bool IsAnyConstraint(string ConstraintName); + bool IsAnySystemTablePermissions(); + bool IsAnyProcedure(string procName); + #endregion + + #region DDL + bool AddDefaultValue(string tableName, string columnName, string defaultValue); + bool CreateIndex(string tableName, string[] columnNames, bool isUnique = false); + bool CreateIndex(string tableName, string[] columnNames, string IndexName, bool isUnique = false); + bool DropTable(string tableName); + bool DropView(string viewName); + bool DropIndex(string indexName); + bool DropIndex(string indexName, string tableName); + bool DropFunction(string funcName); + bool DropProc(string procName); + bool DropTable(params string[] tableName); + bool DropTable(params Type[] tableEntityTypes); + bool DropTable(); + bool DropTable(); + bool DropTable(); + bool DropTable(); + bool TruncateTable(string tableName); + bool TruncateTable(params string[] tableName); + bool TruncateTable(params Type[] tableEntityType); + bool TruncateTable(); + bool TruncateTable(); + bool TruncateTable(); + bool TruncateTable(); + bool TruncateTable(); + bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true); + bool AddColumn(string tableName, DbColumnInfo column); + bool UpdateColumn(string tableName, DbColumnInfo column); + bool AddPrimaryKey(string tableName, string columnName); + bool AddPrimaryKeys(string tableName, string[] columnNames); + bool AddPrimaryKeys(string tableName, string[] columnNames, string pkName); + bool DropConstraint(string tableName, string constraintName); + bool BackupDataBase(string databaseName, string fullFileName); + bool BackupTable(string oldTableName, string newTableName, int maxBackupDataRows = int.MaxValue); + bool DropColumn(string tableName, string columnName); + bool RenameColumn(string tableName, string oldColumnName, string newColumnName); + bool AddRemark(EntityInfo entity); + void AddIndex(EntityInfo entityInfo); + void AddDefaultValue(EntityInfo entityInfo); + bool IsAnyDefaultValue(string tableName, string columnName); + bool IsAnyIndex(string indexName); + bool AddColumnRemark(string columnName, string tableName, string description); + bool DeleteColumnRemark(string columnName, string tableName); + bool IsAnyColumnRemark(string columnName, string tableName); + bool AddTableRemark(string tableName, string description); + bool DeleteTableRemark(string tableName); + bool IsAnyTableRemark(string tableName); + bool RenameTable(string oldTableName, string newTableName); + /// + ///by current connection string + /// + /// + /// + bool CreateDatabase(string databaseDirectory = null); + /// + /// by databaseName + /// + /// + /// + /// + bool CreateDatabase(string databaseName, string databaseDirectory = null); + /// + /// setAuto incrementInitial value + /// + /// + /// + /// + bool SetAutoIncrementInitialValue(Type type, int initialValue); + /// + /// setAuto incrementInitial value + /// + /// + /// + /// + bool SetAutoIncrementInitialValue(string tableName, int initialValue); + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDeleteable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDeleteable.cs new file mode 100644 index 000000000..072d6babb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IDeleteable.cs @@ -0,0 +1,52 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public interface IDeleteable where T : class, new() + { + DeleteBuilder DeleteBuilder { get; set; } + int ExecuteCommand(); + bool ExecuteCommandHasChange(); + Task ExecuteCommandAsync(); + Task ExecuteCommandAsync(CancellationToken token); + Task ExecuteCommandHasChangeAsync(); + IDeleteable AS(string tableName); + IDeleteable AsType(Type tableNameType); + IDeleteable With(string lockString); + IDeleteable Where(T deleteObj); + IDeleteable WhereIF(bool isWhere, Expression> expression); + IDeleteable Where(Expression> expression); + IDeleteable Where(List deleteObjs); + DeleteablePage PageSize(int pageSize); + IDeleteable In(PkType primaryKeyValue); + IDeleteable In(PkType[] primaryKeyValues); + IDeleteable In(List primaryKeyValues); + IDeleteable In(Expression> inField, PkType primaryKeyValue); + IDeleteable In(Expression> inField, PkType[] primaryKeyValues); + IDeleteable In(Expression> inField, List primaryKeyValues); + IDeleteable In(Expression> inField, ISugarQueryable childQueryExpression); + + IDeleteable In(string inField, List primaryKeyValues); + IDeleteable Where(string whereString, object parameters = null); + IDeleteable Where(string whereString, SugarParameter parameter); + IDeleteable Where(string whereString, SugarParameter[] parameters); + IDeleteable Where(string whereString, List parameters); + IDeleteable WhereColumns(T data, Expression> columns); + IDeleteable WhereColumns(List list, Expression> columns); + IDeleteable WhereColumns(List> columns); + IDeleteable Where(List conditionalModels); + IDeleteable Where(List conditionalModels, bool isWrap); + IDeleteable EnableDiffLogEventIF(bool isEnableDiffLogEvent, object businessData = null); + IDeleteable EnableDiffLogEvent(object businessData = null); + IDeleteable RemoveDataCache(); + IDeleteable RemoveDataCache(string likeString); + KeyValuePair> ToSql(); + string ToSqlString(); + IDeleteable EnableQueryFilter(); + IDeleteable EnableQueryFilter(Type type); + SplitTableDeleteProvider SplitTable(Func, IEnumerable> getTableNamesFunc); + SplitTableDeleteByObjectProvider SplitTable(); + LogicDeleteProvider IsLogic(); + void AddQueue(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFastBuilder.cs new file mode 100644 index 000000000..3691e4230 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFastBuilder.cs @@ -0,0 +1,18 @@ +using System.Data; + +namespace SqlSugar +{ + public interface IFastBuilder + { + EntityInfo FastEntityInfo { get; set; } + bool IsActionUpdateColumns { get; set; } + DbFastestProperties DbFastestProperties { get; set; } + SqlSugarProvider Context { get; set; } + string CharacterSet { get; set; } + Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns); + Task ExecuteBulkCopyAsync(DataTable dt); + Task CreateTempAsync(DataTable dt) where T : class, new(); + void CloseDb(); + Task Merge(string tableName, DataTable dt, EntityInfo entityInfo, string[] whereColumns, string[] updateColumns, List datas) where T : class, new(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFastest.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFastest.cs new file mode 100644 index 000000000..6c67b09d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFastest.cs @@ -0,0 +1,45 @@ +using System.Data; + +namespace SqlSugar +{ + public interface IFastest where T : class, new() + { + IFastest RemoveDataCache(); + IFastest RemoveDataCache(string cacheKey); + IFastest AS(string tableName); + IFastest PageSize(int Size); + IFastest OffIdentity(); + IFastest SetCharacterSet(string CharacterSet); + IFastest EnableDataAop(); + int BulkCopy(List datas); + Task BulkCopyAsync(List datas); + int BulkCopy(string tableName, DataTable dataTable); + int BulkCopy(DataTable dataTable); + Task BulkCopyAsync(string tableName, DataTable dataTable); + Task BulkCopyAsync(DataTable dataTable); + + int BulkUpdate(List datas); + Task BulkUpdateAsync(List datas); + int BulkUpdate(List datas, string[] whereColumns, string[] updateColumns); + int BulkUpdate(List datas, string[] whereColumns); + Task BulkUpdateAsync(List datas, string[] whereColumns); + Task BulkUpdateAsync(List datas, string[] whereColumns, string[] updateColumns); + int BulkUpdate(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns); + int BulkUpdate(DataTable dataTable, string[] whereColumns, string[] updateColumns); + int BulkUpdate(DataTable dataTable, string[] whereColumns); + Task BulkUpdateAsync(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns); + Task BulkUpdateAsync(DataTable dataTable, string[] whereColumns); + SplitFastest SplitTable(); + Task BulkMergeAsync(List datas); + int BulkMerge(List datas); + int BulkMerge(DataTable dataTable, string[] whereColumns, bool isIdentity); + Task BulkMergeAsync(DataTable dataTable, string[] whereColumns, bool isIdentity); + int BulkMerge(DataTable dataTable, string[] whereColumns, string[] updateColumns, bool isIdentity); + Task BulkMergeAsync(DataTable dataTable, string[] whereColumns, string[] updateColumns, bool isIdentity); + Task BulkMergeAsync(List datas, string[] whereColumns); + int BulkMerge(List datas, string[] whereColumns); + Task BulkMergeAsync(List datas, string[] whereColumns, string[] updateColumns); + int BulkMerge(List datas, string[] whereColumns, string[] updateColumns); + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFilter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFilter.cs new file mode 100644 index 000000000..376899211 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IFilter.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public interface IFilter + { + IFilter Add(SqlFilterItem filter); + void Remove(string filterName); + List GetFilterList { get; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IIncludes.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IIncludes.cs new file mode 100644 index 000000000..eefb14e99 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IIncludes.cs @@ -0,0 +1,286 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + /// + /// Includes + /// + /// + public partial interface ISugarQueryable + { + NavISugarQueryable AsNavQueryable(); + ISugarQueryable IncludesByExpression2(Expression include1, Expression include2); + ISugarQueryable IncludesByExpression(Expression include1); + ISugarQueryable IncludesByNameString(string navMemberName); + ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2); + ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2, string thenNavMemberName3); + ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2, string thenNavMemberName3, string thenNavMemberName4); + ISugarQueryable IncludesByNameString(string navMemberName, string thenNavMemberName2, string thenNavMemberName3, string thenNavMemberName4, string thenNavMemberName5); + ISugarQueryable IncludesAllFirstLayer(params string[] ignoreProperyNameList); + ISugarQueryable IncludesAllSecondLayer(Expression> expression, params string[] ignoreProperyNameList); + ISugarQueryable Includes(Expression>> include1); + ISugarQueryable Includes(Expression> include1); + ISugarQueryable Includes(Expression>> include1, Expression>> include2); + ISugarQueryable Includes(Expression>> include1, Expression> include2); + ISugarQueryable Includes(Expression> include1, Expression> include2); + ISugarQueryable Includes(Expression> include1, Expression>> include2); + NavISugarQueryable Includes(Expression>> include1, Expression>> include2, Expression>> include3); + NavISugarQueryable Includes(Expression>> include1, Expression>> include2, Expression> include3); + NavISugarQueryable Includes(Expression> include1, Expression>> include2, Expression> include3); + NavISugarQueryable Includes(Expression> include1, Expression> include2, Expression> include3); + NavISugarQueryable Includes(Expression>> include1, Expression> include2, Expression>> include3); + NavISugarQueryable Includes(Expression> include1, Expression> include2, Expression>> include3); + NavISugarQueryable Includes(Expression>> include1, Expression> include2, Expression> include3); + NavISugarQueryable Includes(Expression> include1, Expression>> include2, Expression>> include3); + + } + + /// + /// Includes + /// + /// + public partial interface NavISugarQueryable : ISugarQueryable + { + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression>> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression> include4, Expression>> include5, Expression> include6, Expression>> include7); + NavQueryableProvider Includes(Expression>> include1, Expression> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression>> include1, Expression>> include2, Expression>> include3, Expression> include4, Expression> include5, Expression> include6, Expression> include7); + NavQueryableProvider Includes(Expression> include1, Expression>> include2, Expression>> include3, Expression>> include4, Expression> include5, Expression>> include6, Expression> include7); + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IIncludes.txt b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IIncludes.txt new file mode 100644 index 000000000..df013e689 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IIncludes.txt @@ -0,0 +1,106 @@ + +List sourceNumbers = new List { 2, 4, 8, 16, 32, 64, 128 }; +var ram = new Random(); +foreach (var source in sourceNumbers) +{ + var index = sourceNumbers.IndexOf(source) + 1; + //Console.WriteLine("index=" + index); + + List> result = new List>(); + + string sb = ""; + List sb2 = new List(); + for (int i = 1; i <= source; i++) + { + + List test = new List(); + + List test2 = new List(); + for (int j = 1; j <= index; j++) + { + + test2.Add(new Test() { i = j, b = ram.Next(1, 222) % 2 == 0 }); + + + sb += $"[{test2.Last().b}:{test2.Last().i}]"; + //sb2 += $"[{test2.Last().b}:{test2.Last().i}]"; + if (j == index) + { + if (sb2.Count > 0 && sb2.Contains(sb)) + { + j = 0; + sb = ""; + test2 = new List(); + } + else + { + test.AddRange(test2.Select(x => new Test { b = x.b, i = x.i })); + sb2.Add(sb); + sb = ""; + } + } + + } + + test = test.OrderBy(it => it.i).ToList(); + result.Add(test); + + } + foreach (var test in result) + { + List res = new List(); + List res2 = new List(); + + foreach (var item in test) + { + if (item.i == 1) + { + if (item.b == false) + { + res.Add($"Expression>> include{item.i}"); + } + else + { + res.Add($"Expression> include{item.i}"); + } + + } + else + { + if (item.b == false) + { + res.Add($"Expression>> include{item.i}"); + } + else + { + res.Add($"Expression> include{item.i}"); + } + } + res2.Add("TReturn" + (item.i)); + } + + Console.WriteLine($"ISugarQueryable Includes<{string.Join(",", res2)}>({string.Join(",", res)});"); + } + //Console.WriteLine("--"); +} + +Console.ReadKey(); + +public class Test +{ + public bool b { get; set; } + public int i { get; set; } +} + + +//1:1 true + +//2: +// 1 true , 2 true +// 1 false , 2 true + +//3: +// 1 true , 2 true 3 true +// 1 true , 2 false 3 true +// 1 false , 2 false 3 true +// 1 false , 2 true 3 true diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ILambdaExpressions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ILambdaExpressions.cs new file mode 100644 index 000000000..b5a304e3e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ILambdaExpressions.cs @@ -0,0 +1,33 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public partial interface ILambdaExpressions + { + MappingColumnList MappingColumns { get; set; } + MappingTableList MappingTables { get; set; } + IgnoreColumnList IgnoreComumnList { get; set; } + List SqlFuncServices { get; set; } + + List JoinQueryInfos { get; set; } + bool IsSingle { get; set; } + SqlSugarProvider Context { get; set; } + IDbMethods DbMehtods { get; set; } + Expression Expression { get; set; } + int Index { get; set; } + int ParameterIndex { get; set; } + List Parameters { get; set; } + ExpressionResult Result { get; set; } + string SqlParameterKeyWord { get; } + string SingleTableNameSubqueryShortName { get; set; } + Action InitMappingInfo { get; set; } + Action RefreshMapping { get; set; } + bool PgSqlIsAutoToLower { get; set; } + Expression RootExpression { get; set; } + ExpressionOutParameter SugarContext { get; set; } + bool? TableEnumIsString { get; set; } + + string GetAsString(string fieldName, string fieldValue); + void Resolve(Expression expression, ResolveExpressType resolveType); + void Clear(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IParameterInsertable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IParameterInsertable.cs new file mode 100644 index 000000000..5a6c42a7b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IParameterInsertable.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public interface IParameterInsertable + { + int ExecuteCommand(); + Task ExecuteCommandAsync(); + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IQueryable.cs new file mode 100644 index 000000000..d94a9ef0d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IQueryable.cs @@ -0,0 +1,1970 @@ +using System.Data; +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial interface ISugarQueryable + { + SqlSugarProvider Context { get; set; } + ISqlBuilder SqlBuilder { get; set; } + QueryBuilder QueryBuilder { get; set; } + bool IsCache { get; set; } + int CacheTime { get; set; } + ISugarQueryable Clone(); + ISugarQueryable Hints(string hints); + ISugarQueryable AS(string tableName); + ISugarQueryable AS(string tableName); + ISugarQueryable IF(bool condition, Action> action); + ISugarQueryable AsWithAttr(); + ISugarQueryable AsType(Type tableNameType); + ISugarQueryable Cast(); + ISugarQueryable With(string withString); + //ISugarQueryable CrossQueryWithAttr(); + ISugarQueryable CrossQuery(string configId); + ISugarQueryable CrossQuery(Type type, string configId); + ISugarQueryable IncludeLeftJoin(Expression> leftObjectExp); + ISugarQueryable IncludeInnerJoin(Expression> innerObjectExp); + ISugarQueryable IncludeRightJoin(Expression> rightObjectExp); + ISugarQueryable IncludeFullJoin(Expression> fullObjectExp); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable FullJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + ISugarQueryable ClearFilter(params Type[] types); + ISugarQueryable ClearFilter(); + ISugarQueryable ClearFilter(); + ISugarQueryable ClearFilter(); + ISugarQueryable ClearFilter(); + ISugarQueryable Filter(Type type); + ISugarQueryable Mapper(Action mapperAction); + ISugarQueryable Mapper(Expression> expression); + ISugarQueryable Mapper(Action> mapperAction); + ISugarQueryable Mapper(Expression> mapperObject, Expression> mainField, Expression> childField); + ISugarQueryable Mapper(Expression>> mapperObject, Expression> mainField, Expression> childField); + ISugarQueryable Mapper(Expression> mapperObject, Expression> mapperField); + ISugarQueryable Mapper(Expression>> mapperObject, Expression> mapperField); + ISugarQueryable AddParameters(object parameters); + ISugarQueryable AddParameters(SugarParameter[] parameters); + ISugarQueryable AddParameters(List parameters); + ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + ISugarQueryable AddJoinInfo(Type JoinEntityType, string shortName, string joinWhere, JoinType type = JoinType.Left); + ISugarQueryable AddJoinInfo(Type JoinEntityType, Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString onExpString, JoinType type = JoinType.Left); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + ISugarQueryable WhereClassByPrimaryKey(List list); + ISugarQueryable WhereClassByWhereColumns(List list, string[] whereColumns); + ISugarQueryable WhereClassByPrimaryKey(T data); + ISugarQueryable WhereColumns(List> columns); + ISugarQueryable WhereColumns(Dictionary columns, bool ignoreDefaultValue); + ISugarQueryable WhereColumns(Dictionary columns); + ISugarQueryable TranLock(DbLockType? LockType = DbLockType.Wait); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(string expShortName, FormattableString expressionString); + ISugarQueryable Where(Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expressionString); + ISugarQueryable Where(string whereString, object parameters = null); + ISugarQueryable Where(IFuncModel funcModel); + ISugarQueryable Where(List conditionalModels); + ISugarQueryable Where(List conditionalModels, bool isWrap); + ISugarQueryable Where(string fieldName, string conditionalType, object fieldValue); + ISugarQueryable Having(Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable Having(string whereString, object parameters = null); + + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + T InSingle(object pkValue); + Task InSingleAsync(object pkValue); + ISugarQueryable In(params TParamter[] pkValues); + ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues); + ISugarQueryable InIF(bool isIn, params TParamter[] pkValues); + ISugarQueryable In(string InFieldName, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(List pkValues); + ISugarQueryable In(string InFieldName, List inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + ISugarQueryable InIF(bool isWhere, Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable OrderBy(string orderByFields); + ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(string expShortName, FormattableString expOrderBy, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType); + ISugarQueryable SampleBy(int timeNumber, string timeType); + + + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(string groupFileds); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + + ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + + ISugarQueryable PartitionBy(Expression> expression); + ISugarQueryable PartitionBy(string groupFileds); + + ISugarQueryable Skip(int index); + ISugarQueryable Take(int num); + ISugarQueryable Distinct(); + + T Single(); + Task SingleAsync(); + T Single(Expression> expression); + Task SingleAsync(Expression> expression); + + T First(); + Task FirstAsync(); + Task FirstAsync(CancellationToken token); + T First(Expression> expression); + Task FirstAsync(Expression> expression); + Task FirstAsync(Expression> expression, CancellationToken token); + + bool Any(Expression> expression); + Task AnyAsync(Expression> expression); + Task AnyAsync(Expression> expression, CancellationToken token); + bool Any(); + Task AnyAsync(); + ISugarQueryable Select(string expShortName, FormattableString expSelect, Type resultType); + ISugarQueryable Select(Dictionary keyIsShortName_ValueIsType_Dictionary, FormattableString expSelect, Type resultType); + ISugarQueryable Select(string expShortName, FormattableString expSelect, Type EntityType, Type resultType); + ISugarQueryable Select(string expShortName, FormattableString expSelect, Type resultType); + ISugarQueryable Select(Expression expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + ISugarQueryable Select(); + ISugarQueryable Select(string select); + ISugarQueryable Select(string select); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable MergeTable(); + void ForEachDataReader(Action action); + Task ForEachDataReaderAsync(Action action); + void ForEach(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null); + Task ForEachAsync(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null); + void ForEachByPage(Action action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null); + Task ForEachByPageAsync(Action action, int pageIndex, int pageSize, RefAsync totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null); + int Count(); + Task CountAsync(); + Task CountAsync(CancellationToken token); + int Count(Expression> expression); + Task CountAsync(Expression> expression); + Task CountAsync(Expression> expression, CancellationToken token); + TResult Max(string maxField); + Task MaxAsync(string maxField); + Task MaxAsync(string maxField, CancellationToken token); + TResult Max(Expression> expression); + Task MaxAsync(Expression> expression); + Task MaxAsync(Expression> expression, CancellationToken token); + TResult Min(string minField); + Task MinAsync(string minField); + TResult Min(Expression> expression); + Task MinAsync(Expression> expression); + TResult Sum(string sumField); + Task SumAsync(string sumField); + TResult Sum(Expression> expression); + Task SumAsync(Expression> expression); + TResult Avg(string avgField); + Task AvgAsync(string avgField); + TResult Avg(Expression> expression); + Task AvgAsync(Expression> expression); + List ToList(Expression> expression); + Task> ToListAsync(Expression> expression); + List ToList(); + + int IntoTable(); + int IntoTable(Type TableEntityType); + int IntoTable(string tableName); + int IntoTable(Type TableEntityType, string tableName); + + Task IntoTableAsync(CancellationToken cancellationToken = default); + Task IntoTableAsync(Type TableEntityType, CancellationToken cancellationToken = default); + Task IntoTableAsync(string tableName, CancellationToken cancellationToken = default); + Task IntoTableAsync(Type TableEntityType, string tableName, CancellationToken cancellationToken = default); + + //bool IntoTable(Type TableEntityType, params string[] columnNameList); + //bool IntoTable(params string[] columnNameList); + List SetContext(Expression> whereExpression, ParameterT parameter); + List SetContext(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter); + List SetContext(Expression> thisFiled1, Expression> mappingFiled1, Expression> thisFiled2, Expression> mappingFiled2, ParameterT parameter); + Task> SetContextAsync(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter); + Task> SetContextAsync(Expression> thisFiled1, Expression> mappingFiled1, Expression> thisFiled2, Expression> mappingFiled2, ParameterT parameter); + Dictionary ToDictionary(Expression> key, Expression> value); + Dictionary ToDictionary(Expression> key, Expression> value); + Task> ToDictionaryAsync(Expression> key, Expression> value); + Task> ToDictionaryAsync(Expression> key, Expression> value); + List> ToDictionaryList(); + Task>> ToDictionaryListAsync(); + + T[] ToArray(); + Task ToArrayAsync(); + Task> ToListAsync(); + Task> ToListAsync(CancellationToken token); + + string ToJson(); + Task ToJsonAsync(); + string ToJsonPage(int pageIndex, int pageSize); + Task ToJsonPageAsync(int pageIndex, int pageSize); + string ToJsonPage(int pageIndex, int pageSize, ref int totalNumber); + Task ToJsonPageAsync(int pageIndex, int pageSize, RefAsync totalNumber); + KeyValuePair> ToSql(); + string ToSqlString(); + List ToChildList(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true); + List ToChildList(Expression> parentIdExpression, object[] primaryKeyValues, bool isContainOneself = true); + Task> ToChildListAsync(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true); + Task> ToChildListAsync(Expression> parentIdExpression, object[] primaryKeyValues, bool isContainOneself = true); + List ToParentList(Expression> parentIdExpression, object primaryKeyValue); + List ToParentList(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression); + + Task> ToParentListAsync(Expression> parentIdExpression, object primaryKeyValue); + Task> ToParentListAsync(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression); + List ToTree(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName); + List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue); + List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, Expression> primaryKeyExpression); + Task> ToTreeAsync(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName); + Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue); + Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, Expression> primaryKeyExpression); + List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds); + List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds, Expression> primaryKeyExpression); + Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds); + Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds, Expression> primaryKeyExpression); + DataTable ToDataTable(); + DataTable ToDataTableByEntity(); + Task ToDataTableAsync(); + Task ToDataTableByEntityAsync(); + DataTable ToDataTablePage(int pageNumber, int pageSize); + Task ToDataTablePageAsync(int pageNumber, int pageSize); + DataTable ToDataTablePage(int pageNumber, int pageSize, ref int totalNumber); + DataTable ToDataTableByEntityPage(int pageNumber, int pageSize, ref int totalNumber); + DataTable ToDataTablePage(int pageNumber, int pageSize, ref int totalNumber, ref int totalPage); + Task ToDataTablePageAsync(int pageNumber, int pageSize, RefAsync totalNumber); + Task ToDataTableByEntityPageAsync(int pageNumber, int pageSize, RefAsync totalNumber); + + + DataTable ToOffsetDataTablePage(int pageNumber, int pageSize); + Task ToOffsetDataTablePageAsync(int pageNumber, int pageSize); + DataTable ToOffsetDataTablePage(int pageNumber, int pageSize, ref int totalNumber); + DataTable ToOffsetDataTableByEntityPage(int pageNumber, int pageSize, ref int totalNumber); + DataTable ToOffsetDataTablePage(int pageNumber, int pageSize, ref int totalNumber, ref int totalPage); + Task ToOffsetDataTablePageAsync(int pageNumber, int pageSize, RefAsync totalNumber); + Task ToOffsetDataTableByEntityPageAsync(int pageNumber, int pageSize, RefAsync totalNumber); + + + List ToOffsetPage(int pageNumber, int pageSize); + List ToOffsetPage(int pageNumber, int pageSize, ref int totalNumber); + List ToOffsetPage(int pageNumber, int pageSize, ref int totalNumber, ref int totalPage); + Task> ToOffsetPageAsync(int pageNumber, int pageSize); + Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber); + Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage); + Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber, CancellationToken token); + Task> ToOffsetPageAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage, CancellationToken token); + List ToPageList(int pageNumber, int pageSize); + Task> ToPageListAsync(int pageNumber, int pageSize); + Task> ToPageListAsync(int pageNumber, int pageSize, CancellationToken token); + List ToPageList(int pageNumber, int pageSize, ref int totalNumber); + List ToPageList(int pageNumber, int pageSize, ref int totalNumber, Expression> expression); + List ToPageList(int pageNumber, int pageSize, ref int totalNumber, ref int totalPage); + Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber); + Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, CancellationToken token); + Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, Expression> expression); + Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage); + Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage, CancellationToken token); + ISugarQueryable WithCache(string cacheKey, int cacheDurationInSeconds = int.MaxValue); + ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + string ToClassString(string className); + void Clear(); + void AddQueue(); + ISugarQueryable IgnoreColumns(Expression> columns); + ISugarQueryable IgnoreColumns(params string[] columns); + + #region 内存行转列 + + #region 同步 + DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + IEnumerable ToPivotEnumerable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + #endregion + + #region 异步 + Task ToPivotTableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task> ToPivotListAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task> ToPivotEnumerableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task ToPivotJsonAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + #endregion + + #endregion + + ISugarQueryable SplitTable(Func, IEnumerable> getTableNamesFunc); + ISugarQueryable SplitTable(DateTime beginTime, DateTime endTime); + ISugarQueryable SplitTable(); + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable IF(bool condition, Action> action); + new ISugarQueryable Hints(string hints); + new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType); + new ISugarQueryable SampleBy(int timeNumber, string timeType); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable FullJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + + ISugarQueryable LeftJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable FullJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable RightJoinIF(bool isJoin, Expression> joinExpression, string tableName); + + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable Where(IFuncModel funcModel); + + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object whereObj = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object whereObj = null); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable PartitionBy(Expression> expression); + ISugarQueryable PartitionBy(Expression> expression); + new ISugarQueryable PartitionBy(string groupFileds); + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + new ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + new ISugarQueryable Having(string whereString, object whereObj = null); + new ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + Task MaxAsync(Expression> expression); + Task MinAsync(Expression> expression); + Task SumAsync(Expression> expression); + Task AvgAsync(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + new ISugarQueryable InIF(bool isIn, params TParamter[] pkValues); + new ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable IF(bool condition, Action> action); + new ISugarQueryable Hints(string hints); + new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType); + new ISugarQueryable SampleBy(int timeNumber, string timeType); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable FullJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + ISugarQueryable LeftJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable FullJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable RightJoinIF(bool isJoin, Expression> joinExpression, string tableName); + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable Where(IFuncModel funcModel); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression, bool isAutoFill); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable PartitionBy(Expression> expression); + ISugarQueryable PartitionBy(Expression> expression); + ISugarQueryable PartitionBy(Expression> expression); + new ISugarQueryable PartitionBy(string groupFileds); + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + new ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + new ISugarQueryable Having(string whereString, object parameters = null); + new ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + Task MaxAsync(Expression> expression); + Task MinAsync(Expression> expression); + Task SumAsync(Expression> expression); + Task AvgAsync(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + new ISugarQueryable InIF(bool isIn, params TParamter[] pkValues); + new ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable IF(bool condition, Action> action); + new ISugarQueryable Hints(string hints); + new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType); + new ISugarQueryable SampleBy(int timeNumber, string timeType); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + ISugarQueryable LeftJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable FullJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression, string tableName); + ISugarQueryable RightJoinIF(bool isJoin, Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable Where(IFuncModel funcModel); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + new ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + new ISugarQueryable Having(string whereString, object parameters = null); + new ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + ISugarQueryable In(Expression> expression, params FieldType[] inValues); + ISugarQueryable In(Expression> expression, List inValues); + ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + + new ISugarQueryable InIF(bool isIn, params TParamter[] pkValues); + new ISugarQueryable InIF(bool isIn, string fieldName, params TParamter[] pkValues); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable IF(bool condition, Action> action); + new ISugarQueryable Hints(string hints); + new ISugarQueryable SampleBy(int timeNumber, SampleByUnit timeType); + new ISugarQueryable SampleBy(int timeNumber, string timeType); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable Where(IFuncModel funcModel); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + #endregion + + #region Select + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + new ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + new ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + new ISugarQueryable Having(string whereString, object parameters = null); + new ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable IF(bool condition, Action> action); + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable Where(IFuncModel funcModel); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + + #endregion + + #region Select + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + new ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + new ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + ISugarQueryable Having(Expression> expression); + new ISugarQueryable Having(string whereString, object parameters = null); + new ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + ISugarQueryable HavingIF(bool isHaving, Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + + #endregion + + #region Select + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupByIF(bool isGroupBy, string groupFields); + new ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + ISugarQueryable GroupByIF(bool isGroupBy, Expression> expression); + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(ClassType whereClass, bool ignoreDefaultValue = false) where ClassType : class, new(); + /// + /// if a property that is not empty is a condition + /// + /// + /// + /// + new ISugarQueryable WhereClass(List whereClassList, bool ignoreDefaultValue = false) where ClassType : class, new(); + + #endregion + + #region Select + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + new ISugarQueryable OrderByIF(bool isOrderBy, string orderByFields); + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable Distinct(); + bool Any(Expression> expression); + #endregion + } + + #region 9-12 + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + #endregion + + #region OrderBy + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Distinct(); + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + #endregion + + #region OrderBy + new ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + ISugarQueryable OrderByDescending(Expression> expression); + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + + + + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Distinct(); + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + ISugarQueryable LeftJoinIF(bool isLeftJoin, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, Expression> joinExpression); + ISugarQueryable LeftJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable RightJoin(ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable InnerJoinIF(bool isJoin, ISugarQueryable joinQueryable, Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression); + ISugarQueryable FullJoin(Expression> joinExpression); + ISugarQueryable InnerJoin(Expression> joinExpression); + ISugarQueryable RightJoin(Expression> joinExpression); + ISugarQueryable LeftJoin(Expression> joinExpression, string tableName); + ISugarQueryable FullJoin(Expression> joinExpression, string tableName); + ISugarQueryable InnerJoin(Expression> joinExpression, string tableName); + ISugarQueryable RightJoin(Expression> joinExpression, string tableName); + + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Distinct(); + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + #endregion + } + public partial interface ISugarQueryable : ISugarQueryable + { + new ISugarQueryable Hints(string hints); + ISugarQueryable SelectMergeTable(Expression> expression); + #region Where + new ISugarQueryable Where(string expShortName, FormattableString expressionString); + new ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + ISugarQueryable Where(Expression> expression); + new ISugarQueryable Where(List conditionalModels); + new ISugarQueryable Where(List conditionalModels, bool isWrap); + new ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + ISugarQueryable WhereIF(bool isWhere, Expression> expression); + + new ISugarQueryable Where(string whereString, object parameters = null); + new ISugarQueryable WhereIF(bool isWhere, string whereString, object parameters = null); + #endregion + + #region Select + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable SelectIF(bool condition, Expression> trueSelectExpression, Expression> falseSelectExpression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression); + ISugarQueryable Select(Expression> expression, bool isAutoFill); + #endregion + + #region OrderBy + new ISugarQueryable OrderBy(List models); + new ISugarQueryable OrderByPropertyNameIF(bool isOrderBy, string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderByPropertyName(string orderPropertyName, OrderByType? orderByType = null); + new ISugarQueryable OrderBy(string orderByFields); + new ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderBy(Expression> expression, OrderByType type = OrderByType.Asc); + + new ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + ISugarQueryable OrderByIF(bool isOrderBy, Expression> expression, OrderByType type = OrderByType.Asc); + #endregion + + #region GroupBy + new ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + ISugarQueryable GroupBy(Expression> expression); + #endregion + + #region Aggr + TResult Max(Expression> expression); + TResult Min(Expression> expression); + TResult Sum(Expression> expression); + TResult Avg(Expression> expression); + #endregion + + #region In + new ISugarQueryable In(Expression> expression, params FieldType[] inValues); + new ISugarQueryable In(Expression> expression, List inValues); + new ISugarQueryable In(Expression> expression, ISugarQueryable childQueryExpression); + #endregion + + #region Other + new ISugarQueryable Distinct(); + new ISugarQueryable Take(int num); + new ISugarQueryable Clone(); + new ISugarQueryable AS(string tableName); + new ISugarQueryable AS(string tableName); + new ISugarQueryable ClearFilter(); + new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); + new ISugarQueryable ClearFilter(params Type[] types); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable ClearFilter(); + new ISugarQueryable AddParameters(object parameters); + new ISugarQueryable AddParameters(SugarParameter[] parameters); + new ISugarQueryable AddParameters(List parameters); + new ISugarQueryable AddJoinInfo(string tableName, string shortName, string joinWhere, JoinType type = JoinType.Left); + new ISugarQueryable With(string withString); + new ISugarQueryable WithCache(int cacheDurationInSeconds = int.MaxValue); + new ISugarQueryable WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue); + #endregion + } + #endregion +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IReportable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IReportable.cs new file mode 100644 index 000000000..0f933239c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IReportable.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public interface IReportable + { + //IReportable MakeUp(Func auto); + ISugarQueryable ToQueryable(); + ISugarQueryable> ToQueryable(); + ISugarQueryable> ToQueryable(bool onlySelectEntity); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISaveable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISaveable.cs new file mode 100644 index 000000000..b08502b78 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISaveable.cs @@ -0,0 +1,22 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial interface ISaveable where T : class, new() + { + Task ExecuteCommandAsync(); + Task ExecuteReturnEntityAsync(); + + Task> ExecuteReturnListAsync(); + int ExecuteCommand(); + T ExecuteReturnEntity(); + List ExecuteReturnList(); + ISaveable InsertColumns(Expression> columns); + ISaveable InsertIgnoreColumns(Expression> columns); + ISaveable UpdateColumns(Expression> columns); + ISaveable UpdateIgnoreColumns(Expression> columns); + ISaveable UpdateWhereColumns(Expression> columns); + ISaveable EnableDiffLogEvent(object businessData = null); + ISaveable RemoveDataCache(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISimpleClient.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISimpleClient.cs new file mode 100644 index 000000000..da80d9605 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISimpleClient.cs @@ -0,0 +1,142 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public interface ISimpleClient where T : class, new() + { + SimpleClient CopyNew(); + RepositoryType CopyNew(IServiceProvider serviceProvider) where RepositoryType : ISugarRepository; + RepositoryType CopyNew() where RepositoryType : ISugarRepository; + SimpleClient Change() where ChangeType : class, new(); + RepositoryType ChangeRepository() where RepositoryType : ISugarRepository; + RepositoryType ChangeRepository(IServiceProvider serviceProvider) where RepositoryType : ISugarRepository; + IDeleteable AsDeleteable(); + IInsertable AsInsertable(List insertObjs); + IInsertable AsInsertable(T insertObj); + IInsertable AsInsertable(T[] insertObjs); + ISugarQueryable AsQueryable(); + ISqlSugarClient AsSugarClient(); + ITenant AsTenant(); + IUpdateable AsUpdateable(List updateObjs); + IUpdateable AsUpdateable(T updateObj); + IUpdateable AsUpdateable(); + IUpdateable AsUpdateable(T[] updateObjs); + int Count(Expression> whereExpression); + int Count(List conditionalModels); + bool Delete(Expression> whereExpression); + bool Delete(List conditionalModels); + bool Delete(T deleteObj); + bool Delete(List deleteObjs); + bool DeleteById(dynamic id); + bool DeleteByIds(dynamic[] ids); + T GetById(dynamic id); + List GetList(); + List GetList(Expression> whereExpression); + List GetList(List conditionalList); + List GetList(Expression> whereExpression, List orderByModels); + List GetList(List conditionalList, List orderByModels); + List GetPageList(Expression> whereExpression, PageModel page); + List GetPageList(Expression> whereExpression, PageModel page, List orderByModels); + List GetPageList(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); + List GetPageList(List conditionalList, PageModel page); + List GetPageList(List conditionalList, PageModel page, List orderByModels); + List GetPageList(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); + T GetSingle(Expression> whereExpression); + T GetSingle(List conditionalModels); + T GetFirst(Expression> whereExpression); + T GetFirst(List conditionalModels); + T GetFirst(List conditionalModels, List orderByModels); + bool Insert(T insertObj); + bool InsertOrUpdate(T data); + bool InsertOrUpdate(List datas); + bool InsertRange(List insertObjs); + bool InsertRange(T[] insertObjs); + int InsertReturnIdentity(T insertObj); + long InsertReturnBigIdentity(T insertObj); + long InsertReturnSnowflakeId(T insertObj); + List InsertReturnSnowflakeId(List insertObjs); + T InsertReturnEntity(T insertObj); + + + bool IsAny(Expression> whereExpression); + bool IsAny(List conditionalModels); + bool Update(Expression> columns, Expression> whereExpression); + bool UpdateSetColumnsTrue(Expression> columns, Expression> whereExpression); + bool Update(T updateObj); + bool UpdateRange(List updateObjs); + bool UpdateRange(T[] updateObjs); + + + + + Task CountAsync(Expression> whereExpression); + Task DeleteAsync(Expression> whereExpression); + Task DeleteAsync(T deleteObj); + Task DeleteAsync(List deleteObjs); + Task DeleteByIdAsync(dynamic id); + Task DeleteByIdsAsync(dynamic[] ids); + Task GetByIdAsync(dynamic id); + Task> GetListAsync(); + Task> GetListAsync(Expression> whereExpression); + Task> GetPageListAsync(Expression> whereExpression, PageModel page); + Task> GetPageListAsync(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); + Task> GetPageListAsync(List conditionalList, PageModel page); + Task> GetPageListAsync(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); + Task GetSingleAsync(Expression> whereExpression); + Task GetFirstAsync(Expression> whereExpression); + Task InsertAsync(T insertObj); + Task InsertOrUpdateAsync(T data); + Task InsertOrUpdateAsync(List datas); + Task InsertRangeAsync(List insertObjs); + Task InsertRangeAsync(T[] insertObjs); + Task InsertReturnIdentityAsync(T insertObj); + Task InsertReturnBigIdentityAsync(T insertObj); + Task InsertReturnSnowflakeIdAsync(T insertObj); + Task> InsertReturnSnowflakeIdAsync(List insertObjs); + Task InsertReturnEntityAsync(T insertObj); + + Task IsAnyAsync(Expression> whereExpression); + Task UpdateSetColumnsTrueAsync(Expression> columns, Expression> whereExpression); + Task UpdateAsync(Expression> columns, Expression> whereExpression); + Task UpdateAsync(T updateObj); + Task UpdateRangeAsync(List updateObjs); + Task UpdateRangeAsync(T[] updateObjs); + + + + + Task CountAsync(Expression> whereExpression, CancellationToken cancellationToken); + Task DeleteAsync(Expression> whereExpression, CancellationToken cancellationToken); + Task DeleteAsync(T deleteObj, CancellationToken cancellationToken); + Task DeleteAsync(List deleteObjs, CancellationToken cancellationToken); + Task DeleteByIdAsync(dynamic id, CancellationToken cancellationToken); + Task DeleteByIdsAsync(dynamic[] ids, CancellationToken cancellationToken); + Task GetByIdAsync(dynamic id, CancellationToken cancellationToken); + Task> GetListAsync(CancellationToken cancellationToken); + Task> GetListAsync(Expression> whereExpression, CancellationToken cancellationToken); + Task> GetPageListAsync(Expression> whereExpression, PageModel page, CancellationToken cancellationToken); + Task> GetPageListAsync(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc, CancellationToken cancellationToken = default); + Task> GetPageListAsync(List conditionalList, PageModel page, CancellationToken cancellationToken); + Task> GetPageListAsync(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc, CancellationToken cancellationToken = default); + Task GetSingleAsync(Expression> whereExpression, CancellationToken cancellationToken); + Task GetFirstAsync(Expression> whereExpression, CancellationToken cancellationToken); + Task InsertAsync(T insertObj, CancellationToken cancellationToken); + Task InsertOrUpdateAsync(T data, CancellationToken cancellationToken); + Task InsertOrUpdateAsync(List datas, CancellationToken cancellationToken); + Task InsertRangeAsync(List insertObjs, CancellationToken cancellationToken); + Task InsertRangeAsync(T[] insertObjs, CancellationToken cancellationToken); + Task InsertReturnIdentityAsync(T insertObj, CancellationToken cancellationToken); + Task InsertReturnBigIdentityAsync(T insertObj, CancellationToken cancellationToken); + Task InsertReturnSnowflakeIdAsync(T insertObj, CancellationToken cancellationToken); + Task> InsertReturnSnowflakeIdAsync(List insertObjs, CancellationToken cancellationToken); + Task InsertReturnEntityAsync(T insertObj, CancellationToken cancellationToken); + + Task IsAnyAsync(Expression> whereExpression, CancellationToken cancellationToken); + Task UpdateSetColumnsTrueAsync(Expression> columns, Expression> whereExpression, CancellationToken cancellationToken); + Task UpdateAsync(Expression> columns, Expression> whereExpression, CancellationToken cancellationToken); + Task UpdateAsync(T updateObj, CancellationToken cancellationToken); + Task UpdateRangeAsync(List updateObjs, CancellationToken cancellationToken); + Task UpdateRangeAsync(T[] updateObjs, CancellationToken cancellationToken); + + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISqlBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISqlBuilder.cs new file mode 100644 index 000000000..6c0e82722 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISqlBuilder.cs @@ -0,0 +1,49 @@ +using System.Data; +using System.Text; +namespace SqlSugar +{ + public partial interface ISqlBuilder + { + SqlSugarProvider Context { get; set; } + CommandType CommandType { get; set; } + String AppendWhereOrAnd(bool isWhere, string sqlString); + string AppendHaving(string sqlString); + + SqlQueryBuilder SqlQueryBuilder { get; set; } + QueryBuilder QueryBuilder { get; set; } + InsertBuilder InsertBuilder { get; set; } + DeleteBuilder DeleteBuilder { get; set; } + UpdateBuilder UpdateBuilder { get; set; } + + string SqlParameterKeyWord { get; } + string SqlFalse { get; } + string SqlDateNow { get; } + string FullSqlDateNow { get; } + string SqlTranslationLeft { get; } + string SqlTranslationRight { get; } + string SqlSelectAll { get; } + + void ChangeJsonType(SugarParameter paramter); + string GetTranslationTableName(string name); + string GetTranslationColumnName(string entityName, string propertyName); + string GetTranslationColumnName(string propertyName); + string GetNoTranslationColumnName(string name); + string GetPackTable(string sql, string shortName); + string GetDefaultShortName(); + + string GetWhere(string fieldName, string conditionalType, int? parameterIndex = null); + string GetUnionAllSql(List sqlList); + string GetUnionSql(List sqlList); + void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex); + KeyValuePair ConditionalModelToSql(List models, int beginIndex = 0); + string GetUnionFomatSql(string sql); + Type GetNullType(string tableName, string columnName); + string RemoveParentheses(string sql); + string RemoveN(string sql); + void FormatSaveQueueSql(StringBuilder sqlBuilder); + + bool SupportReadToken { get; set; } + Task GetReaderByToken(IDataReader dataReader, CancellationToken cancellationToken); + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISqlSugarClient.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISqlSugarClient.cs new file mode 100644 index 000000000..46a6cbda6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISqlSugarClient.cs @@ -0,0 +1,245 @@ +using System.Data; +using System.Dynamic; +using System.Linq.Expressions; + +namespace SqlSugar +{ + public interface ISqlSugarClient : IDisposable + { + MappingTableList MappingTables { get; set; } + MappingColumnList MappingColumns { get; set; } + IgnoreColumnList IgnoreColumns { get; set; } + IgnoreColumnList IgnoreInsertColumns { get; set; } + Dictionary TempItems { get; set; } + ConfigQuery ConfigQuery { get; set; } + + Guid ContextID { get; set; } + ConnectionConfig CurrentConnectionConfig { get; set; } + + + IAdo Ado { get; } + AopProvider Aop { get; } + ICodeFirst CodeFirst { get; } + + + IDbFirst DbFirst { get; } + IDbMaintenance DbMaintenance { get; } + EntityMaintenance EntityMaintenance { get; set; } + QueryFilterProvider QueryFilter { get; set; } + IContextMethods Utilities { get; set; } + SugarActionType SugarActionType { get; set; } + + #region Deleteable + DeleteMethodInfo DeleteableByObject(object singleEntityObjectOrListObject); + IDeleteable Deleteable() where T : class, new(); + IDeleteable Deleteable(dynamic primaryKeyValue) where T : class, new(); + IDeleteable Deleteable(dynamic[] primaryKeyValues) where T : class, new(); + IDeleteable Deleteable(Expression> expression) where T : class, new(); + IDeleteable Deleteable(List pkValue) where T : class, new(); + IDeleteable Deleteable(List deleteObjs) where T : class, new(); + IDeleteable Deleteable(T deleteObj) where T : class, new(); + #endregion + + #region Other methods + Task AsyncLock(int timeOutSeconds = 30); + DynamicBuilder DynamicBuilder(); + void ClearTracking(); + void Tracking(T data) where T : class, new(); + void Tracking(List data) where T : class, new(); + SqlSugarClient CopyNew(); + T CreateContext(bool isTran = true) where T : SugarUnitOfWork, new(); + SugarUnitOfWork CreateContext(bool isTran = true); + SplitTableContext SplitHelper(Type entityType); + SplitTableContext SplitHelper() where T : class, new(); + SplitTableContextResult SplitHelper(T data) where T : class, new(); + SplitTableContextResult SplitHelper(List data) where T : class, new(); + DateTime GetDate(); + //SimpleClient GetSimpleClient(); + SimpleClient GetSimpleClient() where T : class, new(); + RepositoryType GetRepository() where RepositoryType : ISugarRepository, new(); + void InitMappingInfo(Type type); + void InitMappingInfo(); + void Open(); + void Close(); + ITenant AsTenant(); + #endregion + + #region Insertable + IInsertable Insertable(Dictionary columnDictionary) where T : class, new(); + IInsertable Insertable(dynamic insertDynamicObject) where T : class, new(); + IInsertable Insertable(List insertObjs) where T : class, new(); + IInsertable Insertable(T insertObj) where T : class, new(); + IInsertable Insertable(T[] insertObjs) where T : class, new(); + InsertMethodInfo InsertableByObject(object singleEntityObjectOrListObject); + IInsertable> InsertableByDynamic(object insertDynamicObject); + #endregion + + #region Queryable + QueryMethodInfo QueryableByObject(Type entityType, string shortName); + QueryMethodInfo QueryableByObject(Type entityType); + ISugarQueryable MasterQueryable(); + ISugarQueryable SlaveQueryable(); + ISugarQueryable SqlQueryable(string sql) where T : class, new(); + ISugarQueryable Queryable(string tableName, string shortName); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression) where T : class, new(); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(Expression> joinExpression); + ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) + where T : class, new() + where T2 : class, new(); + ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) + where T : class, new() + where T2 : class, new(); + + ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, + JoinType joinType1, Expression> joinExpression1, + JoinType joinType2, Expression> joinExpression2) + where T : class, new() + where T2 : class, new() + where T3 : class, new(); + + ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, ISugarQueryable joinQueryable4, + JoinType joinType1, Expression> joinExpression1, + JoinType joinType2, Expression> joinExpression2, + JoinType joinType3, Expression> joinExpression4) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + where T4 : class, new(); + ISugarQueryable Queryable(); + ISugarQueryable Queryable(ISugarQueryable queryable); + ISugarQueryable Queryable(ISugarQueryable queryable, string shortName); + ISugarQueryable Queryable(string shortName); + #endregion + + #region Saveable + GridSaveProvider GridSave(List saveList) where T : class, new(); + GridSaveProvider GridSave(List oldList, List saveList) where T : class, new(); + IStorageable Storageable(T[] dataList) where T : class, new(); + IStorageable Storageable(IList dataList) where T : class, new(); + StorageableDataTable Storageable(List> dictionaryList, string tableName); + StorageableDataTable Storageable(Dictionary dictionary, string tableName); + IStorageable Storageable(List dataList) where T : class, new(); + IStorageable Storageable(T data) where T : class, new(); + StorageableDataTable Storageable(DataTable data); + [Obsolete("use Storageable")] + ISaveable Saveable(List saveObjects) where T : class, new(); + [Obsolete("use Storageable")] + ISaveable Saveable(T saveObject) where T : class, new(); + + StorageableMethodInfo StorageableByObject(object singleEntityObjectOrListObject); + + #endregion + + #region Queue + QueueList Queues { get; set; } + void AddQueue(string sql, object parsmeters = null); + void AddQueue(string sql, List parsmeters); + void AddQueue(string sql, SugarParameter parsmeter); + int SaveQueues(bool isTran = true); + Tuple, List, List, List, List, List, List> SaveQueues(bool isTran = true); + Tuple, List, List, List, List, List> SaveQueues(bool isTran = true); + Tuple, List, List, List, List> SaveQueues(bool isTran = true); + Tuple, List, List, List> SaveQueues(bool isTran = true); + Tuple, List, List> SaveQueues(bool isTran = true); + Tuple, List> SaveQueues(bool isTran = true); + List SaveQueues(bool isTran = true); + Task SaveQueuesAsync(bool isTran = true); + Task, List, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true); + Task, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true); + Task, List, List, List, List>> SaveQueuesAsync(bool isTran = true); + Task, List, List, List>> SaveQueuesAsync(bool isTran = true); + Task, List, List>> SaveQueuesAsync(bool isTran = true); + Task, List>> SaveQueuesAsync(bool isTran = true); + Task> SaveQueuesAsync(bool isTran = true); + #endregion + + #region Union + ISugarQueryable Union(List> queryables) where T : class; + ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class; + ISugarQueryable UnionAll(List> queryables) where T : class; + ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class; + #endregion + + #region Updateable + UpdateMethodInfo UpdateableByObject(object singleEntityObjectOrListObject); + UpdateExpressionMethodInfo UpdateableByObject(Type entityType); + IUpdateable Updateable() where T : class, new(); + IUpdateable Updateable(Dictionary columnDictionary) where T : class, new(); + IUpdateable Updateable(dynamic updateDynamicObject) where T : class, new(); + IUpdateable Updateable(Expression> columns) where T : class, new(); + IUpdateable Updateable(Expression> columns) where T : class, new(); + IUpdateable Updateable(List UpdateObjs) where T : class, new(); + IUpdateable Updateable(T UpdateObj) where T : class, new(); + IUpdateable Updateable(T[] UpdateObjs) where T : class, new(); + IUpdateable> UpdateableByDynamic(object updateDynamicObject); + #endregion + + #region Reportable + IReportable Reportable(T data); + IReportable Reportable(List list); + IReportable Reportable(T[] array); + #endregion + + #region Cache + SugarCacheProvider DataCache { get; } + #endregion + + #region Fastest + IFastest Fastest() where T : class, new(); + #endregion + + #region ThenMapper + void ThenMapper(IEnumerable list, Action action); + Task ThenMapperAsync(IEnumerable list, Func action); + #endregion + + #region Nav CUD + InsertNavTaskInit InsertNav(T data) where T : class, new(); + InsertNavTaskInit InsertNav(List datas) where T : class, new(); + InsertNavTaskInit InsertNav(T data, InsertNavRootOptions rootOptions) where T : class, new(); + InsertNavTaskInit InsertNav(List datas, InsertNavRootOptions rootOptions) where T : class, new(); + DeleteNavTaskInit DeleteNav(T data) where T : class, new(); + DeleteNavTaskInit DeleteNav(List datas) where T : class, new(); + DeleteNavTaskInit DeleteNav(Expression> whereExpression) where T : class, new(); + DeleteNavTaskInit DeleteNav(T data, DeleteNavRootOptions options) where T : class, new(); + DeleteNavTaskInit DeleteNav(List datas, DeleteNavRootOptions options) where T : class, new(); + DeleteNavTaskInit DeleteNav(Expression> whereExpression, DeleteNavRootOptions options) where T : class, new(); + UpdateNavTaskInit UpdateNav(T data) where T : class, new(); + UpdateNavTaskInit UpdateNav(List datas) where T : class, new(); + UpdateNavTaskInit UpdateNav(T data, UpdateNavRootOptions rootOptions) where T : class, new(); + UpdateNavTaskInit UpdateNav(List datas, UpdateNavRootOptions rootOptions) where T : class, new(); + #endregion + + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IStorageable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IStorageable.cs new file mode 100644 index 000000000..a0f23a002 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IStorageable.cs @@ -0,0 +1,191 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + public interface IStorageable where T : class, new() + { + IStorageable TableDataRange(Expression> exp); + IStorageable WhereColumns(Expression> columns); + IStorageable WhereColumns(Expression> columns, Func formatTime); + IStorageable WhereColumns(string[] columns); + IStorageable WhereColumns(string[] columns, Func formatTime); + IStorageable SplitInsert(Func, bool> conditions, string message = null); + IStorageable SplitUpdate(Func, bool> conditions, string message = null); + IStorageable Saveable(string inserMessage = null, string updateMessage = null); + IStorageable SplitError(Func, bool> conditions, string message = null); + IStorageable SplitIgnore(Func, bool> conditions, string message = null); + IStorageable DisableFilters(); + IStorageable TranLock(DbLockType LockType = DbLockType.Wait); + IStorageable TranLock(DbLockType? LockType); + IStorageable SplitDelete(Func, bool> conditions, string message = null); + IStorageable SplitOther(Func, bool> conditions, string message = null); + StorageableResult ToStorage(); + StorageableResult GetStorageableResult(); + Task> ToStorageAsync(); + IStorageable As(string tableName); + int ExecuteCommand(); + T ExecuteReturnEntity(); + Task ExecuteReturnEntityAsync(); + Task ExecuteCommandAsync(); + Task ExecuteCommandAsync(CancellationToken cancellationToken); + int ExecuteSqlBulkCopy(); + Task ExecuteSqlBulkCopyAsync(); + IStorageable DefaultAddElseUpdate(); + StorageableSplitProvider SplitTable(); + StorageablePage PageSize(int PaegSize, Action ActionCallBack = null); + } + + public class StorageableInfo where T : class, new() + { + public T Item { get; set; } + internal List Database { get; set; } + internal string[] PkFields { get; set; } + public bool Any(Func expression) + { + return Database.Any(expression); + } + public bool NotAny(Func expression) + { + return !Database.Any(expression); + } + public bool Any() + { + var list = Database.Where(it => true); + foreach (var pk in PkFields) + { + list = list.Where(it => IsEquals(it, pk)); + } + return list.Any(); + } + + private bool IsEquals(T it, string pk) + { + var leftValue = it.GetType().GetProperty(pk).GetValue(it, null); + var rightValue = Item.GetType().GetProperty(pk).GetValue(Item, null); + var left = leftValue.ObjToString(); + var rigth = rightValue.ObjToString(); + if (leftValue != null && (leftValue is decimal || leftValue is decimal?)) + { + return Convert.ToDecimal(leftValue) == Convert.ToDecimal(rightValue); + } + else + { + return left.EqualCase(rigth); + } + } + + public bool NotAny() + { + return !Any(); + } + } + + public class StorageableMessage : StorageableInfo where T : class, new() + { + public string StorageMessage { get; set; } + public StorageType? StorageType { get; set; } + } + + public enum StorageType + { + Insert = 0, + Update = 1, + Delete = 2, + Error = 3, + Other = 4, + Ignore = 5, + } + internal struct KeyValuePair + { + public TKey key; + public TValue value1; + public TValue2 value2; + public KeyValuePair(TKey key, TValue value1, TValue2 value2) + { + this.key = key; + this.value1 = value1; + this.value2 = value2; + } + } + + public class StorageableResult where T : class, new() + { + public List> TotalList { get; set; } + public List> InsertList { get; set; } + public List> UpdateList { get; set; } + public List> DeleteList { get; set; } + public List> ErrorList { get; set; } + public List> IgnoreList { get; set; } + public List> OtherList { get; set; } + public IInsertable AsInsertable { get; set; } + public IUpdateable AsUpdateable { get; set; } + public IDeleteable AsDeleteable { get; set; } + internal List _WhereColumnList { get; set; } + internal string _AsName { get; set; } + internal SqlSugarProvider _Context { get; set; } + + public int BulkCopy() + { + return this._Context.Fastest().AS(_AsName).BulkCopy(InsertList.Select(it => it.Item).ToList()); + } + public Task BulkCopyAsync() + { + return this._Context.Fastest().AS(_AsName).BulkCopyAsync(InsertList.Select(it => it.Item).ToList()); + } + + public int BulkUpdate() + { + var isWhereColums = _WhereColumnList != null && _WhereColumnList.Count != 0; + if (isWhereColums) + { + var updateColumns = this._Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); + return BulkUpdate(updateColumns); + } + else + { + return this._Context.Fastest().AS(_AsName).BulkUpdate(UpdateList.Select(it => it.Item).ToList()); + } + } + public Task BulkUpdateAsync() + { + var isWhereColums = _WhereColumnList != null && _WhereColumnList.Count != 0; + if (isWhereColums) + { + var updateColumns = this._Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); + return BulkUpdateAsync(updateColumns); + } + else + { + return this._Context.Fastest().AS(_AsName).BulkUpdateAsync(UpdateList.Select(it => it.Item).ToList()); + } + } + public int BulkUpdate(params string[] UpdateColumns) + { + + Check.Exception(UpdateColumns == null, "UpdateColumns is null"); + if (_WhereColumnList != null && _WhereColumnList.Count != 0) + { + return this._Context.Fastest().AS(_AsName).BulkUpdate(UpdateList.Select(it => it.Item).ToList(), _WhereColumnList.Select(it => it.DbColumnName).ToArray(), UpdateColumns); + } + else + { + var pkColumns = this._Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToArray(); + Check.Exception(pkColumns.Length == 0, "need primary key"); + return this._Context.Fastest().AS(_AsName).BulkUpdate(UpdateList.Select(it => it.Item).ToList(), pkColumns, UpdateColumns); + } + } + public async Task BulkUpdateAsync(params string[] UpdateColumns) + { + Check.Exception(UpdateColumns == null, "UpdateColumns is null"); + if (_WhereColumnList != null && _WhereColumnList.Count != 0) + { + return await _Context.Fastest().AS(_AsName).BulkUpdateAsync(UpdateList.Select(it => it.Item).ToList(), _WhereColumnList.Select(it => it.DbColumnName).ToArray(), UpdateColumns).ConfigureAwait(false); + } + else + { + var pkColumns = this._Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToArray(); + Check.Exception(pkColumns.Length == 0, "need primary key"); + return await _Context.Fastest().AS(_AsName).BulkUpdateAsync(UpdateList.Select(it => it.Item).ToList(), pkColumns, UpdateColumns).ConfigureAwait(false); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISubInsertable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISubInsertable.cs new file mode 100644 index 000000000..1ddaaf5e2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISubInsertable.cs @@ -0,0 +1,14 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public interface ISubInsertable + { + ISubInsertable AddSubList(Expression> items); + ISubInsertable AddSubList(Expression> tree); + [Obsolete("use ExecuteCommand")] + object ExecuteReturnPrimaryKey(); + object ExecuteCommand(); + Task ExecuteCommandAsync(); + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISugarDataConverter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISugarDataConverter.cs new file mode 100644 index 000000000..06e372e1e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISugarDataConverter.cs @@ -0,0 +1,11 @@ +using System.Data; + +namespace SqlSugar +{ + public interface ISugarDataConverter + { + SugarParameter ParameterConverter(object columnValue, int columnIndex); + + T QueryConverter(IDataRecord dataRecord, int dataRecordIndex); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISugarRepository.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISugarRepository.cs new file mode 100644 index 000000000..235e52f77 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ISugarRepository.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public interface ISugarRepository + { + ISqlSugarClient Context { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ITenant.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ITenant.cs new file mode 100644 index 000000000..a12386530 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/ITenant.cs @@ -0,0 +1,46 @@ +using System.Data; + +namespace SqlSugar +{ + public interface ITenant + { + SqlSugarClient CopyNew(); + string[] GetCurrentConfigIds(); + void BeginTran(); + void BeginTran(IsolationLevel iso); + void CommitTran(); + void RollbackTran(); + Task BeginTranAsync(); + Task BeginTranAsync(IsolationLevel iso); + Task CommitTranAsync(); + Task RollbackTranAsync(); + void ChangeDatabase(object configId); + void ChangeDatabase(Func changeExpression); + SqlSugarTransaction UseTran(); + DbResult UseTran(Action action, Action errorCallBack = null); + Task> UseTranAsync(Func action, Action errorCallBack = null); + DbResult UseTran(Func action, Action errorCallBack = null); + + Task> UseTranAsync(Func> action, Action errorCallBack = null); + void AddConnection(ConnectionConfig connection); + SqlSugarProvider GetConnection(object configId); + void RemoveConnection(object configId); + SqlSugarScopeProvider GetConnectionScope(object configId); + SqlSugarProvider GetConnectionWithAttr(); + SqlSugarScopeProvider GetConnectionScopeWithAttr(); + ISugarQueryable QueryableWithAttr(); + IInsertable InsertableWithAttr(T insertObj) where T : class, new(); + IInsertable InsertableWithAttr(List insertObjs) where T : class, new(); + IUpdateable UpdateableWithAttr(T updateObj) where T : class, new(); + IUpdateable UpdateableWithAttr() where T : class, new(); + IUpdateable UpdateableWithAttr(List updateObjs) where T : class, new(); + IDeleteable DeleteableWithAttr(T deleteObjs) where T : class, new(); + IDeleteable DeleteableWithAttr(List deleteObjs) where T : class, new(); + IDeleteable DeleteableWithAttr() where T : class, new(); + + bool IsAnyConnection(object configId); + + void Close(); + void Open(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IUpdateable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IUpdateable.cs new file mode 100644 index 000000000..5e040de30 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/IUpdateable.cs @@ -0,0 +1,136 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public interface IUpdateable where T : class, new() + { + UpdateBuilder UpdateBuilder { get; set; } + bool UpdateParameterIsNull { get; set; } + + int ExecuteCommandWithOptLock(bool isThrowError = false); + int ExecuteCommandWithOptLockIF(bool? IsVersionValidation, bool? IsOptLock = null); + Task ExecuteCommandWithOptLockAsync(bool isThrowError = false); + int ExecuteCommand(); + bool ExecuteCommandHasChange(); + Task ExecuteCommandAsync(); + Task ExecuteCommandAsync(CancellationToken token); + Task ExecuteCommandHasChangeAsync(); + Task ExecuteCommandHasChangeAsync(CancellationToken token); + + + IUpdateable AS(string tableName); + IUpdateable AsType(Type tableNameType); + IUpdateable With(string lockString); + IUpdateable In(Expression> inField, ISugarQueryable childQueryExpression); + + IUpdateable Where(Expression> expression); + IUpdateable WhereIF(bool isWhere, Expression> expression); + IUpdateable Where(string whereSql, object parameters = null); + + IUpdateable Where(string fieldName, string conditionalType, object fieldValue); + + + + /// + /// Non primary key entity update function,.WhereColumns(it=>new{ it.Id }) + /// + /// + /// + IUpdateable WhereColumns(Expression> columns); + IUpdateable WhereColumns(string columnName); + IUpdateable WhereColumns(params string[] columnNames); + IUpdateable Where(List conditionalModels); + + /// + /// .UpdateColumns(it=>new{ it.Name,it.Price}) + /// + /// + /// + IUpdateable UpdateColumns(Expression> columns); + IUpdateable UpdateColumns(Expression> columns, bool appendColumnsByDataFilter); + IUpdateable UpdateColumns(params string[] columns); + IUpdateable UpdateColumns(string[] columns, bool appendColumnsByDataFilter); + + + /// + ///.SetColumns(it=>it.Name=="a") + /// + /// + /// + IUpdateable SetColumns(Expression> columns); + /// + /// .SetColumns(it=> new class() { it.Name="a",it.Price=0}) + /// + /// + /// + IUpdateable SetColumns(Expression> columns); + IUpdateable SetColumns(Expression> columns, bool appendColumnsByDataFilter); + IUpdateable SetColumns(string fieldName, object fieldValue); + + IUpdateable SetColumns(Expression> filedNameExpression, object fieldValue); + IUpdateable SetColumns(Expression> filedNameExpression, Expression> valueExpression); + IUpdateable SetColumnsIF(bool isUpdateColumns, Expression> filedNameExpression, object fieldValue); + IUpdateable UpdateColumnsIF(bool isUpdateColumns, Expression> columns); + IUpdateable UpdateColumnsIF(bool isUpdateColumns, params string[] columns); + + + IUpdateable SetColumnsIF(bool isUpdateColumns, Expression> columns); + IUpdateable SetColumnsIF(bool isUpdateColumns, Expression> columns); + + + + IUpdateable IgnoreColumns(bool ignoreAllNullColumns, bool isOffIdentity = false, bool ignoreAllDefaultValue = false); + IUpdateable IgnoreColumns(Expression> columns); + IUpdateable IgnoreColumnsIF(bool isIgnore, Expression> columns); + + IUpdateable IgnoreColumns(params string[] columns); + IUpdateable IgnoreNullColumns(bool isIgnoreNull = true); + + + IUpdateable IsEnableUpdateVersionValidation(); + IUpdateable EnableDiffLogEvent(object businessData = null); + IUpdateable EnableDiffLogEventIF(bool isEnableDiffLog, object businessData = null); + IUpdateable ReSetValue(Action setValueExpression); + IUpdateable PublicSetColumns(Expression> filedNameExpression, string computationalSymbol); + IUpdateable PublicSetColumns(Expression> filedNameExpression, Expression> ValueExpExpression); + IUpdateable RemoveDataCache(); + IUpdateable RemoveDataCache(string likeString); + IUpdateable CallEntityMethod(Expression> method); + KeyValuePair> ToSql(); + string ToSqlString(); + void AddQueue(); + SplitTableUpdateProvider SplitTable(Func, IEnumerable> getTableNamesFunc); + SplitTableUpdateByObjectProvider SplitTable(); + IUpdateable EnableQueryFilter(); + IUpdateable Clone(); + IUpdateable InnerJoin(Expression> joinExpress); + IUpdateable InnerJoin(Expression> joinExpress, string tableName); + IUpdateable InnerJoin(ISugarQueryable queryable, Expression> joinExpress); + UpdateablePage PageSize(int pageSize); + IUpdateable In(object[] ids); + ParameterUpdateable UseParameter(); + } + public interface IUpdateable + { + int ExecuteCommand(); + Task ExecuteCommandAsync(); + IUpdateable InnerJoin(Expression> joinExpress); + IUpdateable SetColumns(Expression> columns); + IUpdateable Where(Expression> whereExpression); + } + public interface IUpdateable + { + IUpdateable InnerJoin(Expression> joinExpress); + int ExecuteCommand(); + Task ExecuteCommandAsync(); + IUpdateable SetColumns(Expression> columns); + IUpdateable Where(Expression> whereExpression); + } + public interface IUpdateable + { + int ExecuteCommand(); + Task ExecuteCommandAsync(); + IUpdateable SetColumns(Expression> columns); + IUpdateable Where(Expression> whereExpression); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/Insertable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/Insertable.cs new file mode 100644 index 000000000..1979fc0ce --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Interface/Insertable.cs @@ -0,0 +1,67 @@ +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial interface IInsertable where T : class, new() + { + InsertBuilder InsertBuilder { get; set; } + int ExecuteCommand(); + Task ExecuteCommandAsync(); + Task ExecuteCommandAsync(CancellationToken token); + List ExecuteReturnPkList(); + Task> ExecuteReturnPkListAsync(); + long ExecuteReturnSnowflakeId(); + List ExecuteReturnSnowflakeIdList(); + Task ExecuteReturnSnowflakeIdAsync(); + Task ExecuteReturnSnowflakeIdAsync(CancellationToken token); + Task> ExecuteReturnSnowflakeIdListAsync(); + Task> ExecuteReturnSnowflakeIdListAsync(CancellationToken token); + int ExecuteReturnIdentity(); + Task ExecuteReturnIdentityAsync(); + Task ExecuteReturnIdentityAsync(CancellationToken token); + T ExecuteReturnEntity(); + T ExecuteReturnEntity(bool isIncludesAllFirstLayer); + Task ExecuteReturnEntityAsync(); + Task ExecuteReturnEntityAsync(bool isIncludesAllFirstLayer); + bool ExecuteCommandIdentityIntoEntity(); + Task ExecuteCommandIdentityIntoEntityAsync(); + long ExecuteReturnBigIdentity(); + Task ExecuteReturnBigIdentityAsync(); + Task ExecuteReturnBigIdentityAsync(CancellationToken token); + IInsertable AS(string tableName); + IInsertable AsType(Type tableNameType); + IInsertable With(string lockString); + IInsertable InsertColumns(Expression> columns); + IInsertable InsertColumns(params string[] columns); + + IInsertable IgnoreColumns(Expression> columns); + IInsertable IgnoreColumns(params string[] columns); + IInsertable IgnoreColumns(bool ignoreNullColumn, bool isOffIdentity = false); + IInsertable IgnoreColumnsNull(bool isIgnoreNull = true); + + ISubInsertable AddSubList(Expression> subForeignKey); + ISubInsertable AddSubList(Expression> tree); + IParameterInsertable UseParameter(); + IInsertable CallEntityMethod(Expression> method); + + IInsertable EnableDiffLogEvent(object businessData = null); + IInsertable EnableDiffLogEventIF(bool isDiffLogEvent, object businessData = null); + IInsertable RemoveDataCache(); + IInsertable RemoveDataCache(string likeString); + KeyValuePair> ToSql(); + string ToSqlString(); + SqlServerBlukCopy UseSqlServer(); + MySqlBlukCopy UseMySql(); + OracleBlukCopy UseOracle(); + + SplitInsertable SplitTable(); + SplitInsertable SplitTable(SplitType splitType); + void AddQueue(); + IInsertable MySqlIgnore(); + IInsertable MySqlIgnore(bool isIgnore); + IInsertable PostgreSQLConflictNothing(string[] columns); + IInsertable OffIdentity(); + IInsertable OffIdentity(bool isSetOn); + InsertablePage PageSize(int pageSize); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/DynamicCoreHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/DynamicCoreHelper.cs new file mode 100644 index 000000000..1ce9168ec --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/DynamicCoreHelper.cs @@ -0,0 +1,171 @@ +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public static class DynamicCoreHelper + { + public static BuildPropertySelectorResult BuildPropertySelector(string shortName, Type type, List propertyNames, params object[] args) + { + BuildPropertySelectorResult result = new BuildPropertySelectorResult(); + if (type == null) + throw new ArgumentNullException(nameof(type)); + + if (propertyNames == null || propertyNames.Count == 0) + throw new ArgumentNullException(nameof(propertyNames)); + + var parameter = Expression.Parameter(type, shortName); + + // 解析多个属性,生成匿名类型 + var newAnonymousTypeStr = $"new {{ {string.Join(", ", propertyNames)} }}"; + newAnonymousTypeStr = ReplaceFormatParameters(newAnonymousTypeStr); + result.formattableString = FormattableStringFactory.Create(newAnonymousTypeStr, args); + var lambda = SqlSugarDynamicExpressionParser.ParseLambda(new[] { parameter }, null, newAnonymousTypeStr, args); + result.ResultNewType = lambda.Body.Type; + result.ShortName = shortName; + result.Exp = lambda; + return result; + } + + public class BuildPropertySelectorResult + { + public FormattableString formattableString { get; set; } + public string ShortName { get; set; } + public Type ResultNewType { get; set; } + public LambdaExpression Exp { get; internal set; } + } + public static Expression> GetWhere(string shortName, FormattableString whereSql) + { + return (Expression>)GetWhere(typeof(T), shortName, whereSql); + } + public static LambdaExpression GetWhere(Type entityType, string shortName, FormattableString whereSql) + { + var parameter = Expression.Parameter(entityType, shortName); + + // 提取 FormattableString 中的参数值 + var arguments = whereSql.GetArguments(); + + + var sql = ReplaceFormatParameters(whereSql.Format); + + sql = CompatibleDynamicLinqCoreBug(sql); + + // 构建动态表达式,使用常量表达式和 whereSql 中的参数值 + var lambda = SqlSugarDynamicExpressionParser.ParseLambda( + new[] { parameter }, + typeof(bool), + sql, + whereSql.GetArguments() + ); + + return lambda; + } + + private static string CompatibleDynamicLinqCoreBug(string sql) + { + //Compatible DynamicCore.Linq bug + if (sql?.Contains("SqlFunc.") == true) + { + sql = sql.Replace("SqlFunc.LessThan(", "SqlFunc.LessThan_LinqDynamicCore("); + sql = sql.Replace("SqlFunc.LessThan (", "SqlFunc.LessThan_LinqDynamicCore ("); + sql = sql.Replace("SqlFunc.GreaterThan(", "SqlFunc.GreaterThan_LinqDynamicCore("); + sql = sql.Replace("SqlFunc.GreaterThan (", "SqlFunc.GreaterThan_LinqDynamicCore ("); + } + return sql; + } + + public static LambdaExpression GetObject(Type entityType, string shortName, FormattableString whereSql) + { + var parameter = Expression.Parameter(entityType, shortName); + + // 提取 FormattableString 中的参数值 + var arguments = whereSql.GetArguments(); + + + var sql = ReplaceFormatParameters(whereSql.Format); + + // 构建动态表达式,使用常量表达式和 whereSql 中的参数值 + var lambda = SqlSugarDynamicExpressionParser.ParseLambda( + new[] { parameter }, + typeof(object), + sql, + whereSql.GetArguments() + ); + + return lambda; + } + public static LambdaExpression GetWhere(Dictionary parameterDictionary, FormattableString whereSql) + { + var parameters = parameterDictionary.Select(it => Expression.Parameter(it.Value, it.Key)).ToArray(); + + // 提取 FormattableString 中的参数值 + var arguments = whereSql.GetArguments(); + + + var sql = ReplaceFormatParameters(whereSql.Format); + + sql = CompatibleDynamicLinqCoreBug(sql); + + // 构建动态表达式,使用常量表达式和 whereSql 中的参数值 + var lambda = SqlSugarDynamicExpressionParser.ParseLambda( + parameters, + typeof(bool), + sql, + whereSql.GetArguments() + ); + + return lambda; + } + public static LambdaExpression GetMember(Dictionary parameterDictionary, Type propertyType, FormattableString memberSql) + { + var parameters = parameterDictionary.Select(it => Expression.Parameter(it.Value, it.Key)).ToArray(); + + // 提取 FormattableString 中的参数值 + var arguments = memberSql.GetArguments(); + + + var sql = ReplaceFormatParameters(memberSql.Format); + + // 构建动态表达式,使用常量表达式和 whereSql 中的参数值 + var lambda = SqlSugarDynamicExpressionParser.ParseLambda( + parameters, + propertyType, + sql, + memberSql.GetArguments() + ); + + return lambda; + } + public static LambdaExpression GetMember(Type entityType, Type propertyType, string shortName, FormattableString memberSql) + { + var parameter = Expression.Parameter(entityType, shortName); + + // 提取 FormattableString 中的参数值 + var arguments = memberSql.GetArguments(); + + + var sql = ReplaceFormatParameters(memberSql.Format); + + // 构建动态表达式,使用常量表达式和 whereSql 中的参数值 + var lambda = SqlSugarDynamicExpressionParser.ParseLambda( + new[] { parameter }, + propertyType, + sql, + memberSql.GetArguments() + ); + + return lambda; + } + private static string ReplaceFormatParameters(string format) + { + int parameterIndex = 0; // 起始参数索引 + return Regex.Replace(format, @"\{\d+\}", match => + { + string replacement = $"@{parameterIndex}"; + parameterIndex++; + return replacement; + }); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/DynamicParameters.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/DynamicParameters.cs new file mode 100644 index 000000000..9e4830562 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/DynamicParameters.cs @@ -0,0 +1,50 @@ +namespace SqlSugar +{ + public static class DynamicParameters + { + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4, string parameterName5, Type parameterType5) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 }, { parameterName5, parameterType5 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4, string parameterName5, Type parameterType5, string parameterName6, Type parameterType6) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 }, { parameterName5, parameterType5 }, { parameterName6, parameterType6 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4, string parameterName5, Type parameterType5, string parameterName6, Type parameterType6, string parameterName7, Type parameterType7) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 }, { parameterName5, parameterType5 }, { parameterName6, parameterType6 }, { parameterName7, parameterType7 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4, string parameterName5, Type parameterType5, string parameterName6, Type parameterType6, string parameterName7, Type parameterType7, string parameterName8, Type parameterType8) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 }, { parameterName5, parameterType5 }, { parameterName6, parameterType6 }, { parameterName7, parameterType7 }, { parameterName8, parameterType8 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4, string parameterName5, Type parameterType5, string parameterName6, Type parameterType6, string parameterName7, Type parameterType7, string parameterName8, Type parameterType8, string parameterName9, Type parameterType9) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 }, { parameterName5, parameterType5 }, { parameterName6, parameterType6 }, { parameterName7, parameterType7 }, { parameterName8, parameterType8 }, { parameterName9, parameterType9 } }; + } + + public static Dictionary Create(string parameterName, Type parameterType1, string parameterName2, Type parameterType2, string parameterName3, Type parameterType3, string parameterName4, Type parameterType4, string parameterName5, Type parameterType5, string parameterName6, Type parameterType6, string parameterName7, Type parameterType7, string parameterName8, Type parameterType8, string parameterName9, Type parameterType9, string parameterName10, Type parameterType10) + { + return new Dictionary() { { parameterName, parameterType1 }, { parameterName2, parameterType2 }, { parameterName3, parameterType3 }, { parameterName4, parameterType4 }, { parameterName5, parameterType5 }, { parameterName6, parameterType6 }, { parameterName7, parameterType7 }, { parameterName8, parameterType8 }, { parameterName9, parameterType9 }, { parameterName10, parameterType10 } }; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/SqlSugarDynamicExpressionParser.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/SqlSugarDynamicExpressionParser.cs new file mode 100644 index 000000000..2821b2cdf --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/DynamicLinq/SqlSugarDynamicExpressionParser.cs @@ -0,0 +1,53 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public static class SqlSugarDynamicExpressionParser + { + + public static LambdaExpression ParseLambda(ParameterExpression[] parameterExpressions, Type type, string sql, object[] objects) + { + if (StaticConfig.DynamicExpressionParserType == null) + { + Check.ExceptionEasy("Please at program startup assignment: StaticConfig DynamicExpressionParserType = typeof (DynamicExpressionParser); NUGET is required to install Dynamic.Core", "请在程序启动时赋值: StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser); 需要NUGET安装 Dynamic.Core"); + } + + if (StaticConfig.DynamicExpressionParsingConfig != null) + { + // 查找 ParseLambda 方法 + MethodInfo parseLambdaMethod = StaticConfig.DynamicExpressionParserType + .GetMyMethod("ParseLambda", 5, StaticConfig.DynamicExpressionParsingConfig.GetType(), typeof(ParameterExpression[]), typeof(Type), typeof(string), typeof(object[])); + + if (parseLambdaMethod == null) + { + throw new InvalidOperationException("ParseLambda method not found in DynamicExpressionParserType."); + } + + // 调用 ParseLambda 方法来解析 Lambda 表达式 + var lambda = (LambdaExpression)parseLambdaMethod.Invoke(null, new object[] { StaticConfig.DynamicExpressionParsingConfig, parameterExpressions, type, sql, objects }); + + return lambda; + } + else + { + + // 查找 ParseLambda 方法 + MethodInfo parseLambdaMethod = StaticConfig.DynamicExpressionParserType + .GetMyMethod("ParseLambda", 4, typeof(ParameterExpression[]), typeof(Type), typeof(string), typeof(object[])); + + if (parseLambdaMethod == null) + { + throw new InvalidOperationException("ParseLambda method not found in DynamicExpressionParserType."); + } + + // 调用 ParseLambda 方法来解析 Lambda 表达式 + var lambda = (LambdaExpression)parseLambdaMethod.Invoke(null, new object[] { parameterExpressions, type, sql, objects }); + + return lambda; + } + } + + } +} + diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonDeleteResult.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonDeleteResult.cs new file mode 100644 index 000000000..6861f3475 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonDeleteResult.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class JsonDeleteResult + { + public int UpdateRows { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonInsertResult.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonInsertResult.cs new file mode 100644 index 000000000..8b4765e74 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonInsertResult.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public class JsonInsertResult + { + public int IdentityValue { get; set; } + public int InsertCount { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonQueryResult.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonQueryResult.cs new file mode 100644 index 000000000..538bae170 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonQueryResult.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public class JsonQueryResult + { + public object Data { get; set; } + public Dictionary TableInfo { get; set; } + public int ToTalRows { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonTableConfig.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonTableConfig.cs new file mode 100644 index 000000000..acfc38501 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonTableConfig.cs @@ -0,0 +1,23 @@ +namespace SqlSugar +{ + + public class JsonTableConfig + { + public string TableName { get; set; } + public string TableDescription { get; set; } + public List Conditionals { get; set; } + public bool? AllowQuery { get; set; } + public bool? AllowUpdate { get; set; } + public bool? AllowDelete { get; set; } + public bool? AllowInsert { get; set; } + public List Columns { get; set; } + } + public class JsonColumnConfig + { + public string Name { get; set; } + public string Description { get; set; } + public string ValidateMessage { get; set; } + public object Validate { get; set; } + bool? AllowEdit { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonUpdateResult.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonUpdateResult.cs new file mode 100644 index 000000000..086352d19 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Entities/JsonUpdateResult.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class JsonUpdateResult + { + public int UpdateRows { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Enums/AsNameFormatType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Enums/AsNameFormatType.cs new file mode 100644 index 000000000..f06d0fd5a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Enums/AsNameFormatType.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + public enum AsNameFormatType + { + Default = 0, + NoConvert = 1 + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Enums/Json2SqlType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Enums/Json2SqlType.cs new file mode 100644 index 000000000..6e5603ff8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Enums/Json2SqlType.cs @@ -0,0 +1,12 @@ +namespace SqlSugar +{ + public enum JsonProviderType + { + Queryable, + QueryableCount, + Insertable, + InsertableIdentity, + Updateable, + Deleteable + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IFuncModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IFuncModel.cs new file mode 100644 index 000000000..6c920a7a4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IFuncModel.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public interface IFuncModel + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonClient.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonClient.cs new file mode 100644 index 000000000..45d04a595 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonClient.cs @@ -0,0 +1,13 @@ +namespace SqlSugar +{ + public interface IJsonClient + { + ISqlSugarClient Context { get; set; } + + IJsonProvider Deleteable(string json); + List GetTableNameList(string json); + IJsonProvider Insertable(string json); + IJsonQueryableProvider Queryable(string json); + IJsonProvider Updateable(string json); + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonDeleteableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonDeleteableProvider.cs new file mode 100644 index 000000000..92bfe2e3e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonDeleteableProvider.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public interface IJsonDeleteableProvider : IJsonProvider + { + // IJsonQueryableProvider UpdateColumns(string tableName, string[] columns); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonInsertableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonInsertableProvider.cs new file mode 100644 index 000000000..98b49595b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonInsertableProvider.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public interface IJsonInsertableProvider : IJsonProvider + { + // IJsonQueryableProvider UpdateColumns(string tableName, string[] columns); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonProvider.cs new file mode 100644 index 000000000..6cbb9dd4a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonProvider.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + + public interface IJsonProvider + { + List ToSqlList(); + SqlObjectResult ToSql(); + List ToSqlString(); + T ToResult(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonQueryableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonQueryableProvider.cs new file mode 100644 index 000000000..26b1259b5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonQueryableProvider.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public interface IJsonQueryableProvider : IJsonProvider + { + IJsonQueryableProvider ShowDesciption(); + IJsonQueryableProvider UseAuthentication(JsonTableConfig config); + IJsonQueryableProvider UseAuthentication(List config); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonToModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonToModel.cs new file mode 100644 index 000000000..94bd2de61 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonToModel.cs @@ -0,0 +1,15 @@ +namespace SqlSugar +{ + /// + /// Json to model + /// + public partial interface IContextMethods + { + List JsonToOrderByModels(string json); + List JsonToGroupByModels(string json); + List> JsonToColumnsModels(string json); + List JsonToSelectModels(string json); + IFuncModel JsonToSqlFuncModels(string json); + JoinModel JsonToJoinModels(string json); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonUpdateableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonUpdateableProvider.cs new file mode 100644 index 000000000..6b2a720bd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IJsonUpdateableProvider.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public interface IJsonUpdateableProvider : IJsonProvider + { + // IJsonQueryableProvider UpdateColumns(string tableName, string[] columns); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IModelToSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IModelToSql.cs new file mode 100644 index 000000000..25ddc7233 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/IModelToSql.cs @@ -0,0 +1,14 @@ +namespace SqlSugar +{ + /// + /// Json Model to sql + /// + public partial interface ISqlBuilder + { + KeyValuePair OrderByModelToSql(List models); + KeyValuePair GroupByModelToSql(List models); + KeyValuePair SelectModelToSql(List models); + KeyValuePair FuncModelToSql(IFuncModel model); + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/ISugarQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/ISugarQueryable.cs new file mode 100644 index 000000000..39ece9c02 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Interface/ISugarQueryable.cs @@ -0,0 +1,16 @@ +namespace SqlSugar +{ + public partial interface ISugarQueryable + { + ISugarQueryable Having(IFuncModel model); + ISugarQueryable OrderBy(List models); + ISugarQueryable GroupBy(List models); + DynamicCoreSelectModel Select(string expShortName, List columns, params object[] args); + ISugarQueryable Select(List models); + ISugarQueryable Select(List models); + ISugarQueryable Select(List models, AsNameFormatType type); + ISugarQueryable AS(string tableName, string shortName); + ISugarQueryable AddJoinInfo(string tableName, string shortName, IFuncModel models, JoinType type = JoinType.Left); + ISugarQueryable AddJoinInfo(List joinInfoParameters); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/FuncModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/FuncModel.cs new file mode 100644 index 000000000..fa7e81b5b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/FuncModel.cs @@ -0,0 +1,18 @@ +namespace SqlSugar +{ + public class ObjectFuncModel : IFuncModel + { + public string FuncName { get; set; } + public List Parameters { get; set; } + + public static ObjectFuncModel Create(string FuncName, params object[] Parameters) + { + return new ObjectFuncModel() { FuncName = FuncName, Parameters = Parameters?.ToList() }; + } + } + public class ArrayFuncModel : IFuncModel + { + public List Objects { get; set; } + } + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/GroupByModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/GroupByModel.cs new file mode 100644 index 000000000..9b986dba7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/GroupByModel.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + public class GroupByModel + { + public object FieldName { get; set; } + public static List Create(params GroupByModel[] groupModels) + { + return groupModels.ToList(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JoinModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JoinModel.cs new file mode 100644 index 000000000..7e22ff0c9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JoinModel.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + + public class JoinModel + { + public string TableName { get; set; } + public string ShortName { get; set; } + public ObjectFuncModel OnWhereList { get; set; } + public JoinType JoinType { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonQueryParameter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonQueryParameter.cs new file mode 100644 index 000000000..91b9c7cb9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonQueryParameter.cs @@ -0,0 +1,13 @@ +namespace SqlSugar +{ + internal class JsonQueryParameter + { + public bool IsSelect { get; set; } + public bool IsJoin { get; set; } + public int? PageIndex { get; set; } + public int? PageSize { get; set; } = 20; + public bool JoinNoSelect { get { return IsJoin && !IsSelect; } } + + public bool IsPage { get { return PageIndex != null; } } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonSqlModels.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonSqlModels.cs new file mode 100644 index 000000000..28d7e82f6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonSqlModels.cs @@ -0,0 +1,18 @@ +namespace SqlSugar +{ + public class SqlObjectResult + { + + + public SqlObjectResult(KeyValuePair> keyValuePair, JsonProviderType jsonSqlType) + { + this.Sql = keyValuePair.Key; + this.Parameters = keyValuePair.Value; + this.JsonSqlType = jsonSqlType; + } + + public JsonProviderType JsonSqlType { get; set; } + public string Sql { get; set; } + public List Parameters { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonTableNameInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonTableNameInfo.cs new file mode 100644 index 000000000..bc368fee9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/JsonTableNameInfo.cs @@ -0,0 +1,9 @@ +namespace SqlSugar +{ + public class JsonTableNameInfo + { + public string TableName { get; set; } + public string ShortName { get; set; } + public string Scheme { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/OrderByModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/OrderByModel.cs new file mode 100644 index 000000000..89a715782 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/OrderByModel.cs @@ -0,0 +1,12 @@ +namespace SqlSugar +{ + public class OrderByModel + { + public object FieldName { get; set; } + public OrderByType OrderByType { get; set; } + public static List Create(params OrderByModel[] orderByModel) + { + return orderByModel.ToList(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/SelectFieldModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/SelectFieldModel.cs new file mode 100644 index 000000000..62807776c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonModels/SelectFieldModel.cs @@ -0,0 +1,17 @@ +namespace SqlSugar +{ + public class SelectModel + { + public object FieldName { get; set; } + + [Obsolete("名字拼错使用FieldName")] + public object FiledName { get { return FieldName; } set { FieldName = value; } } + + public string AsName { get; set; } + + public static List Create(params SelectModel[] SelectModels) + { + return SelectModels.ToList(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/Helper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/Helper.cs new file mode 100644 index 000000000..1447dbc8a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/Helper.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// SqlFunc to model + /// + public partial class ContextMethods : IContextMethods + { + private bool IsObjct(JToken sqlfunc) + { + return sqlfunc.Type == JTokenType.Object; + } + private bool IsArray(string sqlfunc) + { + return sqlfunc.StartsWith('['); + } + public static bool IsSqlFunc(JToken item, string fileName) + { + return item.Type == JTokenType.Object || fileName.Contains("SqlFunc_", StringComparison.CurrentCultureIgnoreCase); + } + private bool IsObject(JToken parameters) + { + return parameters.Type == JTokenType.Object; + } + private bool IsArray(JToken parameters) + { + return parameters.Type == JTokenType.Array; + } + private bool IsString(JToken parameters) + { + return parameters.Type == JTokenType.String; + } + private bool IsFieldName(JToken item) + { + return item.ObjToString().Contains("fieldname", StringComparison.CurrentCultureIgnoreCase); + } + private bool IsArraySingleItem(JToken item) + { + return IsArray(item) && item.Count() == 1; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonSqlFuncToModel.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonSqlFuncToModel.cs new file mode 100644 index 000000000..745c7aaa8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonSqlFuncToModel.cs @@ -0,0 +1,84 @@ +using Newtonsoft.Json.Linq; + +using System.Text; + +namespace SqlSugar +{ + /// + /// SqlFunc to model + /// + public partial class ContextMethods : IContextMethods + { + #region Root + public ObjectFuncModel JsonToSqlFuncModels(JToken sqlfunc) + { + var key = sqlfunc.First(); + if (IsObjct(sqlfunc)) + { + return GetFuncModelByObject(key); + } + else + { + return GetFuncModelByArray(sqlfunc); + } + } + public IFuncModel JsonToSqlFuncModels(string sqlfunc) + { + if (IsArray(sqlfunc)) + { + return GetFuncModelByArray(sqlfunc); + } + else + { + return GetFuncModelByObject(sqlfunc); + } + } + #endregion + + #region Level 1 + private ObjectFuncModel GetFuncModelByArray(JToken sqlfunc) + { + ObjectFuncModel result = new ObjectFuncModel(); + result.Parameters = new List(); + result.FuncName = "Sqlfunc_Format"; + StringBuilder sb = new StringBuilder(); + foreach (var item in sqlfunc) + { + result.Parameters.Add(GetParameter(item)); + } + return result; + } + private ObjectFuncModel GetFuncModelByObject(JToken key) + { + ObjectFuncModel result = new ObjectFuncModel(); + JProperty jProperty = key.ToObject(); + result.FuncName = jProperty.Name; + var parameters = jProperty.Value; + result.Parameters = GetParameter(parameters); + return result; + } + private ObjectFuncModel GetFuncModelByObject(string sqlfunc) + { + var jObject = this.Context.Utilities.DeserializeObject(sqlfunc); + return JsonToSqlFuncModels(jObject); + } + private ObjectFuncModel GetFuncModelByArray(string sqlfunc) + { + ObjectFuncModel result = new ObjectFuncModel(); + result.Parameters = new List(); + result.FuncName = "Sqlfunc_Format"; + var jArrary = this.Context.Utilities.DeserializeObject(sqlfunc); + StringBuilder sb = new StringBuilder(); + foreach (var item in jArrary) + { + result.Parameters.Add(GetParameter(item)); + } + return result; + } + + #endregion + + + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonSqlFuncToParameters.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonSqlFuncToParameters.cs new file mode 100644 index 000000000..abb368075 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonSqlFuncToParameters.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class ContextMethods : IContextMethods + { + #region Root + public List GetParameter(JToken parameters) + { + List result = new List(); + if (IsString(parameters)) + { + result.Add(GetStringParameters(parameters)); + } + else if (IsArray(parameters)) + { + result.AddRange(GetArrayParameters(parameters)); + } + else if (IsObject(parameters)) + { + result.Add(GetObjectParameters(parameters)); + } + else + { + result.Add(GetObjectErrorParameters(parameters)); + } + return result; + } + #endregion + + #region Level1 + private static List GetObjectErrorParameters(JToken parameters) + { + Check.Exception(true, ErrorMessage.GetThrowMessage($" {parameters.ToString()} format is error ", $" {parameters.ToString()} 格式错误")); + return null; + } + + public List GetArrayParameters(JToken parameters) + { + List result = new List(); + foreach (var item in parameters) + { + result.Add(GetParameter(item)); + } + return result; + } + + public object GetObjectParameters(JToken parameters) + { + return JsonToSqlFuncModels(parameters); + } + + public object GetStringParameters(JToken parameters) + { + return parameters.ObjToString().ToCheckField(); + } + #endregion + + + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToColumnsModels.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToColumnsModels.cs new file mode 100644 index 000000000..1ade4ffc1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToColumnsModels.cs @@ -0,0 +1,57 @@ +namespace SqlSugar +{ + public partial class ContextMethods : IContextMethods + { + public List> JsonToColumnsModels(string json) + { + List> result = new List>(); + List conditionalModels = new List(); + if (IsArray(json)) + { + return GetColumnsByArray(json); + } + else + { + return GetColumnsByObject(json); + } + } + private List> GetColumnsByObject(string json) + { + List> result = new List>(); + var dic = this.Context.Utilities.DeserializeObject>(json); + result.Add(GetColumns(dic)); + return result; + } + private List> GetColumnsByArray(string json) + { + List> result = new List>(); + var jarray = this.Context.Utilities.DeserializeObject>>(json); + foreach (var item in jarray) + { + result.Add(GetColumns(item)); + } + return result; + } + + private Dictionary GetColumns(Dictionary dictionary) + { + Dictionary result = new Dictionary(); + foreach (var item in dictionary) + { + var value = GetValue(item); + result.Add(item.Key, value); + } + return result; + } + + private static object GetValue(KeyValuePair item) + { + if (item.Value == null) + return null; + var valueString = item.Value.ToString(); + var vallue = Json2SqlHelper.GetValue(valueString); + var type = Json2SqlHelper.GetType(valueString); + return UtilMethods.ConvertDataByTypeName(type, vallue); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToGroupByModels.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToGroupByModels.cs new file mode 100644 index 000000000..4ef7fef19 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToGroupByModels.cs @@ -0,0 +1,27 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class ContextMethods : IContextMethods + { + public List JsonToGroupByModels(string json) + { + List conditionalModels = new List(); + var jarray = this.Context.Utilities.DeserializeObject(json); + foreach (var item in jarray) + { + if (item.ObjToString().Contains("fieldname", StringComparison.CurrentCultureIgnoreCase)) + { + var model = item.ToObject(); + conditionalModels.Add(model); + } + else + { + conditionalModels.Add(new GroupByModel() { FieldName = item.ObjToString().ToCheckField() }); + } + } + return conditionalModels; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToJoinModels.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToJoinModels.cs new file mode 100644 index 000000000..7990e6b50 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToJoinModels.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// Json to model + /// + public partial class ContextMethods : IContextMethods + { + + public JoinModel JsonToJoinModels(string json) + { + JoinModel conditionalModels = new JoinModel(); + var array = JArray.Parse(json); + Check.Exception(array.Count != 3, json + " format error"); + var tableName = array[0]; + var shortName = array[1]; + var onWhere = array[2]; + JoinModel result = new JoinModel(); + result.TableName = tableName.ObjToString().ToCheckField(); + result.ShortName = shortName.ObjToString().ToCheckField(); + result.OnWhereList = JsonToSqlFuncModels(onWhere); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToOrderByModels.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToOrderByModels.cs new file mode 100644 index 000000000..3c6c7ae3b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToOrderByModels.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class ContextMethods : IContextMethods + { + public List JsonToOrderByModels(string json) + { + List conditionalModels = new List(); + var jarray = this.Context.Utilities.DeserializeObject(json); + foreach (var item in jarray) + { + if (IsFieldName(item)) + { + var model = item.ToObject(); + conditionalModels.Add(model); + } + else if (item.Type == JTokenType.String) + { + conditionalModels.Add(new OrderByModel() { FieldName = item.ObjToString().ToCheckField() }); + } + else if (item.Type == JTokenType.Array) + { + conditionalModels.Add(new OrderByModel() + { + FieldName = item[0].ObjToString(), + OrderByType = item[1].ObjToString().Equals("desc", StringComparison.CurrentCultureIgnoreCase) ? OrderByType.Desc : OrderByType.Asc + }); + } + } + return conditionalModels; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToSelectModels.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToSelectModels.cs new file mode 100644 index 000000000..f33491f98 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/JsonToModel/JsonToSelectModels.cs @@ -0,0 +1,65 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class ContextMethods : IContextMethods + { + public List JsonToSelectModels(string json) + { + List conditionalModels = new List(); + var jarray = this.Context.Utilities.DeserializeObject(json); + foreach (var item in jarray) + { + if (IsFieldName(item)) + { + var model = item.ToObject(); + conditionalModels.Add(model); + } + else if (IsString(item)) + { + conditionalModels.Add(new SelectModel() { FieldName = item.ObjToString().ToCheckField(), AsName = item.ObjToString().Replace(".", "_") }); + } + else if (IsArraySingleItem(item)) + { + object fileName = item[0].ObjToString(); + var asName = item[0].ObjToString().Replace(".", "_"); + if (IsSqlFunc(item[0], fileName.ObjToString())) + { + fileName = JsonToSqlFuncModels(item[0]); + } + conditionalModels.Add(new SelectModel() + { + FieldName = fileName, + AsName = asName + }); + + } + else if (IsArray(item)) + { + object fileName = item[0].ObjToString(); + var asName = item[1].ObjToString().Replace(".", "_"); + if (IsSqlFunc(item[0], fileName.ObjToString())) + { + fileName = JsonToSqlFuncModels(item[0]); + } + conditionalModels.Add(new SelectModel() + { + FieldName = fileName, + AsName = asName + }); + + } + else + { + conditionalModels.Add(new SelectModel() + { + FieldName = item.ObjToString().Trim(), + AsName = item.ObjToString().Trim() + }); + } + + } + return conditionalModels; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/FuncModelToSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/FuncModelToSql.cs new file mode 100644 index 000000000..f5df37e33 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/FuncModelToSql.cs @@ -0,0 +1,182 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + /// + ///Json model to sql + /// + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + #region Root + public KeyValuePair FuncModelToSql(IFuncModel model) + { + ObjectFuncModel data = model as ObjectFuncModel; + var name = data.FuncName; + var parameters = data.Parameters; + var dbMethods = this.Context.Queryable().QueryBuilder.LambdaExpressions.DbMehtods; + var methods = GetAllMethods(dbMethods); + var methodName = GetMethodName(name, methods); + var methodInfo = GetMethod(dbMethods, methodName); + var pars = methodInfo.GetParameters(); + + var resSql = ""; + var resPars = new List(); + resSql = GetSql(parameters, dbMethods, methodName, methodInfo, pars, resPars); + if (name.EqualCase("MappingColumn")) + { + if (!(this.Context?.CurrentConnectionConfig?.MoreSettings?.EnableModelFuncMappingColumn == true)) + { + Check.ExceptionEasy("Enable MappingColumn need in ConnectionConfig - > MoreSettings - > EnableModelFuncMappingColumn set to true", "MappingColumn考虑到风险情况需要开启才能使用,请在 ConnectionConfig->MoreSettings->EnableModelFuncMappingColumn设置为true"); + } + resSql = parameters.First() + ""; + } + return new KeyValuePair(resSql, resPars.ToArray()); + } + #endregion + + #region Level2 + private string GetSql(List parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, System.Reflection.ParameterInfo[] pars, List resPars) + { + string resSql; + if (IsNoParameter(pars)) + { + resSql = GetNoParameterMehtodSql(dbMethods, methodInfo); + } + else if (IsFormatMethod(methodName)) + { + resSql = GetFormatMethodSql(parameters, resPars); + } + else if (IsSqlFuncMethod(pars)) + { + resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars); + } + else if (IsMergeStringMethod(methodName)) + { + resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars); + } + else + { + resSql = GetNoSupportMethodSql(methodInfo); + } + + return resSql; + } + + + private static System.Reflection.MethodInfo GetMethod(IDbMethods dbMethods, string methodName) + { + return dbMethods.GetType().GetMethods() + .Where(it => it.Name == methodName) + .Where(it => it.Name != "Equals" || it.GetParameters().Length == 1 && it.GetParameters().First().ParameterType == typeof(MethodCallExpressionModel)) + .FirstOrDefault(); + } + private static string GetMethodName(string name, List methods) + { + var result = methods.FirstOrDefault(it => name.EqualCase("SqlFunc_" + it) || name.EqualCase(it)); + Check.Exception(result == null, $" {name} is error "); + return result; + } + private static List GetAllMethods(IDbMethods dbMethods) + { + return new ReflectionInoCacheService().GetOrCreate("Json2SqlGetFuncSql", () => + dbMethods.GetType() + .GetMethods().Where(it => it.Name != "GetHashCode").Select(it => it.Name).ToList()); + } + #endregion + + #region Level3 + private static string GetNoSupportMethodSql(System.Reflection.MethodInfo methodInfo) + { + throw new Exception(methodInfo.Name); + } + private string GetSqlFuncSql(List parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, List resPars) + { + string resSql; + var args = new List(); + int i = 0; + foreach (var item in parameters) + { + i++; + string value = null; + if (methodName.IsIn("ContainsArray", "ContainsArrayUseSqlParameters") && i == 1) + { + var first = Regex.Split(item + "", ":").First(); + var last = Regex.Split(item + "", ":").Last(); + object[] array = this.Context.Utilities.DeserializeObject(last); + value = GetParameterName(resPars, array); + } + else + { + value = GetSqlPart(item, resPars); + } + args.Add(new MethodCallExpressionArgs + { + MemberName = value, + MemberValue = resPars.FirstOrDefault(it => it.ParameterName == value)?.Value ?? value, + IsMember = true + }); + } + if (IsMergeStringMethod(methodName)) + { + return methodInfo.Invoke(dbMethods, new object[] { args.Select(it => it.MemberName.ObjToString()).ToArray() }).ObjToString(); + } + if (IsToStringFormat(methodName, args)) + { + var fieldName = args.First().MemberName.ObjToString(); + var format = args.Last().MemberValue.ObjToString(); + var queryable = this.Context.Queryable() + .Select(it => SqlFunc.MappingColumn(fieldName).ToString(format)); + var select = queryable.QueryBuilder.GetSelectValue; + return select; + } + resSql = methodInfo.Invoke(dbMethods, new object[] { new MethodCallExpressionModel() { + Name=methodName, + Args=args + } }).ObjToString(); + return resSql; + } + + private static bool IsToStringFormat(string methodName, List args) + { + return methodName == nameof(ToString) && args?.Count == 2; + } + + private string GetFormatMethodSql(List parameters, List resPars) + { + string resSql; + var objects = new List(); + foreach (var item in parameters) + { + var value = GetSqlPart(item, resPars); + objects.Add(value.ObjToString()); + } + resSql = string.Join(" ", string.Join(" ", objects)); + return resSql; + } + private static string GetNoParameterMehtodSql(IDbMethods dbMethods, System.Reflection.MethodInfo methodInfo) + { + return methodInfo.Invoke(dbMethods, Array.Empty()).ObjToString(); + } + #endregion + + #region Helper + private static bool IsMergeStringMethod(string methodName) + { + return methodName == "MergeString"; + } + + private static bool IsSqlFuncMethod(System.Reflection.ParameterInfo[] pars) + { + return pars.First().ParameterType == typeof(MethodCallExpressionModel); + } + private static bool IsFormatMethod(string methodName) + { + return methodName.EqualCase("format"); + } + private static bool IsNoParameter(System.Reflection.ParameterInfo[] pars) + { + return pars.Length == 0; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/GroupByModelToSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/GroupByModelToSql.cs new file mode 100644 index 000000000..3d9d99acb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/GroupByModelToSql.cs @@ -0,0 +1,31 @@ +using System.Text; +namespace SqlSugar +{ + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + public KeyValuePair GroupByModelToSql(List models) + { + StringBuilder sql = new StringBuilder(""); + var pars = new List { }; + foreach (var item in models) + { + if (item is GroupByModel && item.FieldName is IFuncModel) + { + var orderByModel = item as GroupByModel; + sql.Append($" {GetSqlPart(item.FieldName, pars)} ,"); + } + else if (item is GroupByModel) + { + var orderByModel = item as GroupByModel; + sql.Append($" {this.GetTranslationColumnName(orderByModel.FieldName.ObjToString().ToSqlFilter())} ,"); + } + else + { + + } + + } + return new KeyValuePair(sql.ToString().TrimEnd(','), pars?.ToArray()); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/OrderByModelToSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/OrderByModelToSql.cs new file mode 100644 index 000000000..b2c748b20 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/OrderByModelToSql.cs @@ -0,0 +1,31 @@ +using System.Text; +namespace SqlSugar +{ + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + public KeyValuePair OrderByModelToSql(List models) + { + StringBuilder sql = new StringBuilder(""); + List pars = new List() { }; + foreach (var item in models) + { + if (item is OrderByModel && item.FieldName is IFuncModel) + { + var orderByModel = item as OrderByModel; + sql.Append($" {GetSqlPart(item.FieldName, pars)} {orderByModel.OrderByType.ToString().ToUpper()} ,"); + } + else if (item is OrderByModel) + { + var orderByModel = item as OrderByModel; + sql.Append($" {this.GetTranslationColumnName(orderByModel.FieldName.ObjToString().ToSqlFilter())} {orderByModel.OrderByType.ToString().ToUpper()} ,"); + } + else + { + + } + + } + return new KeyValuePair(sql.ToString().TrimEnd(','), pars?.ToArray()); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/SelectModelToSql.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/SelectModelToSql.cs new file mode 100644 index 000000000..5f00ee787 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/SelectModelToSql.cs @@ -0,0 +1,54 @@ +using System.Text; +namespace SqlSugar +{ + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + public KeyValuePair SelectModelToSql(List models) + { + StringBuilder sql = new StringBuilder(""); + var pars = new List { }; + foreach (var item in models) + { + if (item is SelectModel) + { + var orderByModel = item as SelectModel; + orderByModel.AsName = GetAsName(orderByModel); + orderByModel.FieldName = GetSqlPart(orderByModel.FieldName, pars).ObjToString(); + AppendFiledName(sql, orderByModel); + } + else + { + + } + } + return new KeyValuePair(sql.ToString().TrimEnd(','), pars.ToArray()); + } + + private string GetAsName(SelectModel orderByModel) + { + if (orderByModel.AsName.IsNullOrEmpty()) + { + orderByModel.AsName = orderByModel.FieldName.ObjToString(); + } + if (orderByModel.AsName.StartsWith(UtilConstants.ReplaceKey)) + { + return orderByModel.AsName.Replace(UtilConstants.ReplaceKey, string.Empty); + } + if (orderByModel.AsName?.Contains('[') == true) + { + orderByModel.AsName = orderByModel.AsName.Trim('[').Trim(']'); + return this.SqlTranslationLeft + orderByModel.AsName + this.SqlTranslationRight; + } + if (this.SqlTranslationLeft != null && orderByModel.AsName?.Contains(this.SqlTranslationLeft) == true) + { + return orderByModel.AsName; + } + return this.SqlTranslationLeft + orderByModel.AsName + this.SqlTranslationRight; + } + + private void AppendFiledName(StringBuilder sql, SelectModel orderByModel) + { + sql.Append($" {orderByModel.FieldName} AS {orderByModel.AsName} ,"); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/SqlPart.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/SqlPart.cs new file mode 100644 index 000000000..661529f36 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/ModelToSql/SqlPart.cs @@ -0,0 +1,152 @@ +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder + { + #region Variable + private string[] SqlSplicingOperator = new string[] { ">", ">=", "<", "<=", "(", ")", "!=", "<>", "not", "=", "||", "&&", "&", "|", "null", "is", "isnot", "like", "nolike", "+", "-", "*", "/", "%", "$casewhen", "$then", "$when", "$else", "$end" }; + #endregion + + #region Root + private string GetSqlPart(object value, List pars) + { + Check.Exception(value == null, $" FiledName is error "); + if (IsSqlSplicingOperator(value)) + { + return GetSqlSplicingOperator(value); + } + else if (IsString(value)) + { + return GetSqlPartByString(value, pars); + } + else if (IsListObject(value)) + { + return GetSqlPartByListObject(value, pars); + } + else if (IsObjectFunc(value)) + { + return GetSqlPartByObjectFuncModel(value, pars); + } + else + { + return GetSqlPartError(value); + } + } + + #endregion + + #region Level2 + + private static string GetSqlSplicingOperator(object value) + { + var result = value.ObjToString(); + if (result == "||") return "OR"; + else if (result == "&&") return "AND"; + else if (result.EqualCase("isnot")) return " IS NOT "; + else if (result.EqualCase("$casewhen")) return " CASE WHEN "; + else if (result.EqualCase("$then")) return " THEN "; + else if (result.EqualCase("$when")) return " WHEN "; + else if (result.EqualCase("$else")) return " ELSE "; + else if (result.EqualCase("$end")) return " END "; + return result; + } + private static string GetSqlPartError(object value) + { + Check.Exception(value == null, $" {value} is error "); + return null; + } + private string GetSqlPartByObjectFuncModel(object value, List pars) + { + var data = value as ObjectFuncModel; + var obj = FuncModelToSql(data); + pars.AddRange(obj.Value); + return obj.Key; + } + private string GetSqlPartByListObject(object value, List pars) + { + var list = (value as List); + if (list.Count == 1) + { + return GetSqlPart(list.First(), pars).ObjToString(); + } + else + { + Check.Exception(value == null, $" {value} is error "); + return null; + } + } + private string GetSqlPartByString(object value, List pars) + { + var valueString = value.ObjToString().Trim(); + if (Json2SqlHelper.IsSqlValue(valueString)) + { + return GetParameterName(pars, valueString); + } + else + { + return this.GetTranslationColumnName(value.ObjToString().ToCheckField()); + } + } + #endregion + + #region Level3 + private string GetSplicingOperator(string valueString) + { + var parvalue = Regex.Match(valueString, @"\@s\:(.+)").Groups[1].Value; + if (parvalue == null) parvalue = ""; + parvalue = parvalue.Trim(); + if (parvalue.ToLower().IsIn(SqlSplicingOperator)) + { + return parvalue; + } + else + { + Check.ExceptionEasy($"{valueString} is error ", $"{valueString} 不是有效的拼接符号,拼接符号有:and、or、>=、<=、>、<、=、(、)"); + } + return parvalue; + } + private string GetParameterName(List pars, string valueString) + { + object parvalue = Json2SqlHelper.GetValue(valueString); + SugarParameter parameter = new SugarParameter("@p" + pars.Count, parvalue); + var type = Json2SqlHelper.GetType(valueString); + parvalue = UtilMethods.ConvertDataByTypeName(type, parvalue.ObjToString()); + var parname = GetParameterName(pars, parvalue); + return parname; + } + internal int GetParameterNameIndex = 100; + + private string GetParameterName(List pars, object parvalue) + { + var parname = "@p" + pars.Count + "_" + (GetParameterNameIndex) + $"{this.QueryBuilder?.LambdaExpressions?.ParameterIndex}"; + SugarParameter parameter = new SugarParameter(parname, parvalue); + pars.Add(parameter); + GetParameterNameIndex++; + if (this.QueryBuilder != null) + this.QueryBuilder.LambdaExpressions.ParameterIndex++; + return parname; + } + #endregion + + #region Helper + + private static bool IsListObject(object value) + { + return value.GetType() == typeof(List); + } + private static bool IsString(object value) + { + return value.GetType() == typeof(string); + } + private static bool IsObjectFunc(object value) + { + return value is ObjectFuncModel; + } + private bool IsSqlSplicingOperator(object value) + { + return SqlSplicingOperator.Contains(value.ObjToString()); + } + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Common/JsonCommonProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Common/JsonCommonProvider.cs new file mode 100644 index 000000000..710ff9ee0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Common/JsonCommonProvider.cs @@ -0,0 +1,87 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + internal class JsonCommonProvider + { + public JsonCommonProvider(ISqlSugarClient context) + { + //this.context = context; + this.sqlBuilder = InstanceFactory.GetSqlbuilder(context.CurrentConnectionConfig); + if (context is SqlSugarProvider) + { + this.sqlBuilder.Context = context as SqlSugarProvider; + } + else if (context is SqlSugarScopeProvider) + { + this.sqlBuilder.Context = (context as SqlSugarScopeProvider).conn; + } + else if (context is SqlSugarScope) + { + this.sqlBuilder.Context = (context as SqlSugarScope).GetConnection(context.CurrentConnectionConfig.ConfigId); + } + else + { + this.sqlBuilder.Context = (context as SqlSugarClient).Context; + } + } + //public ISqlSugarClient context { get; set; } + public ISqlBuilder sqlBuilder { get; set; } + public int ParameterIndex { get { return ((SqlBuilderProvider)sqlBuilder)?.GetParameterNameIndex ?? 0; } } + public JsonTableNameInfo GetTableName(JToken item) + { + JsonTableNameInfo jsonTableNameInfo = new JsonTableNameInfo(); + if (item.First().Type == JTokenType.Array && item.First.Count() == 2) + { + var tableName = item.First()[0].ObjToString(); + var shortName = item.First()[1].ObjToString(); + jsonTableNameInfo.ShortName = shortName; + jsonTableNameInfo.TableName = tableName; + + } + else + { + var value = item.First().ToString(); + jsonTableNameInfo.TableName = value; + } + return jsonTableNameInfo; + } + public KeyValuePair GetWhere(string item, SqlSugarProvider context) + { + + if (!IsConditionalModel(item)) + { + var obj = context.Utilities.JsonToSqlFuncModels(item); + var sqlobj = sqlBuilder.FuncModelToSql(obj); + return sqlobj; + } + else + { + var obj = context.Utilities.JsonToConditionalModels(item); + var sqlObj = sqlBuilder.ConditionalModelToSql(obj, 0); + return sqlObj; + } + } + public KeyValuePair GetWhere(JToken item, SqlSugarProvider context) + { + var value = item.First().ToString(); + Check.ExceptionEasy(item.First().Type != JTokenType.Array, "Where format error " + item, "Where格式错误" + item); + if (!IsConditionalModel(value)) + { + var obj = context.Utilities.JsonToSqlFuncModels(value); + var sqlobj = sqlBuilder.FuncModelToSql(obj); + return sqlobj; + } + else + { + var obj = context.Utilities.JsonToConditionalModels(value); + var sqlObj = sqlBuilder.ConditionalModelToSql(obj, 0); + return sqlObj; + } + } + + private static bool IsConditionalModel(string value) + { + return value.Contains("fieldname", StringComparison.CurrentCultureIgnoreCase); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Deleteable/JsonDeleteableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Deleteable/JsonDeleteableProvider.cs new file mode 100644 index 000000000..ef2d5df88 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Deleteable/JsonDeleteableProvider.cs @@ -0,0 +1,88 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public class JsonDeleteableProvider : IJsonDeleteableProvider + { + private ISqlSugarClient context; + private JObject jObject; + private JsonCommonProvider jsonCommonProvider; + private IDeleteable sugarDeleteable = null; + public JsonDeleteableProvider(ISqlSugarClient context, JObject jObject) + { + this.jObject = jObject; + this.context = context; + this.jsonCommonProvider = new JsonCommonProvider(context); + } + public SqlObjectResult ToSql() + { + return this.ToSqlList().First(); + } + public List ToSqlList() + { + List result = new List(); + JsonQueryParameter jsonQueryParameter = new JsonQueryParameter(); + var appendTypeNames = this.jObject.AsJEnumerable().ToList(); + this.sugarDeleteable = this.context.Deleteable(); + foreach (JToken item in appendTypeNames) + { + AppendAll(jsonQueryParameter, item); + } + result.Add(new SqlObjectResult(this.sugarDeleteable.ToSql(), JsonProviderType.Deleteable)); + return result; + } + private void AppendAll(JsonQueryParameter jsonQueryParameter, JToken item) + { + var name = item.Path.ToLower(); + if (IsWhere(name)) + { + AppendWhere(item); + } + else if (IsTable(name)) + { + AppendTable(item); + } + } + private void AppendTable(JToken item) + { + var tableInfo = jsonCommonProvider.GetTableName(item); + var tableName = tableInfo.TableName.ToCheckField(); + if (tableInfo.ShortName.HasValue()) + { + tableName = tableInfo.ShortName + "." + tableInfo.TableName; + } + this.sugarDeleteable.AS(tableName); + } + private void AppendWhere(JToken item) + { + var sqlObj = jsonCommonProvider.GetWhere(item, sugarDeleteable.DeleteBuilder.Context); + sugarDeleteable.Where(sqlObj.Key, sqlObj.Value); + } + private static bool IsTable(string name) + { + return name.Equals(JsonProviderConfig.KeyDeleteable.Get(), StringComparison.CurrentCultureIgnoreCase); + } + private static bool IsWhere(string name) + { + return name.Equals("Where", StringComparison.CurrentCultureIgnoreCase); + } + public string ToSqlString() + { + throw new NotImplementedException(); + } + + public JsonDeleteResult ToResult() + { + var result = new JsonDeleteResult(); + var sqlInfo = this.ToSqlList(); + var sqlInfoResult = sqlInfo.First(); + result.UpdateRows = this.context.Ado.ExecuteCommand(sqlInfoResult.Sql, sqlInfoResult.Parameters); + return result; + } + + List IJsonProvider.ToSqlString() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendIdentity.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendIdentity.cs new file mode 100644 index 000000000..3de2ba8c9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendIdentity.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + public partial class JsonInsertableProvider : IJsonInsertableProvider + { + private void AppendIdentity(JToken item) + { + var tableInfo = jsonCommonProvider.GetTableName(item); + this.IdentityId = tableInfo.TableName; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendName.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendName.cs new file mode 100644 index 000000000..dcac36413 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendName.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + public partial class JsonInsertableProvider : IJsonInsertableProvider + { + private void AppendName(JToken item) + { + var tableInfo = jsonCommonProvider.GetTableName(item); + this.TableName = tableInfo.TableName.ToCheckField(); + if (tableInfo.ShortName.HasValue()) + { + this.TableName = tableInfo.ShortName + "." + tableInfo.TableName; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendRow.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendRow.cs new file mode 100644 index 000000000..30386086e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/AppendRow.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + public partial class JsonInsertableProvider : IJsonInsertableProvider + { + private void AppendRow(JToken item) + { + var value = item.First().ToString(); + var dics = context.Utilities.JsonToColumnsModels(value); + sugarInsertable = this.context.Insertable(dics).AS(this.TableName); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/Helper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/Helper.cs new file mode 100644 index 000000000..a883ef277 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/Helper.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class JsonInsertableProvider : IJsonInsertableProvider + { + private static bool IsColumns(string name) + { + return name.Equals("columns", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsName(string name) + { + return name.Equals(JsonProviderConfig.KeyInsertable.Get(), StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsIdentity(string name) + { + return name.Equals("identity", StringComparison.CurrentCultureIgnoreCase); + } + private List ToSqlHelper() + { + List result = new List(); + JsonQueryParameter jsonQueryParameter = new JsonQueryParameter(); + var appendTypeNames = this.jObject.AsJEnumerable().ToList(); + foreach (JToken item in appendTypeNames.OrderBy(it => it.Path.EqualCase(JsonProviderConfig.KeyInsertable.Get()) ? 0 : 1)) + { + AppendAll(jsonQueryParameter, item); + } + var addItem = this.sugarInsertable.ToSql(); + if (this.IdentityId.HasValue()) + { + result.Add(new SqlObjectResult(addItem, JsonProviderType.InsertableIdentity)); + } + else + { + result.Add(new SqlObjectResult(addItem, JsonProviderType.Insertable)); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/JsonInsertableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/JsonInsertableProvider.cs new file mode 100644 index 000000000..3506f168c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/JsonInsertableProvider.cs @@ -0,0 +1,60 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class JsonInsertableProvider : IJsonInsertableProvider + { + public SqlObjectResult ToSql() + { + return this.ToSqlList().First(); + } + public JsonInsertableProvider(ISqlSugarClient context, JObject jObject) + { + this.jObject = jObject; + this.context = context; + this.jsonCommonProvider = new JsonCommonProvider(context); + } + public JsonInsertResult ToResult() + { + var result = new JsonInsertResult(); + var sqlInfo = this.ToSqlList(); + var sqlInfoResult = sqlInfo.First(); + if (sqlInfoResult.JsonSqlType != JsonProviderType.InsertableIdentity) + { + result.InsertCount = this.context.Ado.ExecuteCommand(sqlInfoResult.Sql, sqlInfoResult.Parameters); + } + else + { + result.InsertCount = this.Count; + result.IdentityValue = this.context.Ado.GetInt(sqlInfoResult.Sql, sqlInfoResult.Parameters); + } + return result; + } + public List ToSqlList() + { + return ToSqlHelper(); + } + + private void AppendAll(JsonQueryParameter jsonQueryParameter, JToken item) + { + var name = item.Path.ToLower(); + if (IsName(name)) + { + AppendName(item); + } + else if (IsIdentity(name)) + { + AppendIdentity(item); + } + else if (IsColumns(name)) + { + AppendRow(item); + } + } + + public List ToSqlString() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/PrivateProperty.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/PrivateProperty.cs new file mode 100644 index 000000000..1aa32faef --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Insertable/PrivateProperty.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class JsonInsertableProvider : IJsonInsertableProvider + { + private ISqlSugarClient context; + private JObject jObject; + private JsonCommonProvider jsonCommonProvider; + private string TableName { get; set; } + private string IdentityId { get; set; } + private int Count { get; set; } + private IInsertable> sugarInsertable; + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ApendJoinLastAfter.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ApendJoinLastAfter.cs new file mode 100644 index 000000000..c4bfabc60 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ApendJoinLastAfter.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + /// + /// ApendJoinLastAfter + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private void ApendJoinLastAfter(JToken item) + { + if (IsAppendSelect()) + { + JArray jArray = new JArray(); + var tableConfigs = this.jsonTableConfigs.GroupBy(it => it.TableName).Select(it => it.First()).ToList(); + var isJoinTable = IsAnyJoin(appendTypeNames); + foreach (var config in tableConfigs) + { + + if (isJoinTable) + { + + } + else + { + if (config.Columns.Count != 0) + { + foreach (var column in config.Columns.Select(it => it.Name).Distinct()) + { + jArray.Add(column); + } + } + } + } + this.AppendSelect(jArray); + } + } + + private bool IsAppendSelect() + { + return !IsAnySelect(appendTypeNames) && this.jsonTableConfigs.Count != 0; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendFrom.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendFrom.cs new file mode 100644 index 000000000..f84e40c96 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendFrom.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// AppendFrom + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + + private void AppendFrom(JToken item) + { + var tableNameInfo = jsonCommonProvider.GetTableName(item); + tableNameInfo.TableName.ToCheckField(); + AddMasterTableInfos(tableNameInfo); + if (tableNameInfo.ShortName.HasValue()) + { + this.sugarQueryable.AS(tableNameInfo.TableName, tableNameInfo.ShortName); + } + else + { + this.sugarQueryable.AS(tableNameInfo.TableName, tableNameInfo.ShortName); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendGroupBy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendGroupBy.cs new file mode 100644 index 000000000..c82a03d55 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendGroupBy.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + /// + /// AppendGroupBy + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + + private void AppendGroupBy(JToken item) + { + var value = item.First().ToString(); + var obj = context.Utilities.JsonToGroupByModels(value); + sugarQueryable.GroupBy(obj); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendHaving.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendHaving.cs new file mode 100644 index 000000000..a67b36322 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendHaving.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + /// + /// AppendHaving + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private void AppendHaving(JToken item) + { + var value = item.First().ToString(); + var obj = context.Utilities.JsonToSqlFuncModels(value); + sugarQueryable.Having(obj); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendJoin.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendJoin.cs new file mode 100644 index 000000000..a31196f80 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendJoin.cs @@ -0,0 +1,52 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + /// + /// AppendJoin + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private bool AppendJoin(JToken item) + { + BeforeJoin(); + bool isJoin = true; + var value = item.First().ToString(); + var obj = context.Utilities.JsonToJoinModels(value); + sugarQueryable.AddJoinInfo(obj.TableName, obj.ShortName, obj.OnWhereList, GetJoinType(item)); + AddTableInfos(obj.TableName, obj.ShortName); + AfterJoin(); + return isJoin; + } + + private static JoinType GetJoinType(JToken obj) + { + var key = obj.Path.ToLower(); + if (key.Contains("right")) + { + return JoinType.Right; + } + else if (key.Contains("left")) + { + return JoinType.Left; + } + else if (key.Contains("full")) + { + return JoinType.Full; + } + else + { + return JoinType.Inner; + } + } + + private void AfterJoin() + { + + } + + private void BeforeJoin() + { + + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendOrderBy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendOrderBy.cs new file mode 100644 index 000000000..59dd09971 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendOrderBy.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// AppendOrderBy + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private void AppendOrderBy(JToken item) + { + var value = item.First().ToString(); + var obj = context.Utilities.JsonToOrderByModels(value); + sugarQueryable.OrderBy(obj); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendPage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendPage.cs new file mode 100644 index 000000000..fd5fd9171 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendPage.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + /// + /// AppendPage + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private int AppendPageSize(JToken item) + { + return Convert.ToInt32(item.First().ToString().ObjToInt()); + } + + private int AppendPageNumber(JToken item) + { + var result = Convert.ToInt32(item.First().ToString().ObjToInt()); + if (result == 0) + { + result = 1; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendSelect.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendSelect.cs new file mode 100644 index 000000000..7f211b66e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendSelect.cs @@ -0,0 +1,79 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + + /// + /// AppendSelect + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private bool AppendSelect(JToken item) + { + bool isSelect = true; + if (item.Type == JTokenType.Property) + { + var value = item.First().ToString(); + var obj = context.Utilities.JsonToSelectModels(value); + obj = FilterSelect(obj); + sugarQueryable.Select(obj); + } + else + { + var obj = context.Utilities.JsonToSelectModels(item.ToString()); + obj = FilterSelect(obj); + sugarQueryable.Select(obj); + } + return isSelect; + } + + private List FilterSelect(List obj) + { + if (this.jsonTableConfigs.Count == 0) + { + return obj; + } + List result = new List(); + foreach (var item in obj) + { + if (item.FieldName is string) + { + var tableName = GetTableName(item.FieldName + ""); + var columnName = GetColumnName(item.FieldName + ""); + if (IsMyColums(tableName, columnName)) + { + result.Add(item); + } + } + else + { + result.Add(item); + } + } + return result; + } + + private bool IsMyColums(string tableName, string columnName) + { + return this.jsonTableConfigs.Any(it => it.TableName.EqualCase(tableName) + && it.Columns.Any(z => z.Name.EqualCase(columnName))); + } + + private string GetColumnName(string filedName) + { + return filedName.Split('.').Last(); + } + + private string GetTableName(string filedName) + { + if (!filedName.Contains('.')) + { + return TableInfos.First(it => it.IsMaster).Table; + } + else + { + var shortName = filedName.Split('.').First(); + return TableInfos.First(it => it.ShortName == shortName).Table; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendWhere.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendWhere.cs new file mode 100644 index 000000000..6f008c040 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/AppendWhere.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + + /// + /// AppendWhere + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private void AppendWhere(JToken item) + { + BeforeWhere(); + var sqlObj = jsonCommonProvider.GetWhere(item, sugarQueryable.Context); + sugarQueryable.Where(sqlObj.Key, sqlObj.Value); + AfterWhere(); + } + + private void AfterWhere() + { + + } + + private void BeforeWhere() + { + if (!IsExecutedBeforeWhereFunc) + { + BeforeWhereFunc(); + IsExecutedBeforeWhereFunc = true; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Entities.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Entities.cs new file mode 100644 index 000000000..ffebe109a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Entities.cs @@ -0,0 +1,11 @@ +namespace SqlSugar +{ + internal class JsonQueryableProvider_TableInfo + { + public string Table { get; set; } + public string ShortName { get; set; } + public bool IsMaster { get; set; } + public bool IsJoin { get; set; } + public int Index { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Helper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Helper.cs new file mode 100644 index 000000000..8a251369b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Helper.cs @@ -0,0 +1,100 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// Helper + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private static bool IsJoin(string name) + { + return name.StartsWith("LeftJoin", StringComparison.CurrentCultureIgnoreCase) || name.StartsWith("RightJoin", StringComparison.CurrentCultureIgnoreCase) || name.StartsWith("InnerJoin", StringComparison.CurrentCultureIgnoreCase); + } + private static bool IsJoinLastAfter(string name) + { + return name == "joinlastafter"; + } + + private static bool IsPageSize(string name) + { + return name.Equals("PageSize", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsPageNumber(string name) + { + return name.Equals("PageNumber", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsSelect(string name) + { + return name.Equals("Select", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsHaving(string name) + { + return name.Equals("Having", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsGroupBy(string name) + { + return name.Equals("GroupBy", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsOrderBy(string name) + { + return name.Equals("OrderBy", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsWhere(string name) + { + return name.Equals("Where", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsForm(string name) + { + return name.Equals(JsonProviderConfig.KeyQueryable.Get(), StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsAnySelect(List appendTypeNames) + { + return appendTypeNames.Any(it => IsSelect(it.Path.ToLower())); + } + private static bool IsAnyJoin(List appendTypeNames) + { + return appendTypeNames.Any(it => IsJoin(it.Path.ToLower())); + } + private int GetSort(string name) + { + if (IsForm(name)) + { + return 0; + } + else if (IsJoin(name)) + { + return 1; + } + else if (IsJoinLastAfter(name)) + { + return 2; + } + else + { + return 100; + } + } + private void AddMasterTableInfos(JsonTableNameInfo tableNameInfo) + { + AddTableInfos(tableNameInfo.TableName, tableNameInfo.ShortName, true); + } + private void AddTableInfos(string tableName, string shortName, bool isMaster = false) + { + UtilMethods.IsNullReturnNew(TableInfos); + TableInfos.Add(new JsonQueryableProvider_TableInfo() { Table = tableName, ShortName = shortName, IsMaster = true }); + } + private JsonQueryableProvider_TableInfo GetMasterTable() + { + return this.TableInfos.First(it => it.IsMaster); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/JsonQueryableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/JsonQueryableProvider.cs new file mode 100644 index 000000000..86f9c9654 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/JsonQueryableProvider.cs @@ -0,0 +1,114 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// JsonQueryableProvider + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + + public JsonQueryableProvider(ISqlSugarClient context, JObject jobject) + { + this.jobject = jobject; + this.context = context; + this.jsonCommonProvider = new JsonCommonProvider(context); + } + public IJsonQueryableProvider ShowDesciption() + { + this.IsDescription = true; + return this; + } + public IJsonQueryableProvider UseAuthentication(JsonTableConfig config) + { + if (config == null) + { + jsonTableConfigs = new List() { config }; + } + else + { + jsonTableConfigs.Add(config); + } + return this; + } + public IJsonQueryableProvider UseAuthentication(List configs) + { + foreach (JsonTableConfig config in configs) + { + UseAuthentication(config); + } + return this; + } + + public SqlObjectResult ToSql() + { + return this.ToSqlList().First(); + } + public JsonQueryResult ToResult() + { + return ToResultDefault(); + } + + public List ToSqlList() + { + var result = ToSqlDefault(); + return result; + } + + public List ToSqlString() + { + throw new NotImplementedException(); + } + + private void AppendQueryableAll(JsonQueryParameter jsonQueryParameter, JToken item) + { + SetQueryableParameterIndex(); + var name = item.Path.ToLower(); + if (IsForm(name)) + { + AppendFrom(item); + } + else if (IsWhere(name)) + { + AppendWhere(item); + } + else if (IsOrderBy(name)) + { + AppendOrderBy(item); + } + else if (IsJoinLastAfter(name)) + { + ApendJoinLastAfter(item); + } + else if (IsGroupBy(name)) + { + AppendGroupBy(item); + } + else if (IsHaving(name)) + { + AppendHaving(item); + } + else if (IsSelect(name)) + { + jsonQueryParameter.IsSelect = AppendSelect(item); + } + else if (IsPageNumber(name)) + { + jsonQueryParameter.PageIndex = AppendPageNumber(item); + } + else if (IsPageSize(name)) + { + jsonQueryParameter.PageSize = AppendPageSize(item); + } + else if (IsJoin(name)) + { + jsonQueryParameter.IsSelect = AppendJoin(item); + } + } + + private void SetQueryableParameterIndex() + { + ((SqlBuilderProvider)sugarQueryable.SqlBuilder).GetParameterNameIndex = jsonCommonProvider.ParameterIndex; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Property.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Property.cs new file mode 100644 index 000000000..72da01ad3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/Property.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + /// + /// Property + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + int appendIndex = 1000; + List appendTypeNames; + JObject jobject; + ISqlSugarClient context; + ISugarQueryable sugarQueryable; + JsonCommonProvider jsonCommonProvider; + List jsonTableConfigs = new List(); + bool IsDescription = false; + List TableInfos = new List(); + bool IsExecutedBeforeWhereFunc = false; + Action BeforeWhereFunc { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/RegisterAop.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/RegisterAop.cs new file mode 100644 index 000000000..9e585b5d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/RegisterAop.cs @@ -0,0 +1,37 @@ +namespace SqlSugar +{ + /// + /// RegisterAop + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private void RegisterAop() + { + this.BeforeWhereFunc = () => + { + var masterTable = GetMasterTable(); + var masterFilters = this.jsonTableConfigs.Where(it => it.TableName.EqualCase(masterTable.Table)).ToList(); + if (masterFilters.Count != 0) + { + foreach (var filter in masterFilters) + { + var conditions = filter.Conditionals; + conditions = GetConvertConditions(conditions); + var p = this.sugarQueryable.SqlBuilder.ConditionalModelToSql(conditions); + var sql = p.Key; + sugarQueryable.SqlBuilder.RepairReplicationParameters(ref sql, p.Value, appendIndex); + appendIndex++; + sugarQueryable.Where(sql, p.Value); + } + ; + + } + }; + } + + private List GetConvertConditions(List conditions) + { + return conditions; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ResultDefault.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ResultDefault.cs new file mode 100644 index 000000000..52249bacf --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ResultDefault.cs @@ -0,0 +1,45 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + + /// + /// ResultDefault + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + private List ToSqlDefault() + { + List result = new List(); + sugarQueryable = context.Queryable(); + appendTypeNames = GetTypeNames(); + JsonQueryParameter jsonQueryParameter = new JsonQueryParameter(); + RegisterAop(); + foreach (JToken item in appendTypeNames) + { + AppendQueryableAll(jsonQueryParameter, item); + } + return ToPageDefault(result, jsonQueryParameter); + } + + private List GetTypeNames() + { + var result = this.jobject.AsJEnumerable().ToList(); + result.Add(JToken.Parse("{JoinLastAfter:null}").First()); + result = result.OrderBy(it => GetSort(it.Path.ToLower())).ToList(); + return result; + } + + private JsonQueryResult ToResultDefault() + { + JsonQueryResult result = new JsonQueryResult(); + var toSqls = this.ToSqlList(); + var SqlCount = toSqls.FirstOrDefault(it => it.JsonSqlType == JsonProviderType.QueryableCount); + var SqlList = toSqls.FirstOrDefault(it => it.JsonSqlType == JsonProviderType.Queryable); + AddCount(result, SqlCount); + AddList(result, SqlList); + AddDescription(); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ResultHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ResultHelper.cs new file mode 100644 index 000000000..fe3b35955 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Queryable/ResultHelper.cs @@ -0,0 +1,64 @@ +namespace SqlSugar +{ + /// + /// ResultHelper + /// + public partial class JsonQueryableProvider : IJsonQueryableProvider + { + #region SqlHelper + private List ToPageDefault(List result, JsonQueryParameter jsonQueryParameter) + { + if (jsonQueryParameter.IsPage) + { + AddPageSql(result, jsonQueryParameter); + } + else + { + AddDefaultSql(result); + } + Check.ExceptionEasy(jsonQueryParameter.JoinNoSelect, "join query need Select", "联表查询需要设置Select"); + return result; + } + + private void AddDefaultSql(List result) + { + result.Add(new SqlObjectResult(sugarQueryable.Clone().ToSql(), JsonProviderType.Queryable)); + } + + private void AddPageSql(List result, JsonQueryParameter jsonQueryParameter) + { + var skipValue = (jsonQueryParameter.PageIndex.Value - 1) * jsonQueryParameter.PageSize.Value; + var takeValue = jsonQueryParameter.PageSize.Value; + result.Add(new SqlObjectResult(sugarQueryable.Clone().Skip(skipValue).Take(takeValue).ToSql(), JsonProviderType.Queryable)); + var countQueryable = sugarQueryable.Select("COUNT(1)"); + countQueryable.QueryBuilder.OrderByValue = null; + result.Add(new SqlObjectResult(countQueryable.ToSql(), JsonProviderType.QueryableCount)); + } + #endregion + + #region ObjectHeper + private void AddDescription() + { + if (this.IsDescription) + { + } + } + + private void AddList(JsonQueryResult result, SqlObjectResult SqlList) + { + if (SqlList != null) + { + result.Data = this.context.Ado.SqlQuery(SqlList.Sql, SqlList.Parameters); + } + } + + private void AddCount(JsonQueryResult result, SqlObjectResult SqlCount) + { + if (SqlCount != null) + { + result.ToTalRows = this.context.Ado.GetInt(SqlCount.Sql, SqlCount.Parameters); + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendRow.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendRow.cs new file mode 100644 index 000000000..8675f175a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendRow.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + public partial class JsonUpdateableProvider : IJsonUpdateableProvider + { + private void AppendRow(JToken item) + { + var itemFirst = item.First(); + var isObject = itemFirst.Type == JTokenType.Object; + var value = itemFirst.ToString(); + var dics = context.Utilities.JsonToColumnsModels(value); + if (isObject) + sugarUpdateable = this.context.Updateable(dics.First()).AS(this.TableName); + else + { + sugarUpdateable = this.context.Updateable(dics).AS(this.TableName); + isList = dics.Take(2).Any(); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendTable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendTable.cs new file mode 100644 index 000000000..b84bd89b7 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendTable.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class JsonUpdateableProvider : IJsonUpdateableProvider + { + private void AppendTable(JToken item) + { + var tableInfo = jsonCommonProvider.GetTableName(item); + this.TableName = tableInfo.TableName.ToCheckField(); + if (tableInfo.ShortName.HasValue()) + { + this.TableName = tableInfo.ShortName + "." + tableInfo.TableName; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendWhere.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendWhere.cs new file mode 100644 index 000000000..e32627061 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendWhere.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class JsonUpdateableProvider : IJsonUpdateableProvider + { + private void AppendWhere(JToken item) + { + Check.Exception(isList, "Batch updates cannot use Where, only WhereColumns can set columns", "批量更新不能使用Where,只能通过WhereColumns设置列"); + var sqlObj = jsonCommonProvider.GetWhere(item, sugarUpdateable.UpdateBuilder.Context); + sugarUpdateable.Where(sqlObj.Key, sqlObj.Value); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendWhereColumns.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendWhereColumns.cs new file mode 100644 index 000000000..0ee72bd03 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/AppendWhereColumns.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json.Linq; + +namespace SqlSugar +{ + public partial class JsonUpdateableProvider : IJsonUpdateableProvider + { + private void AppendWhereColumns(JToken item) + { + var columns = item.First().ToObject(); + Check.ExceptionEasy(columns.IsNullOrEmpty(), "need WhereColumns", "WhereColumns 需要设置列名"); + this.sugarUpdateable.WhereColumns(columns); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/Helpercs.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/Helpercs.cs new file mode 100644 index 000000000..dc25b13b9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/Helpercs.cs @@ -0,0 +1,26 @@ +namespace SqlSugar +{ + public partial class JsonUpdateableProvider : IJsonUpdateableProvider + { + + private static bool IsColumns(string name) + { + return name.Equals("Columns", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsWhere(string name) + { + return name.Equals("Where", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsWhereColumns(string name) + { + return name.Equals("WhereColumns", StringComparison.CurrentCultureIgnoreCase); + } + + private static bool IsTable(string name) + { + return name.Equals(JsonProviderConfig.KeyUpdateable.Get(), StringComparison.CurrentCultureIgnoreCase); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/JsonUpdateableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/JsonUpdateableProvider.cs new file mode 100644 index 000000000..8e24e0867 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Provider/Updateable/JsonUpdateableProvider.cs @@ -0,0 +1,82 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + public partial class JsonUpdateableProvider : IJsonUpdateableProvider + { + private ISqlSugarClient context; + private JObject jObject; + private JsonCommonProvider jsonCommonProvider; + private string TableName { get; set; } + private bool isList { get; set; } + private IUpdateable> sugarUpdateable; + public JsonUpdateableProvider(ISqlSugarClient context, JObject jObject) + { + this.jObject = jObject; + this.context = context; + this.jsonCommonProvider = new JsonCommonProvider(context); + } + public JsonUpdateResult ToResult() + { + var result = new JsonUpdateResult(); + var sqlInfo = this.ToSqlList(); + var sqlInfoResult = sqlInfo.First(); + result.UpdateRows = this.context.Ado.ExecuteCommand(sqlInfoResult.Sql, sqlInfoResult.Parameters); + return result; + } + public SqlObjectResult ToSql() + { + return this.ToSqlList().First(); + } + public List ToSqlList() + { + List result = new List(); + JsonQueryParameter jsonQueryParameter = new JsonQueryParameter(); + List appendTypeNames = GetAppendTypes(); + foreach (JToken item in appendTypeNames) + { + AppendAll(jsonQueryParameter, item); + } + var addItem = this.sugarUpdateable.ToSql(); + result.Add(new SqlObjectResult(addItem, JsonProviderType.Updateable)); + return result; + } + + private List GetAppendTypes() + { + var appendTypeNames = this.jObject.AsJEnumerable().ToList(); + appendTypeNames = appendTypeNames.OrderBy(it => + { + if (it.Path.EqualCase(JsonProviderConfig.KeyUpdateable.Get())) return 0; + if (it.Path.EqualCase("Columns")) return 1; + else return 3; + + }).ToList(); + return appendTypeNames; + } + + private void AppendAll(JsonQueryParameter jsonQueryParameter, JToken item) + { + var name = item.Path.ToLower(); + if (IsTable(name)) + { + AppendTable(item); + } + else if (IsWhereColumns(name)) + { + AppendWhereColumns(item); + } + else if (IsWhere(name)) + { + AppendWhere(item); + } + else if (IsColumns(name)) + { + AppendRow(item); + } + } + public List ToSqlString() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Queryable/QueryableProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Queryable/QueryableProvider.cs new file mode 100644 index 000000000..b375d060d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Queryable/QueryableProvider.cs @@ -0,0 +1,112 @@ +namespace SqlSugar +{ + + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public ISugarQueryable AddJoinInfo(string tableName, string shortName, IFuncModel models, JoinType type = JoinType.Left) + { + var sqlobj = this.SqlBuilder.FuncModelToSql(models); + this.QueryBuilder.Parameters.AddRange(sqlobj.Value); + return this.AddJoinInfo(tableName, shortName, sqlobj.Key, type); + } + public ISugarQueryable AddJoinInfo(List joinInfoParameters) + { + if (joinInfoParameters != null) + { + foreach (var item in joinInfoParameters) + { + this.AddJoinInfo(item.TableName, item.ShortName, item.Models, item.Type); + } + } + return this; + } + public ISugarQueryable AS(string tableName, string shortName) + { + this.QueryBuilder.TableShortName = shortName; + return this.AS(tableName); + } + public ISugarQueryable OrderBy(List models) + { + if (models == null || models.Count == 0) + { + return this; + } + var orderObj = this.SqlBuilder.OrderByModelToSql(models); + this.OrderBy(orderObj.Key); + this.QueryBuilder.Parameters.AddRange(orderObj.Value); + return this; + } + public ISugarQueryable GroupBy(List models) + { + if (models == null || models.Count == 0) + { + return this; + } + var orderObj = this.SqlBuilder.GroupByModelToSql(models); + if (orderObj.Value?.Length > 0 && this.Context.CurrentConnectionConfig?.DbType == DbType.SqlServer) + { + var groupBySql = UtilMethods.GetSqlString(DbType.SqlServer, orderObj.Key, orderObj.Value); + this.QueryBuilder.GroupBySql = groupBySql; + this.QueryBuilder.GroupBySqlOld = orderObj.Key; + this.QueryBuilder.GroupParameters = orderObj.Value.ToList(); + this.GroupBy(orderObj.Key); + } + else + { + this.GroupBy(orderObj.Key); + this.QueryBuilder.Parameters.AddRange(orderObj.Value); + } + return this; + } + public ISugarQueryable Select(List models) + { + var orderObj = this.SqlBuilder.SelectModelToSql(models); + if (this.QueryBuilder.GroupParameters?.Count > 0 && this.QueryBuilder.GroupBySql.HasValue()) + { + var selectSql = UtilMethods.GetSqlString(DbType.SqlServer, orderObj.Key, UtilMethods.CopySugarParameters(orderObj.Value.ToList()).ToArray()); + if (selectSql.Contains(this.QueryBuilder.GroupBySql)) + { + this.Select(UtilConstants.GroupReplaceKey + selectSql); + return this; + } + } + this.Select(orderObj.Key); + this.QueryBuilder.Parameters.AddRange(orderObj.Value); + return this; + } + + public ISugarQueryable Select(List models) + { + var orderObj = this.SqlBuilder.SelectModelToSql(models); + var result = this.Select(orderObj.Key); + result.QueryBuilder.Parameters.AddRange(orderObj.Value); + return result; + } + + + + public ISugarQueryable Select(List models, AsNameFormatType type) + { + if (type == AsNameFormatType.NoConvert) + { + foreach (var model in models) + { + if (!string.IsNullOrEmpty(model.AsName)) + { + model.AsName = (UtilConstants.ReplaceKey + SqlBuilder.SqlTranslationLeft + model.AsName + SqlBuilder.SqlTranslationRight); + model.AsName.ToCheckField(); + } + } + } + return Select(models); + } + public ISugarQueryable Having(IFuncModel model) + { + this.QueryBuilder.WhereIndex++; + var orderObj = this.SqlBuilder.FuncModelToSql(model); + this.Having(orderObj.Key); + this.QueryBuilder.Parameters.AddRange(orderObj.Value); + return this; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Utils/Json2SqlConfig.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Utils/Json2SqlConfig.cs new file mode 100644 index 000000000..684cbb719 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Utils/Json2SqlConfig.cs @@ -0,0 +1,31 @@ +namespace SqlSugar +{ + public static class JsonProviderConfig + { + public const string KeyInsertable = "Insertable"; + public const string KeyUpdateable = "Updateable"; + public const string KeyQueryable = "Queryable"; + public const string KeyDeleteable = "Deleteable"; + + private static Dictionary words = new Dictionary() + { + { KeyInsertable,"Table"}, + { KeyUpdateable,"Table"}, + { KeyQueryable,"Table"}, + { KeyDeleteable,"Table"} + }; + public static string Rename(string key, string name) + { + return words[key] = name; + } + internal static string Get(this string value) + { + return words[value]; + } + internal static string GetWord(string key) + { + Check.ExceptionEasy(words.ContainsKey(key) == false, $"{key} is error", $"{key} 不存在 "); + return words[key]; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Utils/Json2SqlHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Utils/Json2SqlHelper.cs new file mode 100644 index 000000000..76cc2270b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Json2Sql/Utils/Json2SqlHelper.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json.Linq; + +using System.Text.RegularExpressions; +namespace SqlSugar +{ + internal static class Json2SqlHelper + { + public static bool IsSqlValue(string valueString) + { + return Regex.IsMatch(valueString, @"^\{\w{1,10}\}\:"); + } + public static string GetType(string valueString) + { + return Regex.Match(valueString, @"^\{(\w+)\}\:").Groups[1].Value; + } + public static string GetValue(string valueString) + { + return Regex.Replace(valueString, @"^\{\w{1,10}\}\:", ""); + } + + public static List GetTableNames(string json) + { + List result = new List(); + var mainTable = JObject.Parse(json).AsJEnumerable().Where(it => + it.Path.ToLower().IsIn( + JsonProviderConfig.KeyInsertable.Get().ToLower(), + JsonProviderConfig.KeyUpdateable.Get().ToLower(), + JsonProviderConfig.KeyDeleteable.Get().ToLower(), + JsonProviderConfig.KeyQueryable.Get().ToLower() + )).FirstOrDefault(); + if (mainTable != null) + result.Add(mainTable.First().ToString()); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/JsonClient.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/JsonClient.cs new file mode 100644 index 000000000..524195e4d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/JsonClient.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json.Linq; +namespace SqlSugar +{ + public class JsonClient : IJsonClient + { + public ISqlSugarClient Context { get; set; } + + public IJsonQueryableProvider Queryable(string json) + { + var iJsonToSql = new JsonQueryableProvider(Context, JObject.Parse(json)); + return iJsonToSql; + } + public IJsonProvider Insertable(string json) + { + var iJsonToSql = new JsonInsertableProvider(Context, JObject.Parse(json)); + return iJsonToSql; + } + public IJsonProvider Updateable(string json) + { + var iJsonToSql = new JsonUpdateableProvider(Context, JObject.Parse(json)); + return iJsonToSql; + } + public IJsonProvider Deleteable(string json) + { + var iJsonToSql = new JsonDeleteableProvider(Context, JObject.Parse(json)); + return iJsonToSql; + } + public List GetTableNameList(string json) + { + List result = Json2SqlHelper.GetTableNames(json); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/Compatible.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/Compatible.cs new file mode 100644 index 000000000..0601f8213 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/Compatible.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public static class SugarCompatible + { + public const bool IsFramework = false; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/DataExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/DataExtensions.cs new file mode 100644 index 000000000..738680c48 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/DataExtensions.cs @@ -0,0 +1,1127 @@ +using Dm; + +using Kdbndp; + +using Microsoft.Data.SqlClient; +using Microsoft.Data.Sqlite; + +using MySqlConnector; + +using Npgsql; + +using Oracle.ManagedDataAccess.Client; + +using System.Data; +using System.Data.OscarClient; + +namespace SqlSugar +{ + + /// + /// 数据填充器 + /// + public class SqlDataAdapter : IDataAdapter + { + private SqlCommand command; + private string sql; + private SqlConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public SqlDataAdapter(SqlCommand command) + { + this.command = command; + } + + public SqlDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public SqlDataAdapter(string sql, SqlConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public SqlCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new SqlCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (SqlDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (SqlDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + /// + /// 数据填充器 + /// + public class MySqlDataAdapter : IDataAdapter + { + private MySqlCommand command; + private string sql; + private MySqlConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public MySqlDataAdapter(MySqlCommand command) + { + this.command = command; + } + + public MySqlDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public MySqlDataAdapter(string sql, MySqlConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public MySqlCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new MySqlCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (MySqlDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (MySqlDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (dr.GetFieldType(i).Name == "MySqlDateTime") + { + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, UtilConstants.DateType)); + else + { + columns.Add(new DataColumn(name + i, UtilConstants.DateType)); + } + } + else + { + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + /// + /// 数据填充器 + /// + public class SqliteDataAdapter : IDataAdapter + { + private SqliteCommand command; + private string sql; + private SqliteConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public SqliteDataAdapter(SqliteCommand command) + { + this.command = command; + } + + public SqliteDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public SqliteDataAdapter(string sql, SqliteConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public SqliteCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new SqliteCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (SqliteDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + var type = dr.GetFieldType(i); + if (dr.GetDataTypeName(i).EqualCase("datetime")) + { + type = UtilConstants.DateType; + } + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, type)); + else + { + columns.Add(new DataColumn(name + i, type)); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (SqliteDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + var type = dr.GetFieldType(i); + if (dr.GetDataTypeName(i).EqualCase("datetime")) + { + type = UtilConstants.DateType; + } + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, type)); + else + { + columns.Add(new DataColumn(name + i, type)); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + /// + /// 数据填充器 + /// + public class MyOracleDataAdapter : IDataAdapter + { + private OracleCommand command; + private string sql; + private OracleConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public MyOracleDataAdapter(OracleCommand command) + { + this.command = command; + } + + public MyOracleDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public MyOracleDataAdapter(string sql, OracleConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public OracleCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new OracleCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (OracleDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (OracleDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + /// + /// 数据填充器 + /// + public class NpgsqlDataAdapter : IDataAdapter + { + private NpgsqlCommand command; + private string sql; + private NpgsqlConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public NpgsqlDataAdapter(NpgsqlCommand command) + { + this.command = command; + } + + public NpgsqlDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public NpgsqlDataAdapter(string sql, NpgsqlConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public NpgsqlCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new NpgsqlCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (NpgsqlDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (NpgsqlDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + + /// + /// 数据填充器 + /// + public class MyDmDataAdapter : IDataAdapter + { + private DmCommand command; + private string sql; + private DmConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public MyDmDataAdapter(DmCommand command) + { + this.command = command; + } + + public MyDmDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public MyDmDataAdapter(string sql, DmConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public DmCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new DmCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (var dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (var dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + + /// + /// 数据填充器 + /// + public class KdbndpDataAdapter : IDataAdapter + { + private KdbndpCommand command; + private string sql; + private KdbndpConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public KdbndpDataAdapter(KdbndpCommand command) + { + this.command = command; + } + + public KdbndpDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public KdbndpDataAdapter(string sql, KdbndpConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public KdbndpCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new KdbndpCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (KdbndpDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (KdbndpDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + + /// + /// 数据填充器 + /// + public class OscarDataAdapter : IDataAdapter + { + private OscarCommand command; + private string sql; + private OscarConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public OscarDataAdapter(OscarCommand command) + { + this.command = command; + } + + public OscarDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public OscarDataAdapter(string sql, OscarConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public OscarCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new OscarCommand(this.sql, this._sqlConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (OscarDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (OscarDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + + +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/IDataExtensions.cs.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/IDataExtensions.cs.cs new file mode 100644 index 000000000..676a0ae34 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/IDataExtensions.cs.cs @@ -0,0 +1,48 @@ +using System.Data; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public interface IDataAdapter + { + void Fill(DataSet ds); + } + public partial class SqliteProvider : AdoProvider + { + public override void ExecuteBefore(string sql, SugarParameter[] parameters) + { + this.BeforeTime = DateTime.Now; + if (sql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + if (!sql.Contains(name) && Regex.IsMatch(sql, "(" + name + "$)" + "|(" + name + @"[ ,\,])", RegexOptions.IgnoreCase)) + { + parameter.ParameterName = Regex.Match(sql, "(" + name + "$)" + "|(" + name + @"[ ,\,])", RegexOptions.IgnoreCase).Value.Trim(); + } + } + } + if (this.IsEnableLogEvent) + { + Action action = LogEventStarting; + if (action != null) + { + if (parameters == null || parameters.Length == 0) + { + action(sql, Array.Empty()); + } + else + { + action(sql, parameters); + } + } + } + } + } +} +namespace System.Data.Sqlite +{ + +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/PartialExpressionContexts.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/PartialExpressionContexts.cs new file mode 100644 index 000000000..ef084a3fc --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/OnlyCore/PartialExpressionContexts.cs @@ -0,0 +1,32 @@ +namespace SqlSugar +{ + public partial class PostgreSQLExpressionContext + { + } + public partial class DmExpressionContext + { + } + public partial class OracleExpressionContext + { + } + public partial class SqlServerBlukCopy + { + } + public partial class MySqlBlukCopy + { + internal SqlSugarProvider Context { get; set; } + internal ISqlBuilder Builder { get; set; } + internal T[] Entitys { get; set; } + internal string Chara { get; set; } + + public MySqlBlukCopy(SqlSugarProvider context, ISqlBuilder builder, T[] entitys) + { + this.Context = context; + this.Builder = builder; + this.Entitys = entitys; + } + } + public partial class OracleBlukCopy + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/CodeFirst/DmCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/CodeFirst/DmCodeFirst.cs new file mode 100644 index 000000000..11f3f9996 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/CodeFirst/DmCodeFirst.cs @@ -0,0 +1,105 @@ +namespace SqlSugar +{ + public class DmCodeFirst : CodeFirstProvider + { + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + } + } + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + DecimalDigits = item.DecimalDigits, + Scale = item.DecimalDigits, + CreateTableFieldSort = item.CreateTableFieldSort + }; + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + protected override void GetDbType(EntityColumnInfo item, Type propertyType, DbColumnInfo result) + { + if (!string.IsNullOrEmpty(item.DataType)) + { + result.DataType = item.DataType; + } + else if (item.DataType == null && item.UnderType == UtilConstants.LongType) + { + result.Length = 0; + result.DecimalDigits = 0; + result.DataType = "NUMBER(19,0)"; + } + else if (propertyType.IsEnum()) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(item.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name); + } + else + { + if (propertyType.Name.Equals("Guid", StringComparison.CurrentCultureIgnoreCase)) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(UtilConstants.StringType.Name); + if (result.Length <= 1) + { + result.Length = 36; + } + } + else + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(propertyType.Name); + } + } + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName, null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbBind/DmDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbBind/DmDbBind.cs new file mode 100644 index 000000000..e1af5037e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbBind/DmDbBind.cs @@ -0,0 +1,170 @@ +namespace SqlSugar +{ + public class DmDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "blob"; + if (csharpTypeName.Equals("int32", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "int"; + if (csharpTypeName.Equals("int16", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "short"; + if (csharpTypeName.Equals("int64", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "long"; + if (csharpTypeName.Equals("uint32", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "int"; + if (csharpTypeName.Equals("uint16", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "short"; + if (csharpTypeName.Equals("uint64", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "long"; + if (csharpTypeName.ToLower().IsIn("boolean", "bool")) + csharpTypeName = "bool"; + if (csharpTypeName == "Guid") + csharpTypeName = "string"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)); + return mappings.HasValue() ? mappings.First().Key : "varchar"; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (dbTypeName == "int32") + { + return "int"; + } + else if (dbTypeName == "int64") + { + return "long"; + } + else if (dbTypeName == "int16") + { + return "short"; + } + else if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "sbyte") + { + return "byte"; + } + else if (dbTypeName == "xml" || dbTypeName == "string") + { + return "string"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes?.Any() != true) + { + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>() + { + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("tinyint",CSharpDataType.@short), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("interval year to month",CSharpDataType.@int), + new KeyValuePair("interval day to second",CSharpDataType.TimeSpan), + new KeyValuePair("intervalds",CSharpDataType.TimeSpan), + + new KeyValuePair("number",CSharpDataType.@int), + new KeyValuePair("number",CSharpDataType.@float), + new KeyValuePair("number",CSharpDataType.@short), + new KeyValuePair("number",CSharpDataType.@byte), + new KeyValuePair("number",CSharpDataType.@double), + new KeyValuePair("binaryfloat",CSharpDataType.@float), + new KeyValuePair("binarydouble",CSharpDataType.@double), + new KeyValuePair("number",CSharpDataType.@long), + new KeyValuePair("number",CSharpDataType.@bool), + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("bit",CSharpDataType.@bool), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("number",CSharpDataType.@decimal), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("number",CSharpDataType.Single), + new KeyValuePair("decimal",CSharpDataType.Single), + new KeyValuePair("dec",CSharpDataType.@decimal), + new KeyValuePair("double precision",CSharpDataType.@double), + new KeyValuePair("binary", CSharpDataType.@byteArray), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("nvarchar",CSharpDataType.@string), + new KeyValuePair("varchar",CSharpDataType.@Guid), + new KeyValuePair("varchar2",CSharpDataType.@string), + new KeyValuePair("nvarchar2",CSharpDataType.@string), + new KeyValuePair("longvarchar",CSharpDataType.@string), + + + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("nchar",CSharpDataType.@string), + new KeyValuePair("clob",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("long",CSharpDataType.@string), + new KeyValuePair("nclob",CSharpDataType.@string), + new KeyValuePair("rowid",CSharpDataType.@string), + + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + + new KeyValuePair("timestamp with local time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + + + + new KeyValuePair("timestamp with local time zone",CSharpDataType.DateTimeOffset), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTimeOffset), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTimeOffset), + + new KeyValuePair("time",CSharpDataType.TimeSpan), + + new KeyValuePair("float",CSharpDataType.@decimal), + new KeyValuePair("real",CSharpDataType.@float), + + new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("image",CSharpDataType.byteArray), + new KeyValuePair("long raw",CSharpDataType.byteArray), + new KeyValuePair("raw",CSharpDataType.byteArray), + new KeyValuePair("bfile",CSharpDataType.byteArray), + new KeyValuePair("varbinary",CSharpDataType.byteArray) }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbFirst/DmDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbFirst/DmDbFirst.cs new file mode 100644 index 000000000..c77989205 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbFirst/DmDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class DmDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbMaintenance/DmDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbMaintenance/DmDbMaintenance.cs new file mode 100644 index 000000000..8071b5e91 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DbMaintenance/DmDbMaintenance.cs @@ -0,0 +1,669 @@ +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class DmDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string GetTableInfoListSql + { + get + { + return @"SELECT a.TABLE_NAME AS Name,b.COMMENTS AS Description +FROM USER_TABLES a +LEFT JOIN (SELECT DISTINCT TABLE_NAME,COMMENTS FROM USER_TAB_COMMENTS WHERE COMMENTS IS NOT NULL) b ON a.TABLE_NAME=b.TABLE_NAME +WHERE +a.table_name!='HELP' +AND a.table_name NOT LIKE '%$%' +AND a.table_name NOT LIKE 'LOGMNRC_%' +AND a.table_name!='LOGMNRP_CTAS_PART_MAP' +AND a.table_name!='LOGMNR_LOGMNR_BUILDLOG' +AND a.table_name!='SQLPLUS_PRODUCT_PROFILE'"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select VIEW_NAME name from all_views WHERE OWNER=SF_GET_SCHEMA_NAME_BY_ID(CURRENT_SCHID) order by VIEW_NAME"; + } + } + #endregion + + #region DDL + protected override string IsAnyIndexSql + { + get + { + return "select count(1) from USER_INDEXES where upper(index_name)=upper('{0}') and table_owner=SF_GET_SCHEMA_NAME_BY_ID(CURRENT_SCHID)"; + } + } + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0}({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} MODIFY({1} DEFAULT '{2}')"; + } + } + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD ({1} {2}{3} {4} {5} {6})"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "ALTER TABLE {0} modify ({1} {2}{3} {4} {5} {6}) "; + } + } + protected override string BackupDataBaseSql + { + get + { + return @"USE master;BACKUP DATABASE {0} TO disk = '{1}'"; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1} )"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {1} as select * from {2} where ROWNUM<={0}"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} rename column {1} to {2}"; + } + } + protected override string AddColumnRemarkSql + { + get + { + return "comment on column {1}.{0} is '{2}'"; + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + return "comment on column {1}.{0} is ''"; + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + return "select * from user_col_comments where Table_Name='{1}' AND COLUMN_NAME='{0}' order by column_name"; + } + } + + protected override string AddTableRemarkSql + { + get + { + return "comment on table {0} is '{1}'"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "comment on table {0} is ''"; + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + return "select * from user_tab_comments where Table_Name='{0}'order by Table_Name"; + } + } + + protected override string RenameTableSql + { + get + { + return "alter table {0} rename to {1}"; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select t.table_name from user_tables t where rownum=1"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return " null "; + } + } + protected override string CreateTableNotNull + { + get + { + return " not null "; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "IDENTITY(1,1)"; + } + } + #endregion + + #region Methods + public override bool UpdateColumn(string tableName, DbColumnInfo column) + { + ConvertCreateColumnInfo(column); + var oldColumn = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName, false) + .FirstOrDefault(it => it.DbColumnName.EqualCase(column.DbColumnName)); + if (oldColumn != null) + { + if (oldColumn.IsNullable == column.IsNullable) + { + var sql = GetUpdateColumnSqlOnlyType(tableName, column); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + } + return base.UpdateColumn(tableName, column); + } + protected virtual string GetUpdateColumnSqlOnlyType(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + public override List GetDbTypes() + { + var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT DATA_TYPE +FROM DBA_TAB_COLUMNS +WHERE OWNER = user "); + result.Add("TIMESTAMP"); + result.Add("NCLOB"); + return result.Distinct().ToList(); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT trigger_name +FROM all_triggers +WHERE table_name = '" + tableName + "'"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery(" SELECT object_name\r\nFROM all_objects\r\nWHERE object_type = 'FUNCTION' AND owner = USER "); + } + public override bool RenameTable(string oldTableName, string newTableName) + { + oldTableName = SqlBuilder.GetTranslationColumnName(oldTableName); + newTableName = SqlBuilder.GetTranslationColumnName(newTableName); + return base.RenameTable(oldTableName, newTableName); + } + public override List GetIndexList(string tableName) + { + var sql = $"SELECT index_name FROM user_ind_columns\r\nWHERE upper(table_name) = upper('{tableName}')"; + return this.Context.Ado.SqlQuery(sql); + } + public override bool AddColumn(string tableName, DbColumnInfo columnInfo) + { + if (columnInfo.DataType == "varchar" && columnInfo.Length == 0) + { + columnInfo.DataType = "varchar2"; + columnInfo.Length = 50; + } + ConvertCreateColumnInfo(columnInfo); + return base.AddColumn(tableName, columnInfo); + } + public override bool CreateIndex(string tableName, string[] columnNames, bool isUnique = false) + { + string sql = string.Format(CreateIndexSql, tableName, string.Join(",", columnNames), string.Join("_", columnNames.Select(it => (it + "abc").Substring(0, 3))), isUnique ? "UNIQUE" : ""); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + columnName = SqlBuilder.GetTranslationColumnName(columnName); + tableName = SqlBuilder.GetTranslationColumnName(tableName); + if (defaultValue == "''") + { + defaultValue = ""; + } + if (defaultValue.ToLower().IsIn("sysdate")) + { + var template = AddDefaultValueSql.Replace("'", ""); + string sql = string.Format(template, tableName, columnName, defaultValue); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + else + { + return base.AddDefaultValue(tableName, columnName, defaultValue); + } + } + public override bool CreateDatabase(string databaseDirectory = null) + { + if (this.Context.Ado.IsValidConnection()) + { + return true; + } + Check.ExceptionEasy("dm no support create database ", "达梦不支持建库方法,请写有效连接字符串可以正常运行该方法。"); + return true; + } + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + if (this.Context.Ado.IsValidConnection()) + { + return true; + } + Check.ExceptionEasy("dm no support create database ", "达梦不支持建库方法,请写有效连接字符串可以正常运行该方法。"); + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + //column remak + if (db.DbMaintenance.IsAnyColumnRemark(item.DbColumnName.ToUpper(IsUppper), item.DbTableName.ToUpper(IsUppper))) + { + db.DbMaintenance.DeleteColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), this.SqlBuilder.GetTranslationColumnName(item.DbTableName)); + db.DbMaintenance.AddColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), this.SqlBuilder.GetTranslationColumnName(item.DbTableName), item.ColumnDescription); + } + else + { + db.DbMaintenance.AddColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), this.SqlBuilder.GetTranslationColumnName(item.DbTableName), item.ColumnDescription); + } + } + } + + //table remak + if (entity.TableDescription != null) + { + if (db.DbMaintenance.IsAnyTableRemark(entity.DbTableName)) + { + db.DbMaintenance.DeleteTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName)); + db.DbMaintenance.AddTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName), entity.TableDescription); + } + else + { + db.DbMaintenance.AddTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName), entity.TableDescription); + } + } + return true; + } + + public override bool AddTableRemark(string tableName, string description) + { + return base.AddTableRemark(SqlBuilder.GetTranslationColumnName(tableName), description); + } + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + return base.AddColumnRemark(SqlBuilder.GetTranslationColumnName(columnName), SqlBuilder.GetTranslationColumnName(tableName), description); + } + 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) + { + List columns = GetOracleDbType(tableName); + string sql = "select * from " + SqlBuilder.GetTranslationTableName(tableName) + " WHERE 1=2 "; + if (!this.GetTableInfoList(false).Any(it => it.Name == SqlBuilder.GetTranslationTableName(tableName).TrimStart('\"').TrimEnd('\"'))) + { + sql = "select * from \"" + tableName + "\" WHERE 1=2 "; + } + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + using (DbDataReader reader = (DbDataReader)this.Context.Ado.GetDataReader(sql)) + { + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + List result = new List(); + var schemaTable = reader.GetSchemaTable(); + 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["IsIdentity"], + ColumnDescription = GetFieldComment(tableName, row["ColumnName"].ToString()), + DbColumnName = row["ColumnName"].ToString(), + //DefaultValue = row["defaultValue"].ToString(), + IsPrimarykey = GetPrimaryKeyByTableNames(tableName).Any(it => it.Equals(row["ColumnName"].ToString(), StringComparison.CurrentCultureIgnoreCase)), + Length = row["ColumnSize"].ObjToInt(), + Scale = row["numericscale"].ObjToInt() + }; + if (column.DataType.EqualCase("number") || column.DataType.EqualCase("decimal")) + { + column.Length = row["numericprecision"].ObjToInt(); + column.Scale = row["numericscale"].ObjToInt(); + column.DecimalDigits = row["numericscale"].ObjToInt(); + if (column.Length == 38 && column.Scale == 0) + { + column.Length = 22; + } + } + var current = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(column.DbColumnName)); + if (current != null) + { + column.OracleDataType = current.DataType; + column.DefaultValue = current.DefaultValue?.TrimStart('\'')?.TrimEnd('\''); + } + result.Add(column); + } + return result; + } + } + + private List GetOracleDbType(string tableName) + { + var sql0 = $@"select + t1.table_name as TableName, + t6.comments, + t1.column_id, + t1.column_name as DbColumnName, + t5.comments, + t1.data_type as DataType, + t1.data_length as Length, + t1.char_length, + t1.data_precision, + t1.data_scale, + t1.nullable, + t1.data_default as DefaultValue, + t4.index_name, + t4.column_position, + t4.descend + from user_tab_columns t1 + left join (select t2.table_name, + t2.column_name, + t2.column_position, + t2.descend, + t3.index_name + from user_ind_columns t2 + left join user_indexes t3 + on t2.table_name = t3.table_name and t2.index_name = t3.index_name + and t3.status = 'valid' and t3.uniqueness = 'unique') t4 --unique:唯一索引 + on t1.table_name = t4.table_name and t1.column_name = t4.column_name + left join user_col_comments t5 on t1.table_name = t5.table_name and t1.column_name = t5.column_name + left join user_tab_comments t6 on t1.table_name = t6.table_name + where upper(t1.table_name)=upper('{tableName}') + order by t1.table_name, t1.column_id"; + + var columns = this.Context.Ado.SqlQuery(sql0); + return columns; + } + + private List GetPrimaryKeyByTableNames(string tableName) + { + string cacheKey = "DbMaintenanceProvider.GetPrimaryKeyByTableNames." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower(); + cacheKey = GetCacheKey(cacheKey); + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + string sql = @" select distinct cu.COLUMN_name KEYNAME from user_cons_columns cu, user_constraints au + where cu.constraint_name = au.constraint_name + and au.constraint_type = 'P' and au.table_name = '" + tableName.ToUpper(IsUppper) + @"'"; + var pks = this.Context.Ado.SqlQuery(sql); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return pks; + }); + } + + public string GetTableComment(string tableName) + { + string cacheKey = "DbMaintenanceProvider.GetTableComment." + tableName; + var comments = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + string sql = "SELECT COMMENTS FROM USER_TAB_COMMENTS WHERE TABLE_NAME =@tableName ORDER BY TABLE_NAME"; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var pks = this.Context.Ado.SqlQuery(sql, new { tableName = tableName.ToUpper(IsUppper) }); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return pks; + }); + return comments.HasValue() ? comments.First() : ""; + } + + public string GetFieldComment(string tableName, string filedName) + { + string cacheKey = "DbMaintenanceProvider.GetFieldComment." + tableName; + var comments = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + string sql = "SELECT TVNAME AS TableName, COLNAME as DbColumnName ,COMMENT$ AS ColumnDescription from SYSCOLUMNCOMMENTS WHERE TVNAME='" + tableName.ToUpper(IsUppper) + "' ORDER BY TVNAME"; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var pks = this.Context.Ado.SqlQuery(sql); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return pks; + }); + if (comments.HasValue()) + { + var comment = comments.FirstOrDefault(it => it.DbColumnName.Equals(filedName, StringComparison.CurrentCultureIgnoreCase)); + return comment?.ColumnDescription; + } + else + { + return ""; + } + + } + + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + ConvertCreateColumnInfo(item); + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + item.Length = 10; + } + } + } + string sql = GetCreateTableSql(tableName, columns); + //string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + sql = sql.TrimEnd(')') + string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToUpper(IsUppper))))); + sql = sql + ")"; + } + //sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public static string ExtractSchema(string connectionString) + { + string pattern = @"(?i)(?:^|;)schema=(\w+)"; + Match match = Regex.Match(connectionString?.Replace(" ", ""), pattern, RegexOptions.IgnoreCase); + return match.Success ? match.Groups[1].Value : null; + } + public override bool IsAnyTable(string tableName, bool isCache = true) + { + var isSchema = this.Context.CurrentConnectionConfig?.ConnectionString?.Replace(" ", "")?.ToLower()?.Contains("schema=") == true; + if (isSchema) + { + var schema = ExtractSchema(this.Context.CurrentConnectionConfig?.ConnectionString); + Check.ExceptionEasy(schema == null, "ConnectionString schema format error, please use schema=(\\w+)", "连接字符串schema格式错误,请用schema=(\\w+)"); + return this.Context.Ado.GetInt($@"SELECT COUNT(*) +FROM ALL_TABLES t +WHERE upper(t.TABLE_NAME) = upper('{tableName}') + AND upper(t.OWNER) = upper('{schema}') +") > 0; + + } + else + { + return base.IsAnyTable(tableName, isCache); + } + } + #endregion + + #region Helper + public bool IsUppper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + private static void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "int", "date", "clob", "nclob" }; + if (x.OracleDataType.HasValue()) + { + x.DataType = x.OracleDataType; + } + if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + if (x.DecimalDigits > 0 && x.DataType?.ToLower()?.IsIn("varchar", "clob", "varchar2", "nvarchar2", "nvarchar") == true) + { + x.DecimalDigits = 0; + } + } + #endregion + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DmProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DmProvider.cs new file mode 100644 index 000000000..4efea575e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/DmProvider.cs @@ -0,0 +1,246 @@ +using Dm; + +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; + + +namespace SqlSugar +{ + public partial class DmProvider : AdoProvider + { + public DmProvider() + { + //this.FormatSql = sql => + //{ + // sql = sql.Replace("+@", "+:"); + // if (sql.HasValue() && sql.Contains('@')) + // { + // var exceptionalCaseInfo = Regex.Matches(sql, @"\'[^\=]*?\@.*?\'|[\.,\w]+\@[\.,\w]+ | [\.,\w]+\@[\.,\w]+|[\.,\w]+\@[\.,\w]+ |\d+\@\d|\@\@"); + // if (exceptionalCaseInfo != null) + // { + // foreach (var item in exceptionalCaseInfo.Cast()) + // { + // if (item.Value != null && item.Value.IndexOf(",") == 1 && Regex.IsMatch(item.Value, @"^ \,\@\w+$")) + // { + // continue; + // } + // else if (item.Value != null && Regex.IsMatch(item.Value.Trim(), @"^\w+\,\@\w+\,$")) + // { + // continue; + // } + // else if (item.Value != null && item.Value.ObjToString().Contains("||") && Regex.IsMatch(item.Value.Replace(" ", "").Trim(), @"\|\|@\w+\|\|")) + // { + // continue; + // } + // else if (item.Value != null && Regex.IsMatch(item.Value.Replace(" ", "").Trim(), @"\(\@\w+\,")) + // { + // continue; + // } + // else if (item.Value != null && item.Value.Contains("=") && Regex.IsMatch(item.Value, @"\w+ \@\w+[ ]{0,1}\=[ ]{0,1}\'")) + // { + // continue; + // } + // sql = sql.Replace(item.Value, item.Value.Replace("@", UtilConstants.ReplaceKey)); + // } + // } + // sql = sql.Replace("@", ":"); + // sql = sql.Replace(UtilConstants.ReplaceKey, "@"); + // } + // return sql; + //}; + } + public override string SqlParameterKeyWord + { + get + { + return ":"; + } + } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var npgsqlConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + base._DbConnection = new DmConnection(npgsqlConnectionString); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new MyDmDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + sql = ReplaceKeyWordParameterName(sql, parameters); + DmCommand sqlCommand = new DmCommand(sql, (DmConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (DmTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((DmParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((MyDmDataAdapter)dataAdapter).SelectCommand = (DmCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + DmParameter[] result = new DmParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new DmParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + if (sqlParameter.ParameterName[0] == '@') + { + sqlParameter.ParameterName = string.Concat(":", sqlParameter.ParameterName.AsSpan(1, sqlParameter.ParameterName.Length - 1)); + } + if (sqlParameter.DbType == System.Data.DbType.Guid) + { + sqlParameter.DbType = System.Data.DbType.String; + if (sqlParameter.Value != DBNull.Value) + sqlParameter.Value = sqlParameter.Value.ToString(); + } + if (parameter.IsClob) + { + sqlParameter.DmSqlType = DmDbType.Clob; + sqlParameter.Value = parameter.Value; + } + if (parameter.IsNClob) + { + sqlParameter.DmSqlType = DmDbType.Clob; + sqlParameter.Value = parameter.Value; + } + 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)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + if (parameter.IsRefCursor) + { + sqlParameter.DmSqlType = DmDbType.Cursor; + } + if (IsSpOutPutParameter(sqlParameter)) + { + sqlParameter.ParameterName = sqlParameter.ParameterName.Replace("@", ":"); + } + ++index; + } + return result; + } + + private bool IsSpOutPutParameter(DmParameter sqlParameter) + { + return sqlParameter.Direction == ParameterDirection.Output && this.CommandType == CommandType.StoredProcedure; + } + + private static string[] KeyWord = new string[] { "@month", ":month", ":day", "@day", "@group", ":group", ":index", "@index", "@order", ":order", "@user", "@level", ":user", ":level", ":type", "@type", ":year", "@year" }; + private static string ReplaceKeyWordParameterName(string sql, SugarParameter[] parameters) + { + sql = ReplaceKeyWordWithAd(sql, parameters); + if (parameters.HasValue() && parameters.Any(it => it.ParameterName.ToLower().IsIn(KeyWord))) + { + int i = 0; + foreach (var Parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + if (Parameter.ParameterName?.ToLower().IsContainsIn(KeyWord) == true) + { + var newName = ":p" + i + 100; + sql = Regex.Replace(sql, Parameter.ParameterName, newName, RegexOptions.IgnoreCase); + Parameter.ParameterName = newName; + i++; + } + } + } + return sql; + } + + private static string ReplaceKeyWordWithAd(string sql, SugarParameter[] parameters) + { + if (parameters != null && sql?.Contains('@') == true) + { + foreach (var item in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + if (item.ParameterName.StartsWith('@')) + { + item.ParameterName = ":" + item.ParameterName.TrimStart('@'); + } + sql = Regex.Replace(sql, "@" + item.ParameterName.TrimStart(':'), item.ParameterName, RegexOptions.IgnoreCase); + } + } + + return sql; + } + public override Action ErrorEvent => it => + { + if (base.ErrorEvent != null) + { + base.ErrorEvent(it); + } + if (it.Message?.Contains("Detail redacted as it may contain sensitive data.") == true) + { + Check.ExceptionEasy(it.Message, $"错误:可能是字段太小超出,详细错误:{it.Message} "); + } + }; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/Insertable/DmInserttable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/Insertable/DmInserttable.cs new file mode 100644 index 000000000..8ece02f42 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/Insertable/DmInserttable.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class DmInserttable : InsertableProvider where T : class, new() + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/Queryable/DmQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/Queryable/DmQueryable.cs new file mode 100644 index 000000000..bde4467a2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/Queryable/DmQueryable.cs @@ -0,0 +1,63 @@ +namespace SqlSugar +{ + public class DmQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + //public override ISugarQueryable PartitionBy(string groupFileds) + //{ + // this.GroupBy(groupFileds); + // return this; + //} + } + public class DmQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } + public class DmQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmBlukCopy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmBlukCopy.cs new file mode 100644 index 000000000..e1d0120d2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmBlukCopy.cs @@ -0,0 +1,150 @@ +using Dm; + +using System.Data; +namespace SqlSugar +{ + public class DmBlukCopy + { + 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(); + DmBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString; + try + { + bulkCopy.WriteToServer(dt); + } + catch (Exception) + { + CloseDb(); + throw; + } + 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(); + DmBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString; + try + { + bulkCopy.WriteToServer(dt); + await Task.Delay(0).ConfigureAwait(false); + } + catch (Exception) + { + CloseDb(); + throw; + } + 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); + DmBulkCopy 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 DmBulkCopy GetBulkCopyInstance() + { + DmBulkCopy copy; + if (this.Context.Ado.Transaction == null) + { + copy = new DmBulkCopy((DmConnection)this.Context.Ado.Connection); + } + else + { + copy = new DmBulkCopy((DmConnection)this.Context.Ado.Connection, DmBulkCopyOptions.Default, (DmTransaction)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/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmBuilder.cs new file mode 100644 index 000000000..aefc9bb28 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmBuilder.cs @@ -0,0 +1,61 @@ +namespace SqlSugar +{ + public class DmBuilder : SqlBuilderProvider + { + public override string SqlParameterKeyWord + { + get + { + return ":"; + } + } + public override string SqlDateNow + { + get + { + return "sysdate"; + } + } + public override string FullSqlDateNow + { + get + { + return "select sysdate from dual"; + } + } + public override string SqlTranslationLeft { get { return "\""; } } + public override string SqlTranslationRight { get { return "\""; } } + public override string GetTranslationTableName(string name) + { + var result = base.GetTranslationTableName(name); + if (result.Contains('(') && result.Contains(')')) + return result; + else + return result.ToUpper(IsUppper); + } + public override string GetTranslationColumnName(string entityName, string propertyName) + { + var result = base.GetTranslationColumnName(entityName, propertyName); + return result.ToUpper(IsUppper); + } + public override string GetTranslationColumnName(string propertyName) + { + var result = base.GetTranslationColumnName(propertyName); + return result.ToUpper(IsUppper); + } + public bool IsUppper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmDeleteBuilder.cs new file mode 100644 index 000000000..0ade3766a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class DmDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmExpressionContext.cs new file mode 100644 index 000000000..e6e5777d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmExpressionContext.cs @@ -0,0 +1,338 @@ +namespace SqlSugar +{ + public partial class DmExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public DmExpressionContext() + { + base.DbMehtods = new DmMethod(); + } + public override string SqlParameterKeyWord + { + get + { + return ":"; + } + } + public override string SqlTranslationLeft { get { return "\""; } } + public override string SqlTranslationRight { get { return "\""; } } + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + return base.GetTranslationTableName(entityName, isMapping).ToUpper(IsUppper); + } + public override string GetTranslationColumnName(string columnName) + { + return base.GetTranslationColumnName(columnName).ToUpper(IsUppper); + } + public override string GetDbColumnName(string entityName, string propertyName) + { + return base.GetDbColumnName(entityName, propertyName).ToUpper(IsUppper); + } + public bool IsUppper + { + get + { + if (this.SugarContext?.Context?.Context?.CurrentConnectionConfig?.MoreSettings == null) + { + return true; + } + else + { + return this.SugarContext?.Context?.Context?.CurrentConnectionConfig?.MoreSettings.IsAutoToUpper == true; + } + } + } + } + public partial class DmMethod : DefaultDbMethod, IDbMethods + { + + public override string WeekOfYear(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $"TO_NUMBER(TO_CHAR({parameterNameA}, 'WW')) "; + } + public override string ParameterKeyWord { get; set; } = ":"; + public string ForXmlPathLast; + public override string GetForXmlPath() + { + if (string.IsNullOrEmpty(ForXmlPathLast)) return null; + return " GROUP BY " + ForXmlPathLast; + } + public override string GetStringJoinSelector(string result, string separator) + { + if (result.ObjToString().Trim().StartsWith("DISTINCT ", StringComparison.OrdinalIgnoreCase)) + { + int index = result.IndexOf(result, StringComparison.Ordinal); // 找到去掉前缀空格后的位置 + result = result.Substring(index + 9); // 9 是 "DISTINCT " 的长度 + ForXmlPathLast = result; + return $"listagg(to_char(max({result})),'{separator}') within group(order by max({result})) "; + } + else + { + return $"listagg(to_char({result}),'{separator}') within group(order by {result}) "; + } + } + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS Number)", parameter.MemberName); + } + + public override string ToTime(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" to_timestamp({0},'0000-01-01 hh24:mi:ss') ", parameter.MemberName); + } + public override string Substring(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format("SUBSTR({0},1 + {1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + 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 string.Format("(CAST(TO_CHAR({0},'yyyy') AS NUMBER))", parameter.MemberName); + case DateType.Month: + return string.Format("(CAST(TO_CHAR({0},'mm') AS NUMBER))", parameter.MemberName); + case DateType.Hour: + return string.Format("(CAST(TO_CHAR({0},'hh24') AS NUMBER))", parameter.MemberName); + case DateType.Second: + return string.Format("(CAST(TO_CHAR({0},'ss') AS NUMBER))", parameter.MemberName); + case DateType.Minute: + return string.Format("(CAST(TO_CHAR({0},'mi') AS NUMBER))", parameter.MemberName); + case DateType.Millisecond: + return string.Format("(CAST(TO_CHAR({0},'ff3') AS NUMBER))", parameter.MemberName); + case DateType.Quarter: + return string.Format("(CAST(TO_CHAR({0},'q') AS NUMBER))", parameter.MemberName); + case DateType.Weekday: + return $" (TO_NUMBER(TO_CHAR({parameter.MemberName}, 'D'))-1) "; + case DateType.Day: + default: + return string.Format("(CAST(TO_CHAR({0},'dd') AS NUMBER))", parameter.MemberName); + } + } + //public override string DateAddByType(MethodCallExpressionModel model) + //{ + // var parameter = model.Args[0]; + // var parameter2 = model.Args[1]; + // var parameter3 = model.Args[2]; + // var type = (DateType)Enum.Parse(typeof(DateType), parameter3.MemberValue.ObjToString(), false); + // double time = 1; + // switch (type) + // { + // case DateType.Year: + // time = 1 * 365; + // break; + // case DateType.Month: + // time = 1 * 30; + // break; + // case DateType.Day: + // break; + // case DateType.Hour: + // time = 1 / 24.0; + // break; + // case DateType.Second: + // time = 1 / 24.0 / 60.0 / 60.0; + // break; + // case DateType.Minute: + // time = 1 / 24.0 / 60.0; + // break; + // case DateType.Millisecond: + // time = 1 / 24.0 / 60.0 / 60.0 / 1000; + // break; + // } + // return string.Format("({0}+({1}*{2})) ", parameter.MemberName, time, parameter2.MemberName); + //} + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format("({0}+(1*{1})) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR2(4000))", parameter.MemberName); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" to_date({0},'yyyy-mm-dd hh24:mi:ss')", parameter.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 Trim(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" trim({0}) ", parameter.MemberName); + } + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( cast({0} as date)= cast( {1} as date) ) ", parameter.MemberName, parameter2.MemberName); ; + } + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + + var dateType = parameter3.MemberValue.ObjToString().ToLower(); + var date1 = parameter.MemberName; + var date2 = parameter2.MemberName; + + if (dateType == "year") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}))", date1, date2); + } + else if (dateType == "month") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}) AND EXTRACT(MONTH FROM {0}) = EXTRACT(MONTH FROM {1}))", date1, date2); + } + else if (dateType == "day") + { + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } + else if (dateType == "hour") + { + return string.Format("(TRUNC({0}, 'HH24') = TRUNC({1}, 'HH24'))", date1, date2); + } + else if (dateType == "minute") + { + return string.Format("(TRUNC({0}, 'MI') = TRUNC({1}, 'MI'))", date1, date2); + } + else if (dateType == "second") + { + return string.Format("(TRUNC({0}, 'SS') = TRUNC({1}, 'SS'))", date1, date2); + } + else if (dateType == "week" || dateType == "weekday") + { + return string.Format("(TRUNC({0}, 'IW') = TRUNC({1}, 'IW'))", date1, date2); + } + else + { + // 默认按天比较 + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } + } + public override string Length(MethodCallExpressionModel model) + { + 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) + { + return string.Join("||", strings); + } + + public override string GetDate() + { + return "sysdate"; + } + + public override string GetRandom() + { + return "dbms_random.value"; + } + + 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 ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS decimal(18,4))", parameter.MemberName); + } + + public override string TrimEnd(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" RTRIM({parameterNameA}, {parameterNameB}) "; + } + public override string TrimStart(MethodCallExpressionModel mode) + { + + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" LTRIM({parameterNameA}, {parameterNameB}) "; + } + + public override string Left(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" SUBSTR({parameterNameA}, 1, {parameterNameB}) "; + } + public override string Right(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" SUBSTR({parameterNameA}, -2, {parameterNameB}) "; + } + + public override string Ceil(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" CEIL({parameterNameA}) "; + } + + public override string NewUid(MethodCallExpressionModel mode) + { + return " SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 1, 8) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 9, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 13, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 17, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 21) "; + } + public override string JsonField(MethodCallExpressionModel model) + { + return $"JSON_VALUE({model.Args[0].MemberName}, '$.{model.Args[1].MemberValue.ToString().ToSqlFilter()}')"; + //"JSON_VALUE(j.kingorder, '$.Id') = '1'"; + } + + public override string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = "(" + string.Join(",", mode.Args[0].MemberValue as List) + ")"; + } + var searchWord = mode.Args[1].MemberName; + return $" CONTAINS({columns}, {searchWord}, 1) "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmFastBuilder.cs new file mode 100644 index 000000000..d7f4c54eb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmFastBuilder.cs @@ -0,0 +1,98 @@ +using Dm; + +using System.Data; + +namespace SqlSugar +{ + + public class DmFastBuilder : FastBuilder, IFastBuilder + { + public override bool IsActionUpdateColumns { get; set; } = true; + public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() + { + HasOffsetTime = true, + IsConvertDateTimeOffsetToDateTime = true + }; + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + dt = UtilMethods.ConvertDateTimeOffsetToDateTime(dt); + if (DbFastestProperties?.IsOffIdentity == true) + { + var isNoTran = this.Context.Ado.IsNoTran() && this.Context.CurrentConnectionConfig.IsAutoCloseConnection; + try + { + if (isNoTran) + this.Context.Ado.BeginTran(); + + this.Context.Ado.ExecuteCommand($"SET IDENTITY_INSERT {dt.TableName} ON"); + var result = await _Execute(dt).ConfigureAwait(false); + this.Context.Ado.ExecuteCommand($"SET IDENTITY_INSERT {dt.TableName} OFF"); + + if (isNoTran) + this.Context.Ado.CommitTran(); + + return result; + } + catch (Exception) + { + if (isNoTran) + this.Context.Ado.CommitTran(); + throw; + } + } + else + { + return await _Execute(dt).ConfigureAwait(false); + } + } + public override async Task CreateTempAsync(DataTable dt) + { + var queryable = this.Context.Queryable(); + var tableName = queryable.SqlBuilder.GetTranslationTableName(dt.TableName); + var sqlBuilder = this.Context.Queryable().SqlBuilder; + var dts = dt.Columns.Cast().Select(it => sqlBuilder.GetTranslationColumnName(it.ColumnName)).ToList(); + dt.TableName = "temp" + SnowFlakeSingle.instance.getID(); + var sql = queryable.AS(tableName).Where(it => false).Select(string.Join(",", dts)).ToSql().Key; + await Context.Ado.ExecuteCommandAsync($"CREATE TABLE {dt.TableName} as ( {sql} ) ").ConfigureAwait(false); + } + public override string UpdateSql { get; set; } = @"UPDATE {1} TM INNER JOIN {2} TE ON {3} SET {0} "; + + private async Task _Execute(DataTable dt) + { + DmBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = dt.TableName; + try + { + bulkCopy.WriteToServer(dt); + await Task.Delay(0).ConfigureAwait(false);//No Support Async + } + catch (Exception) + { + CloseDb(); + throw; + } + CloseDb(); + return dt.Rows.Count; + } + + public DmBulkCopy GetBulkCopyInstance() + { + DmBulkCopy copy; + if (this.Context.Ado.Transaction == null) + { + copy = new DmBulkCopy((DmConnection)this.Context.Ado.Connection); + } + else + { + copy = new DmBulkCopy((DmConnection)this.Context.Ado.Connection, DmBulkCopyOptions.Default, (DmTransaction)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/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmInsertBuilder.cs new file mode 100644 index 000000000..a137216ac --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmInsertBuilder.cs @@ -0,0 +1,139 @@ +namespace SqlSugar +{ + public class DmInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;select @@identity"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public override string SqlTemplateBatchUnion + { + get + { + return "\t\r\nUNION ALL "; + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + + public override string SqlTemplateBatchSelect => " {0} "; + public override string FormatDateTimeOffset(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff zzz") + "'"; + } + public override string ToSqlString() + { + var result = base.ToSqlString(); + if (!this.EntityInfo.Columns.Any(it => it.IsIdentity) && this.IsReturnIdentity == false) + { + result = result.Replace(";select @@identity", ""); + } + if (this.IsOffIdentity) + { + var tableName = this.GetTableNameString; + result = $"SET IDENTITY_INSERT {tableName} ON;" + result.TrimEnd(';') + $";SET IDENTITY_INSERT {tableName} OFF"; + result = result.Replace(";\r\n;", ";"); + } + return result; + } + + public override object FormatValue(object value) + { + if (value != null && value is DateTime) + { + 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 "to_date('" + date.ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; + } + else + { + return "to_timestamp('" + date.ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + } + } + else + { + return base.FormatValue(value); + } + } + + //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 => Builder.SqlParameterKeyWord + it.DbColumnName)); + // return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + // } + // else + // { + // StringBuilder batchInsetrSql = new StringBuilder(); + // int pageSize = 200; + // int pageIndex = 1; + // int totalRecord = groupList.Count; + // int pageCount = (totalRecord + pageSize - 1) / pageSize; + // while (pageCount >= pageIndex) + // { + // batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + // 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 ( " + string.Join(",", columns.Select(it => + // { + // object value = null; + // if (it.Value is DateTime) + // { + // value = ((DateTime)it.Value).ToString("O"); + // } + // else + // { + // value = it.Value; + // } + // if (value == null||value==DBNull.Value) + // { + // return string.Format(SqlTemplateBatchSelect, "NULL"); + // } + // return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToString().ToSqlFilter() + "'"); + // })) + "),"); + // ++i; + // } + // pageIndex++; + // batchInsetrSql.Remove(batchInsetrSql.Length - 1,1).Append("\r\n;\r\n"); + // } + // return batchInsetrSql.ToString(); + // } + //} + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmQueryBuilder.cs new file mode 100644 index 000000000..f3af297a9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmQueryBuilder.cs @@ -0,0 +1,193 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class DmQueryBuilder : QueryBuilder + { + public override bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS ""\w+\.\w+""") || Regex.IsMatch(sql, @"AS ""\w+\.\w+\.\w+"""); + } + public override string SqlTemplate + { + get + { + return "SELECT {0}{" + UtilConstants.ReplaceKey + "} FROM {1}{2}{3}{4}"; + } + } + public override string ToSqlString() + { + + if (PartitionByValue.HasValue()) + { + return base.ToSqlString(); + } + //Support MySql Model + if (this.Context.CurrentConnectionConfig.MoreSettings?.DatabaseModel == DbType.MySql) + { + return MySqlToSqlString(); + } + var isDistinctPage = IsDistinct && (Take > 1 || Skip > 1); + if (isDistinctPage) + { + return OffsetPage(); + } + + string oldOrderBy = this.OrderByValue; + string externalOrderBy = oldOrderBy; + var isIgnoreOrderBy = this.IsCount && this.PartitionByValue.IsNullOrEmpty(); + AppendFilter(); + sql = new StringBuilder(); + if (this.OrderByValue == null && (Skip != null || Take != null)) this.OrderByValue = " ORDER BY " + this.Builder.SqlDateNow + " "; + if (this.PartitionByValue.HasValue()) + { + this.OrderByValue = this.PartitionByValue + this.OrderByValue; + } + var isRowNumber = Skip != null || Take != null; + var rowNumberString = string.Format(",ROW_NUMBER() OVER({0}) AS RowIndex ", GetOrderByString); + string groupByValue = GetGroupByString + HavingInfos; + string orderByValue = (!isRowNumber && this.OrderByValue.HasValue()) ? GetOrderByString : null; + if (isIgnoreOrderBy) { orderByValue = null; } + sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, groupByValue, orderByValue); + sql.Replace(UtilConstants.ReplaceKey, isRowNumber ? (isIgnoreOrderBy ? null : rowNumberString) : null); + if (isIgnoreOrderBy) { this.OrderByValue = oldOrderBy; return sql.ToString(); } + var result = ToPageSql(sql.ToString(), this.Take, this.Skip); + if (ExternalPageIndex > 0) + { + if (externalOrderBy.IsNullOrEmpty()) + { + externalOrderBy = " ORDER BY " + this.Builder.SqlDateNow + " "; + } + result = string.Format("SELECT *,ROW_NUMBER() OVER({0}) AS RowIndex2 FROM ({1}) ExternalTable ", GetExternalOrderBy(externalOrderBy), result); + result = ToPageSql2(result, ExternalPageIndex, ExternalPageSize, true); + } + this.OrderByValue = oldOrderBy; + result = GetSqlQuerySql(result); + if (result.Contains("-- No table")) + { + return "select * from (select 1 as id) where id=0 -- No table"; + } + return result; + } + + public string MySqlToSqlString() + { + var PageTempalte = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {5},{6}"; + var SqlTemplate = MySqlTemplate; + base.AppendFilter(); + string result = null; + string oldOrderBy = this.OrderByValue; + sql = new StringBuilder(); + sql.AppendFormat(SqlTemplate, GetMySelectValue, 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 += GetMySelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetMySelectValue, 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 += GetMySelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetMySelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt()); + } + else if (Skip != null && Take != null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetMySelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetMySelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take); + } + else + { + result = sql.ToString(); + } + this.OrderByValue = oldOrderBy; + result = GetSqlQuerySql(result); + result = result.Replace(UtilConstants.ReplaceCommaKey, ""); + if (result.IndexOf("-- No table") > 0) + { + return "-- No table"; + } + return result; + } + public string GetMySelectValue + { + get + { + string reval = string.Empty; + if (this.SelectValue == null || this.SelectValue is string) + { + reval = GetSelectValueByString(); + } + else + { + reval = GetSelectValueByExpression(); + } + if (this.SelectType == ResolveExpressType.SelectMultiple) + { + this.SelectCacheKey = this.SelectCacheKey + string.Join("-", this.JoinQueryInfos.Select(it => it.TableName)); + } + if (IsDistinct) + { + reval = " DISTINCT " + reval; + } + if (this.SubToListParameters != null && this.SubToListParameters.Count != 0) + { + reval = SubToListMethod(reval); + } + return reval; + } + } + public string MySqlTemplate + { + get + { + if (this.SampleBy.HasValue()) + { + return "SELECT {0} FROM {1}{2} " + this.SampleBy + " {3}{4}"; + } + return "SELECT {0} FROM {1}{2}{3}{4} "; + } + } + public override string GetExternalOrderBy(string externalOrderBy) + { + return Regex.Replace(externalOrderBy, @"""\w+""\.", ""); + } + + private string OffsetPage() + { + var skip = this.Skip ?? 1; + var take = this.Take; + this.Skip = null; + this.Take = null; + this.Offset = null; + var pageSql = $"SELECT * FROM ( SELECT PAGETABLE1.*,ROWNUM PAGEINDEX FROM( {this.ToSqlString()}) PAGETABLE1 WHERE ROWNUM<={skip + take}) WHERE PAGEINDEX>={(skip == 0 ? skip : (skip + 1))}"; + return pageSql; + } + public override string ToPageSql(string sql, int? take, int? skip, bool isExternal = false) + { + string temp = isExternal ? ExternalPageTempalte : PageTempalte; + if (skip != null && take == null) + { + return string.Format(temp, sql.ToString(), skip.ObjToInt() + 1, long.MaxValue); + } + else if (skip == null && take != null) + { + return string.Format(temp, sql.ToString(), 1, take.ObjToInt()); + } + else if (skip != null && take != null) + { + return string.Format(temp, sql.ToString(), skip.ObjToInt() + 1, skip.ObjToInt() + take.ObjToInt()); + } + else + { + return sql.ToString(); + } + } + + public override string ToPageSql2(string sql, int? pageIndex, int? pageSize, bool isExternal = false) + { + string temp = isExternal ? ExternalPageTempalte : PageTempalte; + return string.Format(temp, sql.ToString(), (pageIndex - 1) * pageSize + 1, pageIndex * pageSize); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmUpdateBuilder.cs new file mode 100644 index 000000000..b93447307 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Dm/SqlBuilder/DmUpdateBuilder.cs @@ -0,0 +1,135 @@ +using System.Text; + +namespace SqlSugar +{ + public class DmUpdateBuilder : UpdateBuilder + { + public override string ReSetValueBySqlExpListType { get; set; } = "dm"; + protected override string GetJoinUpdate(string columnsString, ref string whereString) + { + var joinString = $" {Builder.GetTranslationColumnName(this.TableName)} {Builder.GetTranslationColumnName(this.ShortName)} "; + foreach (var item in this.JoinInfos) + { + joinString += $"\r\n USING {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} ON {item.JoinWhere} "; + } + var tableName = joinString + "\r\n "; + var newTemp = SqlTemplate.Replace("UPDATE", "MERGE INTO").Replace("SET", "WHEN MATCHED THEN \r\nUPDATE SET"); + return string.Format(newTemp, tableName, columnsString, whereString); + } + protected override string TomultipleSqlString(List> groupList) + { + StringBuilder sb = new StringBuilder(); + int i = 0; + sb.AppendLine(string.Join("\r\n", groupList.Select(t => + { + var updateTable = string.Format("UPDATE {0} SET", base.GetTableNameStringNoWith); + var setValues = string.Join(",", t.Where(s => !s.IsPrimarykey).Where(s => OldPrimaryKeys?.Contains(s.DbColumnName) != true).Select(m => GetOracleUpdateColums(i, m)).ToArray()); + var pkList = t.Where(s => s.IsPrimarykey).ToList(); + if (this.IsWhereColumns && this.PrimaryKeys?.Count > 0) + { + var whereColumns = pkList.Where(it => this.PrimaryKeys?.Any(p => p.EqualCase(it.PropertyName) || p.EqualCase(it.DbColumnName)) == true).ToList(); + if (whereColumns.Count != 0) + { + pkList = whereColumns; + } + } + List whereList = new List(); + foreach (var item in pkList) + { + var isFirst = pkList.First() == item; + var whereString = ""; + whereString += GetOracleUpdateColums(i, item); + whereList.Add(whereString); + } + i++; + return string.Format("{0} {1} WHERE {2};", updateTable, setValues, string.Join("AND", whereList)); + }).ToArray())); + var result = sb.ToString(); + if (groupList.Count == 0) + { + return null; + } + return result; + } + + private string GetOracleUpdateColums(int i, DbColumnInfo m) + { + return string.Format("\"{0}\"={1} ", m.DbColumnName.ToUpper(IsUppper), base.GetDbColumn(m, FormatValue(i, m.DbColumnName, m.Value))); + } + public bool IsUppper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + public override string FormatDateTimeOffset(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff zzz") + "'"; + } + public object FormatValue(int i, string name, object value) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + 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 "to_date('" + date.ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; + } + else + { + return "to_timestamp('" + date.ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + } + } + 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 (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/CodeFirst/KdbndpCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/CodeFirst/KdbndpCodeFirst.cs new file mode 100644 index 000000000..1c368907b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/CodeFirst/KdbndpCodeFirst.cs @@ -0,0 +1,91 @@ +namespace SqlSugar +{ + public class KdbndpCodeFirst : CodeFirstProvider + { + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + } + } + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + CreateTableFieldSort = item.CreateTableFieldSort, + DecimalDigits = item.DecimalDigits, + Scale = item.DecimalDigits + }; + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + if (result.DataType.EqualCase("timestamp") && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) + { + result.DataType = "datetime"; + } + if (IsSqlServerModel()) + { + if (result.DataType.EqualCase("int4")) + { + result.DataType = "int"; + } + if (result.DataType.EqualCase("int8")) + { + result.DataType = "bigint"; + } + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName, null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + private bool IsSqlServerModel() + { + return this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbBind/KdbndpBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbBind/KdbndpBind.cs new file mode 100644 index 000000000..fb7d46f9e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbBind/KdbndpBind.cs @@ -0,0 +1,162 @@ +namespace SqlSugar +{ + public class KdbndpDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "bytea"; + + var result = base.GetDbTypeName(csharpTypeName); + return result; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.Replace("pg_catalog.", ""); + dbTypeName = dbTypeName.Replace("sys.", ""); + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json") + { + return "string"; + } + else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + { + return "char"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes?.Any() != true) + { + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("int2",CSharpDataType.@short), + new KeyValuePair("uint2",CSharpDataType.@short), + //new KeyValuePair("int1",CSharpDataType.@byte), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("smallint",CSharpDataType.@byte), + new KeyValuePair("tinyint",CSharpDataType.@byte), + new KeyValuePair("int4",CSharpDataType.@int), + new KeyValuePair("uint4",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("tinyint",CSharpDataType.@int), + new KeyValuePair("int8",CSharpDataType.@long), + new KeyValuePair("uint8",CSharpDataType.@long), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("float4",CSharpDataType.@float), + new KeyValuePair("float4",CSharpDataType.Single), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("float8",CSharpDataType.@double), + new KeyValuePair("double precision",CSharpDataType.@int), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("path",CSharpDataType.@decimal), + new KeyValuePair("point",CSharpDataType.@decimal), + new KeyValuePair("polygon",CSharpDataType.@decimal), + + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("bool",CSharpDataType.@bool), + new KeyValuePair("box",CSharpDataType.@bool), + new KeyValuePair("bytea",CSharpDataType.@bool), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("character varying",CSharpDataType.@string), + new KeyValuePair("name",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("nchar",CSharpDataType.@string), + new KeyValuePair("character",CSharpDataType.@string), + new KeyValuePair("cidr",CSharpDataType.@string), + new KeyValuePair("circle",CSharpDataType.@string), + new KeyValuePair("tsquery",CSharpDataType.@string), + new KeyValuePair("tsvector",CSharpDataType.@string), + new KeyValuePair("txid_snapshot",CSharpDataType.@string), + new KeyValuePair("varcharbyte",CSharpDataType.@string), + new KeyValuePair("varcharbyte varying",CSharpDataType.@string), + new KeyValuePair("bpcharbyte",CSharpDataType.@string), + new KeyValuePair("nvarchar",CSharpDataType.@string), + new KeyValuePair("characterbyte",CSharpDataType.@string), + new KeyValuePair("information_schema.character_data",CSharpDataType.@string), + new KeyValuePair("uuid",CSharpDataType.Guid), + new KeyValuePair("uniqueidentifier",CSharpDataType.Guid), + new KeyValuePair("xml",CSharpDataType.@string), + new KeyValuePair("json",CSharpDataType.@string), + new KeyValuePair("rowid",CSharpDataType.@string), + new KeyValuePair("information_schema.sql_identifier",CSharpDataType.@string), + new KeyValuePair("information_schema.cardinal_number",CSharpDataType.@string), + new KeyValuePair("interval",CSharpDataType.@decimal), + new KeyValuePair("lseg",CSharpDataType.@decimal), + new KeyValuePair("macaddr",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("datetime2",CSharpDataType.DateTime), + new KeyValuePair("datetime",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamptz",CSharpDataType.DateTime), + new KeyValuePair("timestamp without time zone",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("time with time zone",CSharpDataType.DateTime), + new KeyValuePair("timetz",CSharpDataType.DateTime), + new KeyValuePair("time without time zone",CSharpDataType.DateTime), + + new KeyValuePair("bit",CSharpDataType.byteArray), + new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("bit varying",CSharpDataType.byteArray), + new KeyValuePair("binary",CSharpDataType.byteArray), + new KeyValuePair("varbinary",CSharpDataType.byteArray), + new KeyValuePair("image",CSharpDataType.byteArray), + new KeyValuePair("varbit",CSharpDataType.@byte), + new KeyValuePair("rowversion",CSharpDataType.byteArray), + new KeyValuePair("regclass",CSharpDataType.@object), + + new KeyValuePair("geometry",CSharpDataType.@object), + new KeyValuePair("public.geometry",CSharpDataType.@object), + new KeyValuePair("geography",CSharpDataType.@object), + new KeyValuePair("public.geography",CSharpDataType.@object), + + new KeyValuePair("dsinterval",CSharpDataType.TimeSpan), + new KeyValuePair("yminterval",CSharpDataType.@int), + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbFirst/KdbndpDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbFirst/KdbndpDbFirst.cs new file mode 100644 index 000000000..36cd4351b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbFirst/KdbndpDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class KdbndpDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbMaintenance/KdbndpDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbMaintenance/KdbndpDbMaintenance.cs new file mode 100644 index 000000000..bc3d8f8c0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/DbMaintenance/KdbndpDbMaintenance.cs @@ -0,0 +1,712 @@ +namespace SqlSugar +{ + public class KdbndpDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + if (IsPgModel()) + { + return "SELECT datname FROM pg_database"; + } + return "SELECT datname FROM sys_database"; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string sql = $@"select cast (pclass.oid as int4) as TableId,cast(ptables.tablename as varchar) as TableName, + pcolumn.column_name as DbColumnName,pcolumn.udt_name as DataType, + pcolumn.character_maximum_length as Length, + pcolumn.column_default as DefaultValue, + col_description(pclass.oid, pcolumn.ordinal_position) as ColumnDescription, + case when pkey.colname = pcolumn.column_name + then true else false end as IsPrimaryKey, + case when UPPER(pcolumn.column_default) like 'NEXTVAL%' + then true else false end as IsIdentity, + case when UPPER(pcolumn.is_nullable) = 'YES' + then true else false end as IsNullable + from (select * from sys_tables where UPPER(tablename) = UPPER('{{0}}') and lower(schemaname)='{GetSchema()}') ptables inner join sys_class pclass + on ptables.tablename = pclass.relname inner join (SELECT * + FROM information_schema.columns where UPPER(table_schema)=UPPER('{GetSchema()}') + ) pcolumn on pcolumn.table_name = ptables.tablename + left join ( + select sys_class.relname,sys_attribute.attname as colname from + sys_constraint inner join sys_class + on sys_constraint.conrelid = sys_class.oid + inner join sys_attribute on sys_attribute.attrelid = sys_class.oid + and sys_attribute.attnum = sys_constraint.conkey[1] + inner join sys_type on sys_type.oid = sys_attribute.atttypid + where sys_constraint.contype='p' + ) pkey on pcolumn.table_name = pkey.relname + order by ptables.tablename"; + + + if (IsPgModel()) + { + sql = sql.Replace("sys_", "pg_"); + } + else if (IsSqlServerModel()) + { + + sql = sql.Replace("sys_", "pg_"); + sql = sql.Replace("pg_constraint.conkey[1]", "pg_constraint.conkey{{1}}"); + sql = sql.Replace("UPPER(", "pg_catalog.upper("); + sql = sql.Replace("lower(", "pg_catalog.lower("); + sql = sql.Replace("NEXTVAL%", "%nextval%"); + sql = sql.Replace("pcolumn.udt_name", "pcolumn.data_type"); + sql = sql.Replace("case when pkey.colname = pcolumn.column_name", "case when pkey.colname::text = pcolumn.column_name::text"); + sql = sql.Replace("pcolumn on pcolumn.table_name = ptables.tablename", "pcolumn on pcolumn.table_name::text = ptables.tablename::text "); + sql = sql.Replace("pkey on pcolumn.table_name = pkey.relname", "pkey on pcolumn.table_name::text = pkey.relname::text "); + } + else if (IsMySql()) + { + sql = sql.Replace("pcolumn.udt_name", "pcolumn.data_type"); + } + return sql; + } + } + protected override string GetTableInfoListSql + { + get + { + if (IsPgModel()) + { + return @"select cast(relname as varchar) as Name, + cast(obj_description(relfilenode,'pg_class') as varchar) as Description from pg_class c + where relkind = 'r' and c.oid >= 16384 and c.relnamespace != 99 and c.relname not like '%pl_profiler_saved%' order by relname"; + } + var result = @"select cast(relname as varchar) as Name, + cast(obj_description(relfilenode,'pg_class') as varchar) as Description from sys_class c + where relkind = 'r' and c.oid >= 16384 and c.relnamespace != 99 and c.relname not like '%pl_profiler_saved%' order by relname"; + + if (IsSqlServerModel()) + { + result = result.Replace(" as varchar)", " as varchar(max))"); + } + return result; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select table_name as name from information_schema.views where lower(table_schema) ='" + GetSchema() + "' "; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + if (IsSqlServerModel()) + { + return "ALTER TABLE {0} ADD {1} {2}{3} {4} {5} {6}"; + } + return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "alter table {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return "mysqldump.exe {0} -uroot -p > {1} "; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {0} as (select * from {1} limit {2} offset 0)"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} RENAME {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 { throw new NotSupportedException(); } } + + protected override string AddTableRemarkSql => "comment on table {0} is '{1}'"; + + protected override string DeleteTableRemarkSql => "comment on table {0} is ''"; + + protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } } + + protected override string RenameTableSql => "alter table {0} rename to {1}"; + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + if (IsSqlServerModel()) + { + return "ALTER TABLE {0} ALTER {1} SET DEFAULT {2}"; + } + return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}"; + } + } + protected override string IsAnyIndexSql + { + get + { + var sql = "SELECT count(1) WHERE upper('{0}') IN ( SELECT upper(indexname) FROM sys_indexes ) "; + if (IsPgModel()) + { + sql = sql.Replace("sys_", "pg_"); + } + return sql; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select 1 from information_schema.columns limit 1 offset 0"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "DEFAULT NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "serial"; + } + } + #endregion + + #region Methods + public override List GetDbTypes() + { + var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT data_type +FROM information_schema.columns"); + result.Add("varchar"); + result.Add("timestamp"); + result.Add("uuid"); + result.Add("int2"); + result.Add("int4"); + result.Add("int8"); + result.Add("time"); + result.Add("date"); + result.Add("float8"); + result.Add("float4"); + result.Add("json"); + result.Add("jsonp"); + return result.Distinct().ToList(); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT tgname +FROM pg_trigger +WHERE tgrelid = '" + tableName + "'::regclass"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery(" SELECT routine_name\r\nFROM information_schema.routines\r\nWHERE lower( routine_schema ) = '" + GetSchema().ToLower() + "' AND routine_type = 'FUNCTION' "); + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue?.StartsWith('\'') == true && defaultValue?.EndsWith('\'') == true && defaultValue?.Contains('(') == false + && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue.EqualCase("current_timestamp") || defaultValue.EqualCase("current_date")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.Contains('(') == false + && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), "'" + defaultValue + "'"); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else + { + return base.AddDefaultValue(this.SqlBuilder.GetTranslationTableName(tableName), this.SqlBuilder.GetTranslationTableName(columnName), defaultValue); + } + } + public override List GetIndexList(string tableName) + { + var sql = $"SELECT indexname FROM sys_indexes WHERE UPPER(tablename) = UPPER('{tableName}') AND UPPER(schemaname) = UPPER('" + GetSchema() + "') "; + if (IsPgModel()) + { + sql = sql.Replace("sys_", "pg_"); + } + return this.Context.Ado.SqlQuery(sql); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT proname FROM sys_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE UPPER(n.nspname) = UPPER('{dbName}')"; + if (IsPgModel()) + { + sql = sql.Replace("sys_", "pg_"); + } + return this.Context.Ado.SqlQuery(sql); + } + private string GetSchema() + { + var schema = "public"; + if (IsSqlServerModel()) + { + schema = "dbo"; + } + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + + return schema.ToLower(); + } + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + if (IsSqlServerModel()) + { + if (columnInfo.DataType.EqualCase("uuid")) + { + columnInfo.DataType = "uniqueidentifier"; + columnInfo.Length = 0; + columnInfo.Scale = 0; + } + } + + ConvertCreateColumnInfo(columnInfo); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + string type = GetType(tableName, columnInfo); + //this.Context.Ado.ExecuteCommand(sql); + + string sql = @"ALTER TABLE {table} ALTER {column} TYPE {type};ALTER TABLE {table} ALTER COLUMN {column} {null}"; + + var isnull = columnInfo.IsNullable ? " DROP NOT NULL " : " SET NOT NULL "; + + sql = sql.Replace("{table}", tableName) + .Replace("{type}", type) + .Replace("{column}", columnName) + .Replace("{null}", isnull); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + protected string GetType(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + //if (!string.IsNullOrEmpty(dataType)) + //{ + // dataType = dataType; + //} + return dataType + "" + dataSize; + } + //public override bool IsAnyColumn(string tableName, string columnName, bool isCache = true) + //{ + // var sql = + // $"select count(*) from information_schema.columns WHERE table_schema = '{GetSchema()}' and UPPER(table_name) = '{tableName.ToUpper(IsUpper)}' and UPPER(column_name) = '{columnName.ToUpper(IsUpper)}'"; + // return this.Context.Ado.GetInt(sql) > 0; + //} + + public override bool IsAnyTable(string tableName, bool isCache = true) + { + var sql = $"select count(*) from information_schema.tables where UPPER(table_schema)=UPPER('{GetSchema()}') and UPPER(table_type)=UPPER('BASE TABLE') and UPPER(table_name)=UPPER('{tableName.ToUpper(IsUpper)}')"; + if (IsSqlServerModel()) + { + sql = $"select count(*) from information_schema.tables where UPPER(table_schema)=UPPER('{GetSchema()}') and pg_catalog.UPPER(table_name)=pg_catalog.UPPER('{tableName.ToUpper(IsUpper)}')"; + } + return this.Context.Ado.GetInt(sql) > 0; + } + + /// + ///by current connection string + /// + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + if (this.Context.Ado.IsValidConnection()) + { + return true; + } + if (databaseDirectory != null) + { + if (!FileHelper.IsExistDirectory(databaseDirectory)) + { + FileHelper.CreateDirectory(databaseDirectory); + } + } + var oldDatabaseName = this.Context.Ado.Connection.Database; + var connection = this.Context.CurrentConnectionConfig.ConnectionString; + if (IsSqlServerModel()) + { + connection = connection.Replace(oldDatabaseName, "master"); + } + else + { + connection = connection.Replace(oldDatabaseName, "test"); + } + var newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = connection + }); + if (newDb.Ado.IsValidConnection() == false) + { + newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = this.Context.CurrentConnectionConfig.ConnectionString.Replace(oldDatabaseName, "TEST") + }); + } + if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) + { + newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft + databaseName + this.SqlBuilder.SqlTranslationRight, databaseDirectory)); + } + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + db.DbMaintenance.AddColumnRemark(SqlBuilder.GetTranslationColumnName(item.DbColumnName).ToUpper(IsUpper), SqlBuilder.GetTranslationColumnName(item.DbTableName).ToUpper(IsUpper), item.ColumnDescription); + + } + } + //table remak + if (entity.TableDescription != null) + { + db.DbMaintenance.AddTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName), entity.TableDescription); + } + return true; + } + public override bool AddColumn(string tableName, DbColumnInfo columnInfo) + { + if (IsSqlServerModel()) + { + if (columnInfo.DataType.EqualCase("uuid")) + { + columnInfo.DataType = "uniqueidentifier"; + columnInfo.Length = 0; + columnInfo.Scale = 0; + } + } + return base.AddColumn(tableName, columnInfo); + } + public override bool RenameTable(string oldTableName, string newTableName) + { + return base.RenameTable(this.SqlBuilder.GetTranslationTableName(oldTableName), this.SqlBuilder.GetTranslationTableName(newTableName)); + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + + ConvertCreateColumnInfo(item); + //if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + //{ + // if (item.DataType?.ToLower() != "uuid") + // { + // item.Length = 10; + // } + //} + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToUpper(IsUpper))))); + + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + 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 = item.DbColumnName; + string dataType = item.DataType; + if (dataType == "varchar" && item.Length == 0) + { + item.Length = 1; + } + //if (dataType == "uuid") + //{ + // item.Length = 50; + // dataType = "varchar"; + //} + string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + if (item.DecimalDigits > 0 && item.Length > 0 && dataType == "numeric") + { + dataSize = $"({item.Length},{item.DecimalDigits})"; + } + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToUpper(IsUpper)), dataType, dataSize, nullType, primaryKey, ""); + if (item.IsIdentity) + { + if (dataType?.ToLower() == "int") + { + dataSize = "int4"; + } + else if (dataType?.ToLower() == "long") + { + dataSize = "int8"; + } + string length = dataType.Substring(dataType.Length - 1); + string identityDataType = "serial" + length; + addItem = addItem.Replace(dataType, identityDataType); + } + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName.ToUpper(IsUpper)), string.Join(",\r\n", columnArray)); + return tableString; + } + protected override bool IsAnyDefaultValue(string tableName, string columnName, List columns) + { + var defaultValue = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)).First().DefaultValue; + if (defaultValue?.StartsWith("NULL::") == true) + { + return false; + } + return defaultValue.HasValue(); + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported"); + return false; + } + + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + var result = base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); + if (result == null || result.Count == 0) + { + result = base.GetColumnInfosByTableName(tableName, isCache); + } + try + { + string sql = $@"select + kcu.column_name as key_column + from information_schema.table_constraints tco + join information_schema.key_column_usage kcu + on kcu.constraint_name = tco.constraint_name + and kcu.constraint_schema = tco.constraint_schema + and kcu.constraint_name = tco.constraint_name + where tco.constraint_type = 'PRIMARY KEY' + and kcu.table_schema='{GetSchema()}' and + upper(kcu.table_name)=upper('{tableName.TrimEnd('"').TrimStart('"')}')"; + List pkList = new List(); + if (isCache) + { + pkList = GetListOrCache("GetColumnInfosByTableName_N_Pk" + tableName, sql); + } + else + { + pkList = this.Context.Ado.SqlQuery(sql); + } + if (pkList.Count > 1) + { + foreach (var item in result) + { + if (pkList.Select(it => it.ToUpper()).Contains(item.DbColumnName.ToUpper())) + { + item.IsPrimarykey = true; + } + } + } + } + catch + { + + } + return result; + } + public bool IsUpper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + private void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "int4", "text", "int2", "int8", "date", "bit", "text", "timestamp" }; + + if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + + if (IsSqlServerModel()) + { + if (x.DataType.EqualCase("int8")) + { + x.DataType = "bigint"; + x.Length = 0; + x.Scale = 0; + } + } + } + private bool IsPgModel() + { + return this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.PostgreSQL; + } + private bool IsSqlServerModel() + { + return this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; + } + private bool IsMySql() + { + return this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.MySql; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/Insertable/KdbndpInserttable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/Insertable/KdbndpInserttable.cs new file mode 100644 index 000000000..b8cf9fae9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/Insertable/KdbndpInserttable.cs @@ -0,0 +1,99 @@ +namespace SqlSugar +{ + public class KdbndpInserttable : InsertableProvider where T : class, new() + { + public override int ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault() ?? "")); + RestoreMapping(); + sql = GetSql(sql); + AutoRemoveDataCache(); + var result = Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ObjToInt(); + return result; + } + + + public override async Task ExecuteReturnIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault() ?? "")); + RestoreMapping(); + sql = GetSql(sql); + AutoRemoveDataCache(); + var obj = await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + var result = obj.ObjToInt(); + return result; + } + public override KeyValuePair> ToSql() + { + var result = base.ToSql(); + if (GetPrimaryKeys()?.Count > 0) + { + return new KeyValuePair>(result.Key.Replace("$PrimaryKey", GetPrimaryKeys().FirstOrDefault()), result.Value); + } + else + { + return new KeyValuePair>(result.Key.Replace(" returning $PrimaryKey", ""), result.Value); + } + } + + public override long ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault() ?? "")); + RestoreMapping(); + sql = GetSql(sql); + AutoRemoveDataCache(); + var result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0"); + return result; + } + public override async Task ExecuteReturnBigIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault() ?? "")); + RestoreMapping(); + sql = GetSql(sql); + AutoRemoveDataCache(); + var result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false) ?? "0"); + return result; + } + + public override bool ExecuteCommandIdentityIntoEntity() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (identityKeys.Count == 0) { return this.ExecuteCommand() > 0; } + var idValue = ExecuteReturnBigIdentity(); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else + setValue = Convert.ToInt32(idValue); + var propertyName = this.Context.EntityMaintenance.GetPropertyName(identityKey); + typeof(T).GetProperties().First(t => t.Name.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)).SetValue(result, setValue, null); + return idValue > 0; + } + + private string GetSql(string sql) + { + if (GetIdentityKeys().FirstOrDefault() == null) + { + sql = sql.Replace("returning \"\"", ""); + var id = this.Context.DbMaintenance.GetIsIdentities(this.Context.EntityMaintenance.GetTableName(this.InsertBuilder.GetTableNameString)).FirstOrDefault(); + if (id != null) + { + sql = sql.TrimEnd().TrimEnd(';') + " returning " + this.SqlBuilder.GetTranslationColumnName(id); + } + } + + return sql; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/KdbndpSQLProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/KdbndpSQLProvider.cs new file mode 100644 index 000000000..ae4f04dc1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/KdbndpSQLProvider.cs @@ -0,0 +1,196 @@ +using Kdbndp; + +using KdbndpTypes; + +using System.Data; +using System.Data.Common; + +namespace SqlSugar +{ + public partial class KdbndpProvider : AdoProvider + { + public KdbndpProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var npgsqlConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + base._DbConnection = new KdbndpConnection(npgsqlConnectionString); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + public override void CheckConnection() + { + try + { + base.CheckConnection(); + } + catch (Exception ex) + { + if (ex.Message.Contains("Version string portion was too short or too long")) + { + Check.Exception(true, "人大金仓R6请安装 Nuget:SqlSugarCore.Kdbndp到最新版本"); + } + throw; + } + } + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new KdbndpDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + KdbndpCommand sqlCommand = new KdbndpCommand(sql, (KdbndpConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (sqlCommand.CommandType == CommandType.StoredProcedure) + { + sqlCommand.DbModeType = DbMode.Oracle; + } + if (this.Transaction != null) + { + sqlCommand.Transaction = (KdbndpTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((KdbndpParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((KdbndpDataAdapter)dataAdapter).SelectCommand = (KdbndpCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + KdbndpParameter[] result = new KdbndpParameter[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new KdbndpParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + if (parameter.IsJson) + { + sqlParameter.KdbndpDbType = KdbndpDbType.Json; + } + if (parameter.IsArray) + { + // sqlParameter.Value = this.Context.Utilities.SerializeObject(sqlParameter.Value); + var type = sqlParameter.Value.GetType(); + if (ArrayMapping.TryGetValue(type, out KdbndpDbType value)) + { + sqlParameter.KdbndpDbType = value | KdbndpDbType.Array; + } + else + { + Check.Exception(true, sqlParameter.Value.GetType().Name + " No Support"); + } + } + if (sqlParameter.Direction == 0) + { + sqlParameter.Direction = ParameterDirection.Input; + } + if (parameter.IsRefCursor) + { + sqlParameter.KdbndpDbType = KdbndpDbType.Refcursor; + sqlParameter.Direction = ParameterDirection.Output; + } + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + //人大金仓MYSQL模式下json字段类型处理 + if (sqlParameter.KdbndpDbType == KdbndpDbType.Json && this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.MySql) + { + sqlParameter.KdbndpDbType = KdbndpDbType.Varchar; + } + if (parameter.CustomDbType != null && parameter.CustomDbType is KdbndpDbType) + { + sqlParameter.KdbndpDbType = ((KdbndpDbType)parameter.CustomDbType); + } + ++index; + } + return result; + } + public override Action ErrorEvent => it => + { + if (base.ErrorEvent != null) + { + base.ErrorEvent(it); + } + if (it.Message?.StartsWith("42883: function uuid_generate_v4() does not exist") == true) + { + Check.ExceptionEasy(it.Message, $"使用uuid_generate_v4()函数需要创建 CREATE EXTENSION IF NOT EXISTS kbcrypto;CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\" "); + } + }; + + static readonly Dictionary ArrayMapping = new Dictionary() + { + { typeof(int[]),KdbndpDbType.Integer}, + { typeof(short[]),KdbndpDbType.Smallint}, + { typeof(long[]),KdbndpDbType.Bigint}, + { typeof(decimal[]),KdbndpDbType.Numeric}, + { typeof(char[]),KdbndpDbType.Text}, + { typeof(byte[]),KdbndpDbType.Bytea}, + { typeof(bool[]),KdbndpDbType.Boolean}, + {typeof(DateTime[]),KdbndpDbType.Date}, + + + { typeof(int?[]),KdbndpDbType.Integer}, + { typeof(short?[]),KdbndpDbType.Smallint}, + { typeof(long?[]),KdbndpDbType.Bigint}, + { typeof(decimal?[]),KdbndpDbType.Numeric}, + { typeof(char?[]),KdbndpDbType.Text}, + { typeof(byte?[]),KdbndpDbType.Bytea}, + { typeof(bool?[]),KdbndpDbType.Boolean}, + {typeof(DateTime?[]),KdbndpDbType.Date}, + + + { typeof(string[]), KdbndpDbType.Text}, + }; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/Queryable/KdbndpQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/Queryable/KdbndpQueryable.cs new file mode 100644 index 000000000..d1acc11ac --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/Queryable/KdbndpQueryable.cs @@ -0,0 +1,63 @@ +namespace SqlSugar +{ + public class KdbndpQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + //public override ISugarQueryable PartitionBy(string groupFileds) + //{ + // this.QueryBuilder. + // return this; + //} + } + public class KdbndpQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } + public class KdbndpQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpBuilder.cs new file mode 100644 index 000000000..8752a9eca --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpBuilder.cs @@ -0,0 +1,117 @@ +namespace SqlSugar +{ + public class KdbndpBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string SqlDateNow + { + get + { + return "current_date"; + } + } + public override string FullSqlDateNow + { + get + { + return "select current_date"; + } + } + + + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains('.') && !propertyName.Contains(SqlTranslationLeft)) + { + return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToUpper(IsUpper)}{SqlTranslationRight}")); + } + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + else + return SqlTranslationLeft + propertyName.ToUpper(IsUpper) + SqlTranslationRight; + } + + //public override string GetNoTranslationColumnName(string name) + //{ + // return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower(); + //} + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToUpper(IsUpper) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToUpper(IsUpper) + SqlTranslationRight); + } + + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table 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.Contains('.') && !name.Contains('(')) + { + if (SqlTranslationLeft.HasValue() && SqlTranslationLeft == SqlTranslationRight) + { + return string.Join(".", name.ToUpper(IsUpper).Split('.').Select(it => SqlTranslationLeft + it.Replace(SqlTranslationLeft, "") + SqlTranslationRight)); + } + return string.Join(".", name.ToUpper(IsUpper).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else if (name.Contains('(')) + { + return name; + } + else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else + { + return SqlTranslationLeft + name.ToUpper(IsUpper).TrimEnd('"').TrimStart('"') + SqlTranslationRight; + } + } + public override string GetUnionFomatSql(string sql) + { + return " ( " + sql + " ) "; + } + + + /// + /// + /// + public bool IsUpper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpDeleteBuilder.cs new file mode 100644 index 000000000..f81c546bd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class KdbndpDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpExpressionContext.cs new file mode 100644 index 000000000..bbddf6f8d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpExpressionContext.cs @@ -0,0 +1,563 @@ +namespace SqlSugar +{ + public class KdbndpExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public KdbndpExpressionContext() + { + base.DbMehtods = new KdbndpMethod(); + } + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string GetTranslationText(string name) + { + return SqlTranslationLeft + name.ToUpper(IsUpper) + SqlTranslationRight; + } + + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + + var tableName = mappingInfo?.DbTableName + ""; + if (tableName.Contains('.')) + { + tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + return tableName; + } + + return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToUpper(IsUpper) + SqlTranslationRight; + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public override string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord) + { + return columnName; + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public override string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToUpper(IsUpper); + } + else + { + return propertyName.ToUpper(IsUpper); + } + } + public bool IsUpper + { + get + { + if (this.SugarContext?.Context?.Context?.CurrentConnectionConfig?.MoreSettings == null) + { + return true; + } + else + { + return this.SugarContext?.Context?.Context?.CurrentConnectionConfig?.MoreSettings.IsAutoToUpper == true; + } + } + } + } + public class KdbndpMethod : DefaultDbMethod, IDbMethods + { + public override string CharIndexNew(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({0},{1}))", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string TrueValue() + { + return "true"; + } + public override string FalseValue() + { + return "false"; + } + public override string DateDiff(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return base.DateDiff(model); + } + + var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString())); + var begin = model.Args[1].MemberName; + var end = model.Args[2].MemberName; + switch (parameter) + { + case DateType.Year: + return $" ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) )"; + case DateType.Month: + return $" ( ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) ) * 12 + (DATE_PART('month', {end}) - DATE_PART('month', {begin})) )"; + case DateType.Day: + return $" ( DATE_PART('day', {end} - {begin}) )"; + case DateType.Hour: + return $" ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) )"; + case DateType.Minute: + return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) )"; + case DateType.Second: + return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) ) * 60 + DATE_PART('second', {end} - {begin} )"; + case DateType.Millisecond: + break; + default: + break; + } + throw new Exception(parameter + " datediff no support"); + } + public override string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter.Type == UtilConstants.BoolType) + { + parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); + parameter2.MemberName = false; + parameter3.MemberName = true; + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + public override string Substring(MethodCallExpressionModel model) + { + if (model?.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.MySql) + { + return base.Substring(model).Replace(" + ", " operator(pg_catalog.+) "); + } + return base.Substring(model); + } + public override string DateValue(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return new SqlServerMethod().DateValue(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var format = "dd"; + if (parameter2.MemberValue.ObjToString() == DateType.Year.ToString()) + { + format = "yyyy"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Month.ToString()) + { + format = "MM"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Day.ToString()) + { + format = "dd"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Hour.ToString()) + { + format = "hh24"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Minute.ToString()) + { + format = "mi"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Second.ToString()) + { + format = "ss"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Millisecond.ToString()) + { + format = "ms"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Quarter.ToString()) + { + format = "q"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Weekday.ToString()) + { + return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) "; + } + + return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName); + } + + public override string Contains(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return base.Contains(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like pg_catalog.concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string StartsWith(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return base.StartsWith(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like pg_catalog.concat({1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string EndsWith(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return base.EndsWith(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like pg_catalog.concat('%',{1}))", parameter.MemberName, parameter2.MemberName); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return new SqlServerMethod().DateIsSameDay(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL )", parameter.MemberName); + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return new SqlServerMethod().DateIsSameByType(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + DateType dateType = (DateType)parameter3.MemberValue; + var format = "yyyy-MM-dd"; + if (dateType == DateType.Quarter) + { + return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName, format); + } + switch (dateType) + { + case DateType.Year: + format = "yyyy"; + break; + case DateType.Month: + format = "yyyy-MM"; + break; + case DateType.Day: + break; + case DateType.Hour: + format = "yyyy-MM-dd HH"; + break; + case DateType.Second: + format = "yyyy-MM-dd HH:mm:ss"; + break; + case DateType.Minute: + format = "yyyy-MM-dd HH:mm"; + break; + case DateType.Millisecond: + format = "yyyy-MM-dd HH:mm.ms"; + break; + default: + break; + } + return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + if (IsSqlServerModel(model)) + { + return string.Format(" CAST({0} AS dateTime)", parameter.MemberName); + } + return string.Format(" CAST({0} AS timestamp)", parameter.MemberName); + } + public override string DateAddByType(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return base.DateAddByType(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (model?.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.MySql) + { + return string.Format(" ({1} + ({2} operator(pg_catalog.||) '{0}')::INTERVAL) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName); + } + return string.Format(" ({1} + ({2}||'{0}')::INTERVAL) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return base.DateAddDay(model); + } + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} + ({1}||'day')::INTERVAL) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return new SqlServerMethod().ToInt32(model); + } + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT4)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + if (IsSqlServerModel(model)) + { + return new SqlServerMethod().ToInt64(model); + } + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT8)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + if (IsSqlServerModel(model)) + { + return base.ToString(model); + } + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS UUID)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS boolean)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string MergeString(params string[] strings) + { + var key = Guid.NewGuid() + ""; + if (strings.Length == 1) + { + return " pg_catalog.concat(" + string.Join(",", strings.Select(it => it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ",null) "; + } + return " pg_catalog.concat(" + string.Join(",", strings.Select(it => it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName); + } + public override string GetDate() + { + return "NOW()"; + } + public override string GetRandom() + { + return "RANDOM()"; + } + + public override string EqualTrue(string fieldName) + { + return "( " + fieldName + "=true )"; + } + + public override string JsonField(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + //var parameter2 = model.Args[2]; + //var parameter3= model.Args[3]; + var result = GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count == 2); + if (model.Args.Count > 2) + { + result = GetJson(result, model.Args[2].MemberName, model.Args.Count == 3); + } + if (model.Args.Count > 3) + { + result = GetJson(result, model.Args[3].MemberName, model.Args.Count == 4); + } + if (model.Args.Count > 4) + { + result = GetJson(result, model.Args[4].MemberName, model.Args.Count == 5); + } + if (model.Args.Count > 5) + { + result = GetJson(result, model.Args[5].MemberName, model.Args.Count == 6); + } + return result; + } + + public override string JsonContainsFieldName(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})"; + } + + private string GetJson(object memberName1, object memberName2, bool isLast) + { + if (isLast) + { + return $"({memberName1}::json->>{memberName2})"; + } + else + { + return $"({memberName1}->{memberName2})"; + } + } + + public override string JsonArrayLength(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" json_array_length({parameter.MemberName}::json) "; + } + + public override string JsonParse(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" ({parameter.MemberName}::json) "; + } + + public override string JsonArrayAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name)) + { + return $"{model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb "; + } + else + { + return $"{model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb "; + } + } + public override string Format(MethodCallExpressionModel model) + { + return base.Format(model).Replace("concat(", "pg_catalog.concat("); + } + public override string JsonListObjectAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) + { + return $"{model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}]'::jsonb "; + } + else + { + return $"{model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}]'::jsonb "; + } + } + public override string GetDateString(string dateValue, string formatString) + { + if (formatString.HasValue() && formatString.Contains("hh:mm")) + { + formatString = formatString.Replace("hh:mm", "hh:mi"); + } + else if (formatString.HasValue() && formatString.Contains("hhmm")) + { + formatString = formatString.Replace("hhmm", "hhmi"); + } + else if (formatString.HasValue() && formatString.Contains("HH:mm")) + { + formatString = formatString.Replace("HH:mm", "HH:mi"); + } + else if (formatString.HasValue() && formatString.Contains("HHmm")) + { + formatString = formatString.Replace("HHmm", "HHmi"); + } + if (formatString.Contains("HH")) + { + formatString = formatString.Replace("HH", "hh24"); + } + return $" to_char({dateValue},'{formatString}') "; + } + + private static bool IsSqlServerModel(MethodCallExpressionModel model) + { + return model?.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; + } + + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpFastBuilder.cs new file mode 100644 index 000000000..ff6ee44f4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpFastBuilder.cs @@ -0,0 +1,139 @@ +using NpgsqlTypes; + +using System.Data; + +namespace SqlSugar +{ + public class KdbndpFastBuilder : FastBuilder, IFastBuilder + { + public static Dictionary PgSqlType = UtilMethods.EnumToDictionary(); + + public KdbndpFastBuilder() + { + } + + public override string UpdateSql { get; set; } = @"UPDATE {1} SET {0} FROM {2} AS TE WHERE {3} +"; + + //public virtual async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + //{ + // Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + // Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + // var sets = string.Join(",", updateColumns.Select(it => $"TM.{it}=TE.{it}")); + // var wheres = string.Join(",", whereColumns.Select(it => $"TM.{it}=TE.{it}")); + // string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + // return await this.Context.Ado.ExecuteCommandAsync(sql); + //} + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + List lsColNames = new List(); + for (int i = 0; i < dt.Columns.Count; i++) + { + lsColNames.Add($"\"{dt.Columns[i].ColumnName}\""); + } + string copyString = $"COPY {dt.TableName} ( {string.Join(",", lsColNames)} ) FROM STDIN (FORMAT BINARY)"; + Kdbndp.KdbndpConnection conn = (Kdbndp.KdbndpConnection)this.Context.Ado.Connection; + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(this.FastEntityInfo.DbTableName); + try + { + var identityColumnInfo = this.FastEntityInfo.Columns.FirstOrDefault(it => it.IsIdentity); + if (identityColumnInfo != null) + { + throw new Exception("PgSql bulkcopy no support identity"); + } + BulkCopy(dt, copyString, conn, columns); + } + catch (Exception) + { + throw; + } + finally + { + base.CloseDb(); + } + return await Task.FromResult(dt.Rows.Count).ConfigureAwait(false); + } + + private void BulkCopy(DataTable dt, string copyString, Kdbndp.KdbndpConnection conn, List columns) + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + List columnViews = new List(); + foreach (DataColumn item in dt.Columns) + { + ColumnView result = new ColumnView(); + result.DbColumnInfo = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + result.DataColumn = item; + result.EntityColumnInfo = this.FastEntityInfo.Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + var key = result.DbColumnInfo?.DataType?.ToLower(); + if (result.DbColumnInfo == null) + { + result.Type = null; + } + else if (PgSqlType.TryGetValue(key, out NpgsqlDbType value)) + { + result.Type = value; + } + else if (key?.First() == '_') + { + var type = PgSqlType[key.Substring(1)]; + result.Type = NpgsqlDbType.Array | type; + } + else + { + result.Type = null; + } + columnViews.Add(result); + } + using (var writer = conn.BeginBinaryImport(copyString)) + { + foreach (DataRow row in dt.Rows) + { + writer.StartRow(); + foreach (var column in columnViews) + { + var value = row[column.DataColumn.ColumnName]; + if (value == null) + { + value = DBNull.Value; + } + if (column.Type == null) + { + writer.Write(value); + } + else + { + writer.Write(value); + } + } + } + writer.Complete(); + } + } + + + public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlquerybulder = this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(updateColumns.Length == 0, "update columns count is 0"); + Check.ArgumentNullException(whereColumns.Length == 0, "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"{tableName}.{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + return await Context.Ado.ExecuteCommandAsync(sql).ConfigureAwait(false); + } + public override async Task CreateTempAsync(DataTable dt) + { + await Context.Queryable().Where(it => false).AS(dt.TableName).Select(" * into temp mytemptable").ToListAsync().ConfigureAwait(false); + dt.TableName = "mytemptable"; + } + + public class ColumnView + { + public DataColumn DataColumn { get; set; } + public EntityColumnInfo EntityColumnInfo { get; set; } + public DbColumnInfo DbColumnInfo { get; set; } + public NpgsqlDbType? Type { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpInsertBuilder.cs new file mode 100644 index 000000000..a87493064 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpInsertBuilder.cs @@ -0,0 +1,131 @@ +using System.Text; + +namespace SqlSugar +{ + public class KdbndpInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) returning $PrimaryKey"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + public override string SqlTemplateBatchUnion => " VALUES "; + + public override string SqlTemplateBatchSelect => " {0} "; + + 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 = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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 ( " + string.Join(",", columns.Select(it => + { + if (it.InsertServerTime || it.InsertSql.HasValue() || it.SqlParameterDbType is Type || it?.PropertyType?.Name == "DateOnly" || it?.PropertyType?.Name == "TimeOnly") + { + return GetDbColumn(it, null); + } + object value = null; + if (it.Value is DateTime) + { + if (IsSqlServerModel()) + { + value = ((DateTime)it.Value).ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + else + { + value = ((DateTime)it.Value).ToString("O"); + } + } + else if (it.Value is DateTimeOffset) + { + return FormatDateTimeOffset(it.Value); + } + else if (IsSqlOracleModel() && it.Value is TimeSpan timeSpan) + { + return $"'{timeSpan.Days} {timeSpan.Hours:00}:{timeSpan.Minutes:00}:{timeSpan.Seconds:00}.{timeSpan.Milliseconds:000}{timeSpan.Ticks % 10000:0000}'"; + } + else if (it.Value is bool && (IsMySqlModel() || IsSqlServerModel())) + { + return Convert.ToBoolean(it.Value) ? "1" : "0"; + } + else + { + value = it.Value; + } + if (value == null || value == DBNull.Value) + { + return string.Format(SqlTemplateBatchSelect, "NULL"); + } + return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToString().ToSqlFilter() + "'"); + })) + "),"); + ++i; + } + pageIndex++; + batchInsetrSql.Remove(batchInsetrSql.Length - 1, 1).Append("\r\n;\r\n"); + } + return batchInsetrSql.ToString(); + } + } + private bool IsSqlOracleModel() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Oracle; + } + private bool IsSqlServerModel() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; + } + private bool IsMySqlModel() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.MySql; + } + public override string FormatDateTimeOffset(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff zzz") + "'"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpQueryBuilder.cs new file mode 100644 index 000000000..910004876 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpQueryBuilder.cs @@ -0,0 +1,149 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class KdbndpQueryBuilder : QueryBuilder + { + #region Sql Template + public override string SqlTemplate + { + get + { + if (this.PartitionByValue.HasValue()) + { + return "SELECT {0}{" + UtilConstants.ReplaceKey + "} FROM {1}{2}{3}{4}"; + } + return base.SqlTemplate; + } + } + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 10 offset 0 + */ + if (this.PartitionByValue.HasValue()) + { + return base.PageTempalte; + } + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {6} offset {5}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS ""\w+\.\w+""") || Regex.IsMatch(sql, @"AS ""\w+\.\w+\.\w+"""); + } + public override string ToSqlString() + { + if (PartitionByValue.HasValue()) + { + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) + { + return base.ToSqlString(); + } + else + { + return base.ToSqlString().Replace(" GetDate() ", " NOW() "); + } + } + base.AppendFilter(); + string oldOrderValue = this.OrderByValue; + var isNullOrderValue = Skip == 0 && Take == 1 && oldOrderValue == "ORDER BY NOW() "; + if (isNullOrderValue) + { + this.OrderByValue = null; + } + 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 (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; + } + //if (result.Contains("uuid_generate_v4()")) + //{ + // result = " CREATE EXTENSION IF NOT EXISTS kbcrypto;CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"; " + result; + //} + return result; + } + + #endregion + + #region Get SQL Partial + public override string GetExternalOrderBy(string externalOrderBy) + { + return Regex.Replace(externalOrderBy, @"""\w+""\.", ""); + } + + 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.Count != 0) + { + result = SubToListMethod(result); + } + return result; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpUpdateBuilder.cs new file mode 100644 index 000000000..d83d68283 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Kdbndp/SqlBuilder/KdbndpUpdateBuilder.cs @@ -0,0 +1,281 @@ +using System.Text; + +namespace SqlSugar +{ + public class KdbndpUpdateBuilder : UpdateBuilder + { + public override string SqlTemplateBatch + { + get + { + return @"UPDATE {1} {2} SET {0} FROM ${{0}} "; + } + } + public override string SqlTemplateJoin + { + get + { + return @" (VALUES + {0} + + ) AS T ({2}) WHERE {1} + "; + } + } + + public override string SqlTemplateBatchUnion + { + get + { + return ","; + } + } + + public override object FormatValue(object value) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + var date = value.ObjToDate(); + if (date < Convert.ToDateTime("1900-1-1")) + { + date = Convert.ToDateTime("1900-1-1"); + } + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + return bytesString; + } + else if (type.IsEnum()) + { + return Convert.ToInt64(value); + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (value is DateTimeOffset) + { + return FormatDateTimeOffset(value); + } + else if (IsSqlOracleModel() && value is TimeSpan timeSpan) + { + return $"'{timeSpan.Days} {timeSpan.Hours:00}:{timeSpan.Minutes:00}:{timeSpan.Seconds:00}.{timeSpan.Milliseconds:000}{timeSpan.Ticks % 10000:0000}'"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + protected override string TomultipleSqlString(List> groupList) + { + Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List need Primary key"); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + StringBuilder batchUpdateSql = new StringBuilder(); + while (pageCount >= pageIndex) + { + StringBuilder updateTable = new StringBuilder(); + string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = string.Format("{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName)); + return result; + })); + string tempColumnValue = string.Join(",", groupList.First().Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = Builder.GetTranslationColumnName(it.DbColumnName); + return result; + })); + batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString); + int i = 0; + var tableColumnList = this.Context.DbMaintenance.GetColumnInfosByTableName(GetTableNameStringNoWith); + + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) + { + updateTable.Append(SqlTemplateBatchUnion); + } + updateTable.Append("\r\n (" + string.Join(",", columns.Select(it => + { + var columnInfo = tableColumnList.FirstOrDefault(x => x.DbColumnName.Equals(it.DbColumnName, StringComparison.OrdinalIgnoreCase)); + var dbType = columnInfo?.DataType; + if (dbType == null) + { + var typeName = it.PropertyType.Name.ToLower(); + if (typeName == "int32") + typeName = "int"; + if (typeName == "int64") + typeName = "long"; + if (typeName == "int16") + typeName = "short"; + if (typeName == "boolean") + typeName = "bool"; + + var isAnyType = PostgreSQLDbBind.MappingTypesConst.Where(x => x.Value.ToString().Equals(typeName, StringComparison.CurrentCultureIgnoreCase)).Any(); + if (isAnyType) + { + dbType = PostgreSQLDbBind.MappingTypesConst.Where(x => x.Value.ToString().Equals(typeName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault().Key; + } + else + { + dbType = "varchar"; + } + } + if (IsMySqlModel()) + { + if (dbType == "numeric") + { + dbType = "numeric(18,6)"; + } + } + if (IsSqlServerModel()) + { + if (dbType == "numeric") + { + dbType = "numeric(18,6)"; + } + else if (dbType == "varchar") + { + dbType = "varchar(max)"; + } + else if (dbType == "nvarchar") + { + dbType = "nvarchar(max)"; + } + else if (dbType == "char") + { + dbType = "char(8000)"; + } + else if (dbType == "nchar") + { + dbType = "nchar(4000)"; + } + } + return string.Format("CAST({0} AS {1})", base.GetDbColumn(it, FormatValue(it.Value)), dbType); + + })) + ")"); + ++i; + } + pageIndex++; + updateTable.Append("\r\n"); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += item.Replace(" \"", $" {Builder.GetTranslationColumnName(this.EntityInfo.DbTableName)}.\""); + } + } + if (PrimaryKeys.HasValue()) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += string.Format("{0}.{1}=T.{1}", GetTableNameStringNoWith, Builder.GetTranslationColumnName(item)); + } + } + var format = string.Format(SqlTemplateJoin, updateTable, whereString, tempColumnValue); + batchUpdateSql.Replace("${0}", format); + batchUpdateSql.Append(';'); + } + batchUpdateSql = GetBatchUpdateSql(batchUpdateSql); + return batchUpdateSql.ToString(); + } + + private bool IsSqlServerModel() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; + } + + private bool IsMySqlModel() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.MySql; + } + + private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql) + { + if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null) + { + var result = batchUpdateSql.ToString(); + foreach (var item in ReSetValueBySqlExpList) + { + var dbColumnName = item.Value.DbColumnName; + if (item.Value.Type == ReSetValueBySqlExpListModelType.List) + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={GetTableNameString}.{dbColumnName}{item.Value.Sql}T.{dbColumnName}"); + } + else + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(dbColumnName, $"{Builder.GetTranslationColumnName(this.TableName)}.{dbColumnName}")}"); + } + batchUpdateSql = new StringBuilder(result); + } + } + + return batchUpdateSql; + } + protected override string GetJoinUpdate(string columnsString, ref string whereString) + { + var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} "; + var joinString = ""; + foreach (var item in this.JoinInfos) + { + whereString += " AND " + item.JoinWhere; + joinString += $"\r\n FROM {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} "; + } + var tableName = formString + "\r\n "; + columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName) + ".", "") + joinString; + return string.Format(SqlTemplate, tableName, columnsString, whereString); + } + public override string FormatDateTimeOffset(object value) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff zzz") + "'"; + } + private bool IsSqlOracleModel() + { + return this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Oracle; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs new file mode 100644 index 000000000..c63220f08 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs @@ -0,0 +1,140 @@ +namespace SqlSugar +{ + public class MySqlCodeFirst : CodeFirstProvider + { + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.OrderBy(it => it.IsPrimarykey ? 0 : 1)) + { + if (item.IsIgnore) + continue; + if (item.PropertyInfo != null && UtilMethods.GetUnderType(item.PropertyInfo.PropertyType) == UtilConstants.GuidType && item.Length == 0 && item.DataType == null) + { + item.Length = Guid.NewGuid().ToString().Length; + } + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + } + } + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + DecimalDigits = item.DecimalDigits, + CreateTableFieldSort = item.CreateTableFieldSort + }; + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName, null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + internal DbColumnInfo GetEntityColumnToDbColumn(EntityInfo entity, string dbTableName, EntityColumnInfo item) + { + return EntityColumnToDbColumn(entity, dbTableName, item); + } + + protected override void GetDbType(EntityColumnInfo item, Type propertyType, DbColumnInfo result) + { + if (!string.IsNullOrEmpty(item.DataType)) + { + result.DataType = item.DataType; + } + else if (propertyType.IsEnum()) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(item.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name); + } + else if (item.IsJson && item.DataType == null) + { + result.DataType = "json"; + } + else if (propertyType == UtilConstants.DecType && item.Length == 0 && item.DecimalDigits == 0) + { + result.Length = 18; + result.DecimalDigits = 4; + result.DataType = "decimal"; + } + else + { + var name = GetType(propertyType.Name); + if (name == "Boolean") + { + result.DataType = "tinyint"; + result.Length = 1; + result.Scale = 0; + result.DecimalDigits = 0; + } + else + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(name); + if (name == "Guid" && result.DataType == "varchar" && result.Length <= 1) + { + result.Length = 36; + } + } + } + } + + + protected override bool IsNoSamgeType(EntityColumnInfo ec, DbColumnInfo dc) + { + if (ec.UnderType == UtilConstants.BoolType && dc.DataType == "tinyint" && dc.Length == 1) + { + return false; + } + else if (ec.UnderType == UtilConstants.DobType && dc.DataType == "double") + { + return false; + } + else if (ec.UnderType == UtilConstants.DateType && dc.DataType?.StartsWith("datetime") == true) + { + return false; + } + return base.IsNoSamgeType(ec, dc); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbBind/MySqlDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbBind/MySqlDbBind.cs new file mode 100644 index 000000000..2aab9f37d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbBind/MySqlDbBind.cs @@ -0,0 +1,94 @@ +namespace SqlSugar +{ + public class MySqlDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + { + return "longblob"; + } + if (csharpTypeName == "Int32") + csharpTypeName = "int"; + if (csharpTypeName == "Int16") + csharpTypeName = "short"; + if (csharpTypeName == "Int64") + csharpTypeName = "long"; + if (csharpTypeName == "Boolean") + csharpTypeName = "bool"; + if (csharpTypeName == "SByte") + csharpTypeName = "Byte"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)); + return (mappings?.Any() == true) ? mappings.First().Key : "varchar"; + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("mediumint",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("int unsigned",CSharpDataType.@int), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("enum",CSharpDataType.@string), + new KeyValuePair("mediumtext",CSharpDataType.@string), + new KeyValuePair("tinytext",CSharpDataType.@string), + new KeyValuePair("longtext",CSharpDataType.@string), + + new KeyValuePair("tinyint",CSharpDataType.@byte), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("bit",CSharpDataType.@bool), + new KeyValuePair("real",CSharpDataType.@double), + new KeyValuePair("double",CSharpDataType.@double), + new KeyValuePair("float",CSharpDataType.@float), + new KeyValuePair("float",CSharpDataType.Single), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("year",CSharpDataType.@int), + + new KeyValuePair("datetime",CSharpDataType.DateTime), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + + new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("longblob",CSharpDataType.byteArray), + new KeyValuePair("tinyblob",CSharpDataType.byteArray), + new KeyValuePair("varbinary",CSharpDataType.byteArray), + new KeyValuePair("binary",CSharpDataType.byteArray), + new KeyValuePair("multipoint",CSharpDataType.byteArray), + new KeyValuePair("geometry",CSharpDataType.byteArray), + new KeyValuePair("multilinestring",CSharpDataType.byteArray), + new KeyValuePair("polygon",CSharpDataType.byteArray), + new KeyValuePair("mediumblob",CSharpDataType.byteArray), + + new KeyValuePair("varchar",CSharpDataType.Guid), + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbFirst/MySqlDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbFirst/MySqlDbFirst.cs new file mode 100644 index 000000000..17c3ebc3f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbFirst/MySqlDbFirst.cs @@ -0,0 +1,30 @@ +namespace SqlSugar +{ + public class MySqlDbFirst : DbFirstProvider + { + protected override string GetPropertyTypeName(DbColumnInfo item) + { + if (item.DataType == "tinyint" && item.Length == 1 && Context.CurrentConnectionConfig.ConnectionString.Contains("treattinyasboolea", StringComparison.CurrentCultureIgnoreCase) == false) + { + item.DataType = "bit"; + item.DefaultValue = "true"; + return "bool"; + } + if (item.DataType == "mediumint") + { + item.DataType = "int"; + return "int"; + } + if (item.DataType == "mediumint unsigned") + { + item.DataType = "mediumint unsigned"; + return "uint"; + } + if (item.DataType == "double unsigned") + { + return "double"; + } + return base.GetPropertyTypeName(item); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbMaintenance/DorisHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbMaintenance/DorisHelper.cs new file mode 100644 index 000000000..c6fe07330 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbMaintenance/DorisHelper.cs @@ -0,0 +1,54 @@ +namespace SqlSugar +{ + internal static class DorisHelper + { + + public static void UpdateDateParameter(MySqlConnector.MySqlParameter sqlParameter) + { + if (sqlParameter.DbType == System.Data.DbType.DateTime) + { + sqlParameter.DbType = System.Data.DbType.String; + sqlParameter.Value = sqlParameter.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + if (sqlParameter.DbType == System.Data.DbType.DateTimeOffset) + { + sqlParameter.DbType = System.Data.DbType.String; + sqlParameter.Value = sqlParameter.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + } + public static List GetColumns(List colums) + { + foreach (var item in colums) + { + if (item.DataType?.Contains('(') == true) + { + item.DataType = item.DataType.Substring(0, item.DataType.IndexOf('(')); + } + if (item.DataType == "tinyint" && item.Length == 4) + { + item.Length = 1; + } + } + return colums; + } + + public static bool IsDoris(ISqlSugarClient context) + { + return context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Doris; + } + + public static string UpdateDorisSql(ISqlBuilder sqlBuilder, List columns, string sql) + { + var pk = columns.FirstOrDefault(it => it.IsPrimarykey); + if (pk != null) + { + Check.ExceptionEasy(columns.Where(it => it.IsIdentity).Count() > 1, "Doris identity key no supported", "Doris不支持自增"); + Check.ExceptionEasy(columns.Where(it => it.IsPrimarykey).Count() > 1, "Doris Only one primary key is supported", "Doris只支持单主键"); + sql = sql.Replace("$PrimaryKey)", ")"); + var pkName = sqlBuilder.GetTranslationColumnName(pk.DbColumnName); + sql += " \r\nENGINE=OLAP\r\nUNIQUE KEY(" + pkName + ")\r\nDISTRIBUTED BY HASH(" + pkName + ") BUCKETS 1\r\nPROPERTIES (\r\n 'replication_num' = '1',\r\n 'storage_format' = 'DEFAULT'\r\n);\r\n\r\n"; + } + return sql; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs new file mode 100644 index 000000000..8ea57d52f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs @@ -0,0 +1,810 @@ +using System.Data; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class MySqlDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + return "SHOW DATABASES"; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string sql = @"SELECT + 0 as TableId, + TABLE_NAME as TableName, + column_name AS DbColumnName, + CASE WHEN left(COLUMN_TYPE,LOCATE('(',COLUMN_TYPE)-1)='' THEN COLUMN_TYPE ELSE left(COLUMN_TYPE,LOCATE('(',COLUMN_TYPE)-1) END AS DataType, + CAST(SUBSTRING(COLUMN_TYPE,LOCATE('(',COLUMN_TYPE)+1,LOCATE(')',COLUMN_TYPE)-LOCATE('(',COLUMN_TYPE)-1) AS decimal(18,0) ) AS Length, + column_default AS `DefaultValue`, + column_comment AS `ColumnDescription`, + CASE WHEN COLUMN_KEY = 'PRI' + THEN true ELSE false END AS `IsPrimaryKey`, + CASE WHEN EXTRA='auto_increment' THEN true ELSE false END as IsIdentity, + CASE WHEN is_nullable = 'YES' + THEN true ELSE false END AS `IsNullable`, + numeric_scale as Scale, + numeric_scale as DecimalDigits, + LOCATE( 'unsigned',COLUMN_type ) >0 as IsUnsigned + FROM + Information_schema.columns where TABLE_NAME='{0}' and TABLE_SCHEMA=(select database()) ORDER BY ordinal_position"; + if (DorisHelper.IsDoris(this.Context)) + { + sql = sql.Replace("CASE WHEN left(COLUMN_TYPE,LOCATE('(',COLUMN_TYPE)-1)='' THEN COLUMN_TYPE ELSE left(COLUMN_TYPE,LOCATE('(',COLUMN_TYPE)-1) END AS DataType", "COLUMN_TYPE AS DataType "); + } + return sql; + } + } + protected override string GetTableInfoListSql + { + get + { + return @"select TABLE_NAME as Name,TABLE_COMMENT as Description from information_schema.tables + where TABLE_SCHEMA=(select database()) AND TABLE_TYPE='BASE TABLE'"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select TABLE_NAME as Name,TABLE_COMMENT as Description from information_schema.tables + where TABLE_SCHEMA=(select database()) AND TABLE_TYPE='VIEW' + "; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE `{0}` CHARACTER SET utf8 COLLATE utf8_general_ci "; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + // return "ALTER TABLE {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + return "alter table {0} change column {1} {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return "mysqldump.exe {0} -uroot -p > {1} "; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "Create table {1} (Select * from {2} LIMIT 0,{0})"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} drop primary key;"; + } + } + protected override string RenameColumnSql + { + get + { + return "alter table {0} change column {1} {2}"; + } + } + protected override string IsAnyProcedureSql + { + get + { + return "select count(*) from information_schema.Routines where ROUTINE_NAME='{0}' and ROUTINE_TYPE='PROCEDURE'"; + } + } + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select 1 from Information_schema.columns where TABLE_SCHEMA=(select database()) limit 0,1"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "DEFAULT NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "AUTO_INCREMENT"; + } + } + + protected override string AddColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string AddTableRemarkSql + { + get + { + return "ALTER TABLE {0} COMMENT='{1}';"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "ALTER TABLE {0} COMMENT='';"; + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string RenameTableSql + { + get + { + return "alter table {0} rename {1}"; + } + } + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX `Index_{0}_{2}` ON `{0}` ({1})"; + } + } + + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE `{0}` ALTER COLUMN `{1}` SET DEFAULT '{2}'"; + } + } + protected override string IsAnyIndexSql + { + get + { + return "SELECT count(*) FROM information_schema.statistics WHERE index_name = '{0}' and index_schema = '{1}'"; + } + } + #endregion + + #region Methods + public override bool DropIndex(string indexName, string tableName) + { + indexName = this.SqlBuilder.GetNoTranslationColumnName(indexName); + tableName = this.SqlBuilder.GetNoTranslationColumnName(tableName); + this.Context.Ado.ExecuteCommand($" DROP INDEX {indexName} ON {tableName}"); + return true; + } + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + if (DorisHelper.IsDoris(this.Context)) + { + var colums = base.GetColumnInfosByTableName(tableName, isCache); + colums = DorisHelper.GetColumns(colums); + return colums; + } + return base.GetColumnInfosByTableName(tableName, isCache); + } + + public override bool SetAutoIncrementInitialValue(string tableName, int initialValue) + { + initialValue++; + this.Context.Ado.ExecuteCommand($"ALTER TABLE " + this.SqlBuilder.GetTranslationColumnName(tableName) + " AUTO_INCREMENT = " + initialValue); + return true; + } + public override bool SetAutoIncrementInitialValue(Type entityType, int initialValue) + { + return this.SetAutoIncrementInitialValue(this.Context.EntityMaintenance.GetEntityInfo(entityType).DbTableName, initialValue); + } + public override List GetDbTypes() + { + return this.Context.Ado.SqlQuery(@"SELECT DISTINCT DATA_TYPE +FROM information_schema.COLUMNS"); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT TRIGGER_NAME +FROM INFORMATION_SCHEMA.TRIGGERS +WHERE EVENT_OBJECT_TABLE = '" + tableName + "'"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery(" SELECT routine_name\r\nFROM information_schema.ROUTINES\r\nWHERE routine_schema = (SELECT DATABASE()) AND routine_type = 'FUNCTION'; "); + } + public override List GetIndexList(string tableName) + { + var sql = $"SHOW INDEX FROM {this.SqlBuilder.GetTranslationColumnName(tableName)}"; + return this.Context.Ado.GetDataTable(sql).AsEnumerable().Cast().Select(it => it["key_name"]).Cast().ToList(); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT ROUTINE_NAME FROM information_schema.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE' AND ROUTINE_SCHEMA = '{dbName}'"; + return this.Context.Ado.SqlQuery(sql); + } + public override bool IsAnyTable(string tableName, bool isCache = true) + { + try + { + return base.IsAnyTable(tableName, isCache); + } + catch (Exception ex) + { + if (SugarCompatible.IsFramework && ex.Message == "Invalid attempt to Read when reader is closed.") + { + Check.ExceptionEasy($"To upgrade the MySql.Data. Error:{ex.Message}", $" 请先升级MySql.Data 。 详细错误:{ex.Message}"); + return true; + } + else + { + throw; + } + } + } + public override bool IsAnyColumnRemark(string columnName, string tableName) + { + var isAny = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName, false) + .Any(it => it.ColumnDescription.HasValue() && it.DbColumnName.EqualCase(columnName)); + return isAny; + } + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + + tableName = this.SqlBuilder.GetTranslationColumnName(tableName); + columnName = this.SqlBuilder.GetTranslationColumnName(columnName); + var sql = this.Context.Ado.GetDataTable($"SHOW CREATE TABLE {tableName};").Rows[0][1] + ""; + var columns = sql.Split('\n'); + var columnList = columns.Where(it => it.Last() == ',').ToList(); + + foreach (var column in columnList) + { + if (column.Contains(columnName)) + { + Regex regex = new Regex(" COMMENT .+$"); + var newcolumn = regex.Replace(column.TrimEnd(','), ""); + newcolumn += $" COMMENT '{description.ToSqlFilter()}' "; + var updateSql = $"ALTER TABLE {tableName} MODIFY COLUMN " + newcolumn.TrimEnd(','); + this.Context.Ado.ExecuteCommand(updateSql); + break; + } + } + ////base.AddColumnRemark(columnName, tableName, description); + //var message= @"db.DbMaintenance.UpdateColumn(""tablename"", new DbColumnInfo() + //{{ + // DataType = ""VARCHAR(30) NOT NULL COMMENT 'xxxxx'"", + // DbColumnName = ""columnname"" + //}})" ; + //Check.Exception(true,"MySql no support AddColumnRemark , use " + message); + return true; + } + /// + ///by current connection string + /// + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + + if (this.Context.Ado.IsValidConnection() && this.Context.Ado.Connection.Database?.ToLower() == databaseName?.ToLower()) + { + return true; + } + + if (databaseDirectory != null) + { + if (!FileHelper.IsExistDirectory(databaseDirectory)) + { + FileHelper.CreateDirectory(databaseDirectory); + } + } + var oldDatabaseName = this.Context.Ado.Connection.Database; + var connection = this.Context.CurrentConnectionConfig.ConnectionString; + if (Regex.Split(connection, oldDatabaseName).Length > 2) + { + var name = Regex.Match(connection, @"database\=\w+|datasource\=\w+", RegexOptions.IgnoreCase).Value; + if (!string.IsNullOrEmpty(name)) + { + connection = connection.Replace(name, "database=mysql"); + } + else + { + Check.ExceptionEasy("Failed to create the database. The database name has a keyword. Please change the name", "建库失败,库名存在关键字,请换一个名字"); + } + } + else + { + connection = connection.Replace(oldDatabaseName, "mysql"); + } + var newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = connection + }); + if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) + { + var createSql = CreateDataBaseSql; + if (ContainsCharSet("utf8mb4")) + { + createSql = createSql.Replace("utf8 COLLATE utf8_general_ci", "utf8mb4"); + } + if (!string.IsNullOrEmpty(StaticConfig.CodeFirst_MySqlCollate)) + { + if (createSql.Contains(" COLLATE ")) + { + createSql = $" {Regex.Split(createSql, " COLLATE ").First()} COLLATE {StaticConfig.CodeFirst_MySqlCollate} "; + } + else + { + createSql += $" COLLATE {StaticConfig.CodeFirst_MySqlCollate} "; + } + } + newDb.Ado.ExecuteCommand(string.Format(createSql, databaseName, databaseDirectory)); + } + return true; + } + public override bool AddTableRemark(string tableName, string description) + { + if (DorisHelper.IsDoris(this.Context)) + { + return false; + } + string sql = string.Format(this.AddTableRemarkSql, this.SqlBuilder.GetTranslationTableName(tableName), description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + item.Length = 10; + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName)))); + + } + if (DorisHelper.IsDoris(this.Context)) + { + sql = DorisHelper.UpdateDorisSql(this.SqlBuilder, columns, sql); + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + if (!string.IsNullOrEmpty(StaticConfig.CodeFirst_MySqlTableEngine)) + { + sql += " ENGINE = " + StaticConfig.CodeFirst_MySqlTableEngine; + } + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var oldColumns = this.Context.DbMaintenance.GetColumnInfosByTableName(entity.DbTableName, false); + var db = this.Context; + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + List columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + var mySqlCodeFirst = this.Context.CodeFirst as MySqlCodeFirst; + if (item.UnderType == UtilConstants.GuidType && item.Length == 0) + { + item.Length = 36; + } + var columnInfo = oldColumns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.DbColumnName)); + if (columnInfo?.ColumnDescription.ObjToString() != item.ColumnDescription.ObjToString()) + { + string sql = GetUpdateColumnSql(entity.DbTableName, mySqlCodeFirst.GetEntityColumnToDbColumn(entity, entity.DbTableName, item)) + " " + (item.IsIdentity ? "AUTO_INCREMENT" : "") + " " + " COMMENT '" + item.ColumnDescription + "'"; + db.Ado.ExecuteCommand(sql); + } + } + } + return true; + } + protected override string GetCreateTableSql(string tableName, List columns) + { + List columnArray = new List(); + Check.Exception(columns.IsNullOrEmpty(), "No columns found "); + foreach (var item in columns) + { + + ConvertCreateColumnInfo(item); + + string columnName = item.DbColumnName; + string dataSize = ""; + dataSize = GetSize(item); + string dataType = item.DataType; + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string identity = item.IsIdentity ? this.CreateTableIdentity : null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName), dataType, dataSize, nullType, primaryKey, identity); + if (!string.IsNullOrEmpty(item.ColumnDescription)) + { + addItem += " COMMENT '" + item.ColumnDescription.ToSqlFilter() + "' "; + } + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",\r\n", columnArray)); + return tableString; + } + + public override bool AddPrimaryKey(string tableName, string columnName) + { + if (DorisHelper.IsDoris(this.Context)) + { + return false; + } + return base.AddPrimaryKey(tableName, columnName); + } + public override bool AddColumn(string tableName, DbColumnInfo columnInfo) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var isAddNotNUll = columnInfo.IsNullable == false && columnInfo.DefaultValue.HasValue(); + if (isAddNotNUll) + { + columnInfo = this.Context.Utilities.TranslateCopy(columnInfo); + columnInfo.IsNullable = true; + } + string sql = GetAddColumnSql(tableName, columnInfo); + if (sql != null && columnInfo.ColumnDescription.HasValue() && !sql.Contains("comment", StringComparison.CurrentCultureIgnoreCase)) + { + sql = $"{sql}{" COMMENT '" + columnInfo.ColumnDescription.ToSqlFilter() + "' "}"; + } + if (DorisHelper.IsDoris(this.Context)) + { + sql = sql.Replace(" ADD ", " ADD COLUMN "); + } + this.Context.Ado.ExecuteCommand(sql); + if (isAddNotNUll) + { + var dtColums = this.Context.Queryable().AS(columnInfo.TableName).Where("1=2") + .Select(this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName)).ToDataTable().Columns.Cast(); + var dtColumInfo = dtColums.First(it => it.ColumnName.EqualCase(columnInfo.DbColumnName)); + var type = UtilMethods.GetUnderType(dtColumInfo.DataType); + var value = type == UtilConstants.StringType ? (object)"" : Activator.CreateInstance(type); + //if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + //{ + // value = columnInfo.DefaultValue; + // if (value.Equals("")) + // { + // value = "empty"; + // } + //} + value = GetDefaultValue(columnInfo, value); + var dt = new Dictionary(); + dt.Add(columnInfo.DbColumnName, value); + this.Context.Updateable(dt) + .AS(tableName) + .Where($"{columnInfo.DbColumnName} is null ").ExecuteCommand(); + columnInfo.IsNullable = false; + UpdateColumn(tableName, columnInfo); + } + return true; + } + public override bool UpdateColumn(string tableName, DbColumnInfo column) + { + ConvertCreateColumnInfo(column); + if (DorisHelper.IsDoris(this.Context)) + { + return DorisUpadteColumns(ref tableName, column); + } + return base.UpdateColumn(tableName, column); + } + + + protected override string GetSize(DbColumnInfo item) + { + string dataSize = null; + var isMax = item.Length > 4000 || item.Length == -1; + if (isMax) + { + dataSize = ""; + item.DataType = "longtext"; + } + else if (item.Length > 0 && item.DecimalDigits == 0) + { + dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + } + else if (item.Length == 0 && item.DecimalDigits > 0) + { + item.Length = 10; + dataSize = string.Format("({0},{1})", item.Length, item.DecimalDigits); + } + else if (item.Length > 0 && item.DecimalDigits > 0) + { + dataSize = item.Length > 0 ? string.Format("({0},{1})", item.Length, item.DecimalDigits) : null; + } + return dataSize; + } + + public override bool RenameColumn(string tableName, string oldColumnName, string newColumnName) + { + var columns = GetColumnInfosByTableName(tableName, false).Where(it => it.DbColumnName.Equals(oldColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (columns?.Any() == true) + { + var column = columns.First(); + var appendSql = " " + column.DataType; + if (column.Length > 0 && column.Scale == 0) + { + appendSql += string.Format("({0}) ", column.Length); + } + else if (column.Scale > 0 && column.Length > 0) + { + appendSql += string.Format("({0},{1}) ", column.Length, column.Scale); + } + else + { + appendSql += column.IsNullable ? " NULL " : " NOT NULL "; + } + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + oldColumnName = this.SqlBuilder.GetTranslationColumnName(oldColumnName); + newColumnName = this.SqlBuilder.GetTranslationColumnName(newColumnName); + string sql = string.Format(this.RenameColumnSql, tableName, oldColumnName, newColumnName + appendSql); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + else + { + return false; + } + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue == "''") + { + defaultValue = ""; + } + if (defaultValue.ToLower().IsIn("null", "now()", "current_timestamp") || defaultValue.Contains("current_timestamp", StringComparison.CurrentCultureIgnoreCase) || defaultValue.Contains("()")) + { + defaultValue = "(" + defaultValue + ")"; + string sql = string.Format(AddDefaultValueSql.Replace("'", ""), tableName, columnName, defaultValue); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + else if (defaultValue == "0" || defaultValue == "1") + { + string sql = string.Format(AddDefaultValueSql.Replace("'", ""), tableName, columnName, defaultValue); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + else + { + return base.AddDefaultValue(tableName, columnName, defaultValue); + } + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("MySql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + if (fullFileName == null) + { + fullFileName = $"c:\\{databaseName}.sql"; + } + var db = this.Context.CopyNew(); + using (db.Ado.OpenAlways()) + { + if (databaseName != null) + { + db.Ado.Connection.ChangeDatabase(databaseName); + } + // Load the MySqlBackup assembly + Assembly assembly = null; + + try + { + if (StaticConfig.Backup_MySqlBackupType != null) + { + assembly = StaticConfig.Backup_MySqlBackupType.Assembly; + } + else + { + Assembly currentAssembly = Assembly.GetExecutingAssembly(); + string exePath = currentAssembly.Location.Replace("SqlSugar.dll", "MySqlBackupNet.MySqlConnector.dll"); + assembly = Assembly.LoadFrom(exePath); + } + } + catch (Exception) + { + Check.ExceptionEasy("Need MySqlBackup.NET.MySqlConnector", "需要安装:MySqlBackup.NET.MySqlConnector"); + throw; + } + + // Get the MySqlBackup type + Type mbType = assembly.GetType("MySqlConnector.MySqlBackup", false); + + // Create an instance of the MySqlBackup class + object mb = Activator.CreateInstance(mbType, db.Ado.Connection.CreateCommand()); + + // Get the ExportToFile method + MethodInfo exportMethod = mbType.GetMethod("ExportToFile"); + + // Invoke the ExportToFile method + exportMethod.Invoke(mb, new object[] { fullFileName }); + } + return true; + } + + #endregion + + #region Helper + + private bool DorisUpadteColumns(ref string tableName, DbColumnInfo column) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columName = this.SqlBuilder.GetTranslationTableName(column.DbColumnName); + string sql = GetUpdateColumnSql(tableName, column) + .Replace("change column", " MODIFY COLUMN") + .Replace("DEFAULT NULL ", " NULL ") + .Replace($"{columName} {columName}", columName); + try + { + this.Context.Ado.ExecuteCommand(sql); + } + catch (Exception ex) + { + if (ex.Message == "errCode = 2, detailMessage = Nothing is changed. please check your alter stmt.") + { + return true; + } + throw; + } + return true; + } + private bool ContainsCharSet(string charset) + { + if (Context.CurrentConnectionConfig.ConnectionString.ObjToString().Contains(charset, StringComparison.CurrentCultureIgnoreCase)) + { + return true; + } + else + { + return false; + } + } + private static void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "longtext", "date" }; + + if (("nvarchar".EqualCase(x.DataType) || "varchar".EqualCase(x.DataType))) + { + if (x.Length < 1) + { + x.DataType = $"{x.DataType}(255)"; // 设置默认长度为 255,你可以根据需要修改 + } + } + else if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/MySqlProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/MySqlProvider.cs new file mode 100644 index 000000000..c43fbfbb9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/MySqlProvider.cs @@ -0,0 +1,323 @@ +using MySqlConnector; + +using Newtonsoft.Json.Linq; + +using System.Data; +using System.Data.Common; +namespace SqlSugar +{ + public class MySqlProvider : AdoProvider + { + public MySqlProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var mySqlConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + Check.ExceptionEasy(String.IsNullOrEmpty(mySqlConnectionString), "ConnectionString is not null", "连接字符串ConnectionString不能为Null"); + if (!mySqlConnectionString.Contains("charset", StringComparison.CurrentCultureIgnoreCase) && !mySqlConnectionString.Contains("character", StringComparison.CurrentCultureIgnoreCase)) + { + mySqlConnectionString = mySqlConnectionString.Trim().TrimEnd(';') + ";charset=utf8;"; + } + //if (!mySqlConnectionString.ToLower().Contains("min")) + //{ + // mySqlConnectionString = mySqlConnectionString.Trim().TrimEnd(';') + ";min pool size=1"; + //} + base._DbConnection = new MySqlConnection(mySqlConnectionString); + } + catch (Exception ex) + { + if (ex is SqlSugarException) + { + throw; + } + else + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new MySqlDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + MySqlCommand sqlCommand = new MySqlCommand(sql, (MySqlConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (MySqlTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((MySqlParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((MySqlDataAdapter)dataAdapter).SelectCommand = (MySqlCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + MySqlParameter[] result = new MySqlParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new MySqlParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + if (parameter.Direction == 0) + { + parameter.Direction = ParameterDirection.Input; + } + sqlParameter.Direction = parameter.Direction; + //if (sqlParameter.Direction == 0) + //{ + // sqlParameter.Direction = ParameterDirection.Input; + //} + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + else if (parameter.DbType == System.Data.DbType.DateTimeOffset) + { + if (sqlParameter.Value != DBNull.Value) + sqlParameter.Value = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)sqlParameter.Value); + sqlParameter.DbType = System.Data.DbType.DateTime; + } + if (sqlParameter.Value is DateTime && sqlParameter.Value.ObjToDate() == DateTime.MinValue) + { + var date = Convert.ToDateTime(sqlParameter.Value); + if (date == DateTime.MinValue) + { + sqlParameter.Value = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + } + } + if (parameter.IsJson == false && sqlParameter.Value != null && sqlParameter.Value is JArray) + { + sqlParameter.Value = sqlParameter.Value.ToString(); + } + if (DorisHelper.IsDoris(this.Context)) + { + DorisHelper.UpdateDateParameter(sqlParameter); + } + ++index; + } + return result; + } + + + protected override void SugarCatch(Exception ex, string sql, SugarParameter[] parameters) + { + base.SugarCatch(ex, sql, parameters); + + if (ex is NullReferenceException && SugarCompatible.IsFramework) + { + Check.ExceptionEasy($"To upgrade the MySql.Data. Error:{ex.Message}", $" 请先升级MySql.Data 。 详细错误:{ex.Message}"); + } + } + + #region async + public override async Task GetCommandAsync(string sql, SugarParameter[] parameters) + { + MySqlCommand sqlCommand = new MySqlCommand(sql, (MySqlConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (MySqlTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((MySqlParameter[])ipars); + } + if (this.Connection.State != ConnectionState.Open) + { + try + { + await (Connection as MySqlConnection).OpenAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + Check.Exception(true, ex.Message); + } + } + return sqlCommand; + } + public override async Task ExecuteCommandAsync(string sql, params SugarParameter[] parameters) + { + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return await base.ExecuteCommandAsync(sql, parameters).ConfigureAwait(false); + try + { + Async(); + InitParameters(ref sql, parameters); + if (FormatSql != null) + sql = FormatSql(sql); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + var sqlCommand = await GetCommandAsync(sql, parameters).ConfigureAwait(false); + int count; + if (this.CancellationToken == null) + count = await sqlCommand.ExecuteNonQueryAsync().ConfigureAwait(false); + else + count = await sqlCommand.ExecuteNonQueryAsync(CancellationToken.Value).ConfigureAwait(false); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + SqlExecuteCount = count; + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return count; + } + catch (Exception ex) + { + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) + { + await CloseAsync().ConfigureAwait(false); + } + SetConnectionEnd(sql); + } + } + public override async Task GetDataReaderAsync(string sql, params SugarParameter[] parameters) + { + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return await base.GetDataReaderAsync(sql, parameters).ConfigureAwait(false); + try + { + Async(); + InitParameters(ref sql, parameters); + if (FormatSql != null) + sql = FormatSql(sql); + SetConnectionStart(sql); + var isSp = this.CommandType == CommandType.StoredProcedure; + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + var sqlCommand = await GetCommandAsync(sql, parameters).ConfigureAwait(false); + DbDataReader sqlDataReader; + if (this.CancellationToken == null) + sqlDataReader = await sqlCommand.ExecuteReaderAsync(IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default).ConfigureAwait(false); + else + sqlDataReader = await sqlCommand.ExecuteReaderAsync(IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default, CancellationToken.Value).ConfigureAwait(false); + if (isSp) + DataReaderParameters = sqlCommand.Parameters; + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + SetConnectionEnd(sql); + if (SugarCompatible.IsFramework || this.Context.CurrentConnectionConfig.DbType != DbType.Sqlite) + sqlCommand.Dispose(); + return sqlDataReader; + } + catch (Exception ex) + { + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + } + public override async Task GetScalarAsync(string sql, params SugarParameter[] parameters) + { + if (this.Context.CurrentConnectionConfig?.SqlMiddle?.IsSqlMiddle == true) + return await base.GetScalarAsync(sql, parameters).ConfigureAwait(false); + try + { + Async(); + InitParameters(ref sql, parameters); + if (FormatSql != null) + sql = FormatSql(sql); + SetConnectionStart(sql); + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, ref parameters); + ExecuteBefore(sql, parameters); + var sqlCommand = await GetCommandAsync(sql, parameters).ConfigureAwait(false); + object scalar; + if (CancellationToken == null) + scalar = await sqlCommand.ExecuteScalarAsync().ConfigureAwait(false); + else + scalar = await sqlCommand.ExecuteScalarAsync(CancellationToken.Value).ConfigureAwait(false); + //scalar = (scalar == null ? 0 : scalar); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + sqlCommand.Dispose(); + return scalar; + } + catch (Exception ex) + { + CommandType = CommandType.Text; + if (ErrorEvent != null) + ExecuteErrorEvent(sql, parameters, ex); + throw; + } + finally + { + if (this.IsAutoClose()) + { + await CloseAsync().ConfigureAwait(false); + } + SetConnectionEnd(sql); + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/PatialClass/MySqlFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/PatialClass/MySqlFastBuilder.cs new file mode 100644 index 000000000..5a3a4ab5a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/PatialClass/MySqlFastBuilder.cs @@ -0,0 +1,31 @@ +using MySqlConnector; + +using System.Data; + +namespace SqlSugar +{ + public partial class MySqlFastBuilder : FastBuilder, IFastBuilder + { + private async Task MySqlConnectorBulkCopy(DataTable dt) + { + try + { + this.Context.Open(); + var tran = (MySqlTransaction)this.Context.Ado.Transaction; + var connection = (MySqlConnection)this.Context.Ado.Connection; + MySqlBulkCopy bulkCopy = new MySqlBulkCopy(connection, tran); + bulkCopy.DestinationTableName = dt.TableName; + await bulkCopy.WriteToServerAsync(dt).ConfigureAwait(false); + return dt.Rows.Count; + } + catch (Exception) + { + throw; + } + finally + { + CloseDb(); + } + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/Queryable/MySqlQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/Queryable/MySqlQueryable.cs new file mode 100644 index 000000000..54bca969e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/Queryable/MySqlQueryable.cs @@ -0,0 +1,72 @@ +namespace SqlSugar +{ + public class MySqlQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + if (withString == null) + { + return this; + } + if (UtilMethods.StringCheckFirstAndLast(withString.TrimStart(' ').TrimEnd(' '), "/*", "*/")) + { + QueryBuilder.TableWithString = withString; + } + else if (UtilMethods.StringCheckFirstAndLast(withString.TrimStart(' ').TrimEnd(' ').ToLower(), "force", ")")) + { + QueryBuilder.TableWithString = withString; + } + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + this.GroupBy(groupFileds); + return this; + } + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } + public class MySqlQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlBlukCopy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlBlukCopy.cs new file mode 100644 index 000000000..9a7d2cbb8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlBlukCopy.cs @@ -0,0 +1,202 @@ +using MySqlConnector; + +using System.Data; +using System.Reflection; +using System.Text; +namespace SqlSugar +{ + public partial class MySqlBlukCopy + { + + private MySqlBlukCopy() + { + + } + + public bool ExecuteBulkCopy(string characterSet) + { + this.Chara = characterSet; + return ExecuteBulkCopy(); + } + + public bool ExecuteBulkCopy() + { + var IsBulkLoad = false; + if (Entitys == null || Entitys.Length <= 0) + return IsBulkLoad; + if (Entitys.First() == null && Entitys.Length == 1) + return IsBulkLoad; + DataTable dt = new DataTable(); + Type type = typeof(T); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + dt.TableName = this.Builder.GetTranslationColumnName(entity.DbTableName); + //if (this.Context.MappingTables != null && this.Context.MappingTables.Any(it => it.EntityName == it.EntityName)) + //{ + // dt.TableName = this.Builder.GetTranslationColumnName(this.Context.MappingTables.First(it => it.EntityName == it.EntityName).DbTableName); + //} + //创建属性的集合 + List pList = new List(); + //把所有的public属性加入到集合 并添加DataTable的列 + Array.ForEach(entity.Columns.ToArray(), p => + { + if (!p.IsIgnore && !p.IsOnlyIgnoreInsert) + { + pList.Add(p.PropertyInfo); dt.Columns.Add(p.DbColumnName); + } + }); + DataRow row = null; + foreach (T item in Entitys) + { + row = dt.NewRow(); + pList.ForEach(p => + { + var name = p.Name; + if (entity.Columns.Any(it => it.PropertyName == name)) + { + name = entity.Columns.First(it => it.PropertyName == name).DbColumnName; + } + row[name] = GetValue(p, item); + }); + dt.Rows.Add(row); + } + var dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "failFiles"); + DirectoryInfo dir = new DirectoryInfo(dllPath); + if (!dir.Exists) + { + dir.Create(); + } + var fileName = Path.Combine(dllPath, Guid.NewGuid().ToString() + ".csv"); + var dataTableToCsv = DataTableToCsvString(dt); + File.WriteAllText(fileName, dataTableToCsv, new UTF8Encoding(false)); + MySqlConnection conn = this.Context.Ado.Connection as MySqlConnection; + try + { + this.Context.Ado.Open(); + // IsolationLevel.Parse + MySqlBulkLoader bulk = new MySqlBulkLoader(conn) + { + CharacterSet = GetChara(), + FieldTerminator = ",", + FieldQuotationCharacter = '"', + EscapeCharacter = '"', + LineTerminator = Environment.NewLine, + FileName = fileName, + NumberOfLinesToSkip = 0, + TableName = dt.TableName, + Local = true, + }; + bulk.Columns.AddRange(dt.Columns.Cast().Select(colum => colum.ColumnName).Distinct().ToArray()); + IsBulkLoad = bulk.Load() > 0; + //执行成功才删除文件 + if (IsBulkLoad && File.Exists(fileName)) + { + File.Delete(fileName); + } + } + catch (MySqlException) + { + throw; + } + finally + { + CloseDb(); + } + return IsBulkLoad; ; + } + + public Task ExecuteBulkCopyAsync() + { + return Task.FromResult(ExecuteBulkCopy()); + } + + public Task ExecuteBulkCopyAsync(string characterSet) + { + this.Chara = characterSet; + return Task.FromResult(ExecuteBulkCopy()); + } + + #region Helper + private string GetChara() + { + if (this.Chara == null) + { + return "utf8mb4"; + } + else + { + return this.Chara; + } + } + + private void CloseDb() + { + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) + { + this.Context.Ado.Connection.Close(); + } + } + + /// + ///DataTable to CSV + /// + /// datatable + /// CSV + public string DataTableToCsvString(DataTable table) + { + if (table.Rows.Count == 0) + return ""; + StringBuilder sb = new StringBuilder(); + DataColumn colum; + foreach (DataRow row in table.Rows) + { + for (int i = 0; i < table.Columns.Count; i++) + { + colum = table.Columns[i]; + if (i != 0) sb.Append(','); + if (colum.DataType == typeof(string) && (row[colum].ToString().Contains(',') || row[colum].ToString().Contains('\r') || row[colum].ToString().Contains('"') || row[colum].ToString().Contains('\n'))) + { + sb.Append('\"' + row[colum].ToString().Replace("\"", "\"\"") + '\"'); + } + else if (colum.DataType == typeof(bool)) + { + if (row[colum] == DBNull.Value) + { + sb.Append("NULL"); + } + else + { + sb.Append(row[colum].ObjToBool() ? 1 : 0); + } + } + else if (colum.DataType == UtilConstants.DateType && row[colum] != null && row[colum] != DBNull.Value) + { + sb.Append(row[colum].ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff")); + } + else if (row[colum] == null || row[colum] == DBNull.Value) + { + sb.Append("NULL"); + } + else sb.Append(row[colum].ToString()); + } + sb.AppendLine(); + } + return sb.ToString(); + } + + + private static object GetValue(PropertyInfo p, T item) + { + var result = p.GetValue(item, null); + if (result != null && UtilMethods.GetUnderType(p.PropertyType) == UtilConstants.BoolType) + { + if (result.ObjToBool() == false) + { + result = null; + } + } + return result; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlBuilder.cs new file mode 100644 index 000000000..1f1b933a2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlBuilder.cs @@ -0,0 +1,35 @@ +namespace SqlSugar +{ + public class MySqlBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft { get { return "`"; } } + public override string SqlTranslationRight { get { return "`"; } } + public override string SqlDateNow + { + get + { + return "NOW(6)"; + } + } + public override string FullSqlDateNow + { + get + { + return "select NOW(6)"; + } + } + public override string GetUnionFomatSql(string sql) + { + return " ( " + sql + " ) "; + } + + public override string RemoveParentheses(string sql) + { + if (sql.Contains(" ORDER BY") && sql.StartsWith('(') && sql.EndsWith(')') && !sql.Contains("limit", StringComparison.CurrentCultureIgnoreCase)) + { + sql = $" {sql.TrimEnd(')')} limit 0,{int.MaxValue}) "; + } + return sql; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlDeleteBuilder.cs new file mode 100644 index 000000000..97189bcab --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class MySqlDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlExpressionContext.cs new file mode 100644 index 000000000..f4633548e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlExpressionContext.cs @@ -0,0 +1,332 @@ +namespace SqlSugar +{ + public class MySqlExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public MySqlExpressionContext() + { + base.DbMehtods = new MySqlMethod(); + } + public override string SqlTranslationLeft { get { return "`"; } } + public override string SqlTranslationRight { get { return "`"; } } + } + public class MySqlMethod : DefaultDbMethod, IDbMethods + { + public override string JsonArrayLength(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return $" JSON_LENGTH({parameter.MemberName}) "; + } + + public override string JsonIndex(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"JSON_UNQUOTE(JSON_EXTRACT({parameter.MemberName}, '$[{parameter1.MemberValue}]'))"; + } + public override string WeekOfYear(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" WEEK({parameterNameA}) "; + } + public override string GetStringJoinSelector(string result, string separator) + { + return $"group_concat({result} separator '{separator}') "; + } + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" TIMESTAMPDIFF({0},{1},{2}) ", parameter.MemberValue?.ToString().ToSqlFilter(), parameter2.MemberName, parameter3.MemberName); + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + if (parameter.MemberName != null && parameter.MemberName is DateTime) + { + if (parameter2.MemberValue?.ToString() == DateType.Weekday.ToString()) + { + return string.Format(" case when {0}('{1}')=6 then 0 else ({0}('{1}')+1) end ", parameter2.MemberValue, parameter.MemberName); + } + else + { + return string.Format(" {0}('{1}') ", parameter2.MemberValue, parameter.MemberName); + } + } + else + { + if (parameter2.MemberValue?.ToString() == DateType.Weekday.ToString()) + { + return string.Format(" case when {0}({1})=6 then 0 else ({0}({1})+1) end ", parameter2.MemberValue, parameter.MemberName); + } + else + { + return string.Format(" {0}({1}) ", parameter2.MemberValue, parameter.MemberName); + } + } + } + + public override string Contains(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string StartsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat({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 concat('%',{1}))", parameter.MemberName, parameter2.MemberName); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" (TIMESTAMPDIFF(day,date({0}),date({1}))=0) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter3.MemberValue.ObjToString() == DateType.Weekday.ObjToString()) + { + parameter3.MemberValue = "Week"; + } + if (parameter3.MemberValue.ObjToString() == DateType.Month.ObjToString()) + { + return string.Format(" (DATE_FORMAT({0}, '%Y%m') = DATE_FORMAT({1}, '%Y%m')) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + else if (parameter3.MemberValue.ObjToString() == DateType.Year.ObjToString()) + { + return string.Format(" (DATE_FORMAT({0}, '%Y') = DATE_FORMAT({1}, '%Y')) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + else if (parameter3.MemberValue.ObjToString() == DateType.Day.ObjToString()) + { + return string.Format(" (DATE_FORMAT({0}, '%Y-%m-%d') = DATE_FORMAT({1}, '%Y-%m-%d')) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + else if (parameter3.MemberValue.ObjToString() == DateType.Hour.ObjToString()) + { + return string.Format(" (DATE_FORMAT({0}, '%Y-%m-%d %H') = DATE_FORMAT({1}, '%Y-%m-%d %H')) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + else if (parameter3.MemberValue.ObjToString() == DateType.Minute.ObjToString()) + { + return string.Format(" (DATE_FORMAT({0}, '%Y-%m-%d %H:%i') = DATE_FORMAT({1}, '%Y-%m-%d %H:%i')) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + else if (parameter3.MemberValue.ObjToString() == DateType.Second.ObjToString()) + { + return string.Format(" (DATE_FORMAT({0}, '%Y-%m-%d %H:%i:%S') = DATE_FORMAT({1}, '%Y-%m-%d %H:%i:%S')) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + return string.Format(" (TIMESTAMPDIFF({2},{0},{1})=0) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter3.MemberValue.ObjToString() == "Millisecond") + { + parameter3.MemberValue = "Second"; + return string.Format(" (DATE_ADD({1} , INTERVAL {2}/1000 {0})) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName); + } + return string.Format(" (DATE_ADD({1} , INTERVAL {2} {0})) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" (DATE_ADD({0}, INTERVAL {1} day)) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS SIGNED)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS SIGNED)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS CHAR)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS CHAR)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS SIGNED)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string MergeString(params string[] strings) + { + return " concat(" + string.Join(",", strings) + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + if (parameter1.MemberValue is bool) + { + return string.Format("IFNULL(CAST({0} as SIGNED),{1})", parameter.MemberName, parameter1.MemberName); + } + else + { + return string.Format("IFNULL({0},{1})", parameter.MemberName, parameter1.MemberName); + } + } + public override string GetDate() + { + return "NOW(6)"; + } + + public override string GetRandom() + { + return "rand()"; + } + + public override string Collate(MethodCallExpressionModel model) + { + var name = model.Args[0].MemberName; + return $" binary {name} "; + } + + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format("instr ({0},{1})", model.Args[0].MemberName, model.Args[1].MemberName); + } + + public override string JsonField(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + //var parameter2 = model.Args[2]; + //var parameter3= model.Args[3]; + var result = GetJson(parameter.MemberName, parameter1.MemberValue, model.Args.Count == 2); + if (model.Args.Count > 2) + { + result = GetJson(result, model.Args[2].MemberValue, model.Args.Count == 3); + } + if (model.Args.Count > 3) + { + result = GetJson(result, model.Args[3].MemberValue, model.Args.Count == 4); + } + if (model.Args.Count > 4) + { + result = GetJson(result, model.Args[4].MemberValue, model.Args.Count == 5); + } + if (model.Args.Count > 5) + { + result = GetJson(result, model.Args[5].MemberValue, model.Args.Count == 6); + } + return result; + } + + private string GetJson(object memberName1, object memberName2, bool isLast) + { + if (memberName1?.ToString()?.Contains("->") == true) + { + return $"{memberName1.ToString().TrimEnd('\'')}.{memberName2}'"; + } + else + { + return $"{memberName1}->'$.{memberName2}'"; + } + } + + public override string JsonArrayAny(MethodCallExpressionModel model) + { + if (model.Args[1].MemberValue == null) + { + return $" JSON_CONTAINS({model.Args[0].MemberName}, JSON_QUOTE({model.Args[1].MemberName}) )"; + } + else if (UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name)) + { + return $" JSON_CONTAINS({model.Args[0].MemberName}, '{model.Args[1].MemberValue}')"; + } + else + { + return $" JSON_CONTAINS({model.Args[0].MemberName}, '\"{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"')"; + } + } + public override string JsonListObjectAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) + { + return $" JSON_CONTAINS({model.Args[0].MemberName},'{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}')"; + } + else + { + return $" JSON_CONTAINS({model.Args[0].MemberName},'{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}')"; + } + } + public override string NewUid(MethodCallExpressionModel mode) + { + return " CONCAT(\r\n LPAD(UPPER(HEX(FLOOR(UUID_SHORT() / 0x100000000))), 8, '0'),\r\n '-',\r\n LPAD(UPPER(HEX(FLOOR(UUID_SHORT() / 0x10000) & 0xFFFF)), 4, '0'),\r\n '-',\r\n LPAD(UPPER(HEX(FLOOR(UUID_SHORT() / 0x100) & 0xFFFF)), 4, '0'),\r\n '-',\r\n LPAD(UPPER(HEX(UUID_SHORT() & 0xFF)), 4, '0'),\r\n '-000000000000'\r\n ) "; + } + //public override string TrimEnd(MethodCallExpressionModel mode) + //{ + // var parameterNameA = mode.Args[0].MemberName; + // var parameterNameB = mode.Args[1].MemberName; + // return $" TRIM(TRAILING {parameterNameA} FROM {parameterNameB}) "; + //} + //public override string TrimStart(MethodCallExpressionModel mode) + //{ + + // var parameterNameA = mode.Args[0].MemberName; + // var parameterNameB = mode.Args[1].MemberName; + // return $" TRIM(LEADING {parameterNameA} FROM {parameterNameB}) "; + //} + public override string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = string.Join(",", mode.Args[0].MemberValue as List); + } + var searchWord = mode.Args[1].MemberName; + return $" MATCH({columns}) AGAINST({searchWord}) "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlFastBuilder.cs new file mode 100644 index 000000000..c3a588272 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlFastBuilder.cs @@ -0,0 +1,105 @@ +using MySqlConnector; + +using System.Data; +using System.Text; + +namespace SqlSugar +{ + + public partial class MySqlFastBuilder : FastBuilder, IFastBuilder + { + public override string UpdateSql { get; set; } = @"UPDATE {1} TM INNER JOIN {2} TE ON {3} SET {0} "; + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + if (dt.Columns.Cast().Any(it => it.DataType == UtilConstants.ByteArrayType)) + { + return await MySqlConnectorBulkCopy(dt).ConfigureAwait(false); + } + var dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bulkcopyfiles"); + if (StaticConfig.BulkCopy_MySqlCsvPath.HasValue()) + { + dllPath = StaticConfig.BulkCopy_MySqlCsvPath; + } + DirectoryInfo dir = new DirectoryInfo(dllPath); + if (!dir.Exists) + { + dir.Create(); + } + var fileName = Path.Combine(dllPath, Guid.NewGuid().ToString() + ".csv"); + var dataTableToCsv = new MySqlBlukCopy(this.Context.Context, null, null).DataTableToCsvString(dt); + File.WriteAllText(fileName, dataTableToCsv, new UTF8Encoding(false)); + MySqlConnection conn = this.Context.Ado.Connection as MySqlConnection; + int result = 0; + try + { + this.Context.Ado.Open(); + // IsolationLevel.Parse + MySqlBulkLoader bulk = new MySqlBulkLoader(conn) + { + CharacterSet = "utf8mb4", + FieldTerminator = ",", + FieldQuotationCharacter = '"', + EscapeCharacter = '"', + LineTerminator = Environment.NewLine, + FileName = fileName, + NumberOfLinesToSkip = 0, + TableName = dt.TableName, + Local = true, + }; + if (this.CharacterSet.HasValue()) + { + bulk.CharacterSet = this.CharacterSet; + } + bulk.Columns.AddRange(dt.Columns.Cast().Select(colum => new MySqlBuilder().GetTranslationColumnName(colum.ColumnName)).Distinct().ToArray()); + result = await bulk.LoadAsync().ConfigureAwait(false); + //执行成功才删除文件 + if (File.Exists(fileName)) + { + File.Delete(fileName); + } + } + catch (Exception ex) + { + if (ex.Message == "The used command is not allowed with this MySQL version") + { + Check.ExceptionEasy("connection string add : AllowLoadLocalInfile=true", "BulkCopy MySql连接字符串需要添加 AllowLoadLocalInfile=true; 添加后如果还不行Mysql数据库执行一下 SET GLOBAL local_infile=1 "); + } + else if (ex.Message.Contains("To use MySqlBulkLoader.Local=true, set Allo")) + { + Check.ExceptionEasy("connection string add : AllowLoadLocalInfile=true", "BulkCopy MySql连接字符串需要添加 AllowLoadLocalInfile=true; 添加后如果还不行Mysql数据库执行一下 SET GLOBAL local_infile=1 "); + } + else if (ex.Message == "Loading local data is disabled; this must be enabled on both the client and server sides") + { + this.Context.Ado.ExecuteCommand("SET GLOBAL local_infile=1"); + Check.ExceptionEasy(ex.Message, " 检测到你没有开启文件,AllowLoadLocalInfile=true加到自符串上,已自动执行 SET GLOBAL local_infile=1 在试一次"); + } + else + { + throw; + } + } + finally + { + CloseDb(); + } + return result; + } + public override async Task CreateTempAsync(DataTable dt) + { + var queryable = this.Context.Queryable(); + var tableName = queryable.SqlBuilder.GetTranslationTableName(dt.TableName); + dt.TableName = "temp" + SnowFlakeSingle.instance.getID(); + var sql = string.Empty; + if (dt.Columns.Cast().Any(it => it.DataType == UtilConstants.ByteArrayType)) + { + sql = queryable.AS(tableName).Where(it => false) + .Select(string.Join(",", dt.Columns.Cast().Select(it => queryable.SqlBuilder.GetTranslationTableName(it.ColumnName)))).ToSql().Key; + } + else + { + sql = queryable.AS(tableName).Where(it => false).ToSql().Key; + } + await Context.Ado.ExecuteCommandAsync($"Create TEMPORARY table {dt.TableName}({sql}) ").ConfigureAwait(false); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlInsertBuilder.cs new file mode 100644 index 000000000..b919c5549 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlInsertBuilder.cs @@ -0,0 +1,191 @@ +using System.Globalization; +using System.Text; + +namespace SqlSugar +{ + public class MySqlInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;SELECT LAST_INSERT_ID();"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + int i = 0; + public object FormatValue(object value, string name) + { + var n = "N"; + if (this.Context.CurrentConnectionConfig.MoreSettings?.DisableNvarchar == true) + { + n = ""; + } + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + return GetDateTimeString(value); + } + else if (value is DateTimeOffset) + { + return GetDateTimeOffsetString(value); + } + else if (value is decimal decValue) + { + return decValue.ToString(CultureInfo.InvariantCulture); + } + else if (value is double douValue) + { + return douValue.ToString(CultureInfo.InvariantCulture); + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + Convert.ToHexString((byte[])value); + if (bytesString == "0x") + { + bytesString = "''"; + } + 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 if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + ++i; + var parameterName = this.Builder.SqlParameterKeyWord + name + "_" + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else + { + return n + "'" + GetString(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") + "'"; + } + + private string GetString(object value) + { + var result = value.ToString(); + if (result.HasValue() && result.Contains('\\')) + { + result = result.Replace("\\", "\\\\"); + } + 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))); + ActionMinDate(); + var result = string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + result = GetMySqlIgnore(result); + return result; + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + batchInsetrSql.Append("INSERT INTO " + GetTableNameString + " "); + batchInsetrSql.Append('('); + batchInsetrSql.Append(columnsString); + batchInsetrSql.Append(") VALUES"); + string insertColumns = ""; + foreach (var item in groupList) + { + batchInsetrSql.Append('('); + insertColumns = string.Join(",", item.Select(it => base.GetDbColumn(it, FormatValue(it.Value, it.PropertyName)))); + batchInsetrSql.Append(insertColumns); + if (groupList.Last() == item) + { + batchInsetrSql.Append(") "); + } + else + { + batchInsetrSql.Append("), "); + } + } + if (DorisHelper.IsDoris(this.Context)) + { + //doris insert ignore + } + else + { + batchInsetrSql.AppendLine(";select @@IDENTITY"); + } + var result = batchInsetrSql.ToString(); + result = GetMySqlIgnore(result); + return result; + } + } + + private string GetMySqlIgnore(string result) + { + if (this.MySqlIgnore) + { + result = result.Replace("INSERT INTO", " INSERT IGNORE INTO"); + } + + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlQueryBuilder.cs new file mode 100644 index 000000000..2f0723dab --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlQueryBuilder.cs @@ -0,0 +1,165 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class MySqlQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 0,10 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {5},{6}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override bool IsComplexModel(string sql) + { + return 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]; + var maxLongValue = long.MaxValue; + if (this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.OceanBase) + { + maxLongValue = Convert.ToInt64(maxLongValue / 2.0); + } + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt(), maxLongValue); + } + 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 NOW() ") + { + 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.Count != 0) + { + result = SubToListMethod(result); + } + return result; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlUpdateBuilder.cs new file mode 100644 index 000000000..d27ab07d6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/MySql/SqlBuilder/MySqlUpdateBuilder.cs @@ -0,0 +1,231 @@ +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class MySqlUpdateBuilder : UpdateBuilder + { + public override string SqlTemplateBatch + { + get + { + return @"UPDATE {1} S {2} INNER JOIN ${{0}} SET {0} "; + } + } + public override string SqlTemplateJoin + { + get + { + return @" ( + {0} + + ) T ON {1} + "; + } + } + protected override string GetJoinUpdate(string columnsString, ref string whereString) + { + var joinString = $" {Builder.GetTranslationColumnName(this.TableName)} {Builder.GetTranslationColumnName(this.ShortName)} "; + foreach (var item in this.JoinInfos) + { + joinString += $"\r\n JOIN {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} ON {item.JoinWhere} "; + } + var tableName = joinString + "\r\n "; + return string.Format(SqlTemplate, tableName, columnsString, whereString); + } + protected override string TomultipleSqlString(List> groupList) + { + Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List need Primary key"); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + StringBuilder batchUpdateSql = new StringBuilder(); + while (pageCount >= pageIndex) + { + StringBuilder updateTable = new StringBuilder(); + string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName)); + return result; + })); + batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString); + int i = 0; + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) + { + updateTable.Append(SqlTemplateBatchUnion); + } + updateTable.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, base.GetDbColumn(it, FormatValue(it.Value, it.PropertyName)), this.Builder.GetTranslationColumnName(it.DbColumnName))))); + ++i; + } + pageIndex++; + updateTable.Append("\r\n"); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += Regex.Replace(item, " \\" + this.Builder.SqlTranslationLeft, "S." + this.Builder.SqlTranslationLeft); + } + } + if (PrimaryKeys.HasValue()) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(item)); + } + } + var format = string.Format(SqlTemplateJoin, updateTable, whereString); + batchUpdateSql.Replace("${0}", format); + batchUpdateSql.Append(';'); + } + batchUpdateSql = GetBatchUpdateSql(batchUpdateSql); + return batchUpdateSql.ToString(); + } + + private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql) + { + if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null) + { + var result = batchUpdateSql.ToString(); + foreach (var item in ReSetValueBySqlExpList) + { + var dbColumnName = item.Value.DbColumnName; + if (item.Value.Type == ReSetValueBySqlExpListModelType.List) + { + result = result.Replace($"T.{dbColumnName}", "S." + dbColumnName + item.Value.Sql + "T." + dbColumnName); + } + else + { + result = result.Replace($"T.{dbColumnName}", item.Value.Sql.Replace(dbColumnName, "S." + dbColumnName)); + } + batchUpdateSql = new StringBuilder(result); + } + } + + return batchUpdateSql; + } + int i = 0; + public object FormatValue(object value, string name) + { + var n = "N"; + if (this.Context.CurrentConnectionConfig.MoreSettings?.DisableNvarchar == true) + { + n = ""; + } + if (value == null) + { + return "NULL"; + } + else + { + 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" + Convert.ToHexString((byte[])value); + if (bytesString == "0x") + { + bytesString = "''"; + } + 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.LongType) + { + return GetString(value); + } + else if (type == UtilConstants.IntType) + { + return GetString(value); + } + else if (value is decimal decValue) + { + return decValue.ToString(CultureInfo.InvariantCulture); + } + else if (value is double douValue) + { + return douValue.ToString(CultureInfo.InvariantCulture); + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + ++i; + var parameterName = this.Builder.SqlParameterKeyWord + name + "_" + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else + { + return n + "'" + GetString(value) + "'"; + } + } + } + + 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") + "'"; + } + + 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 string GetString(object value) + { + var result = value.ToString(); + if (result.HasValue() && result.Contains('\\')) + { + result = result.Replace("\\", "\\\\"); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs new file mode 100644 index 000000000..f157d3ab8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs @@ -0,0 +1,63 @@ +namespace SqlSugar +{ + public class OracleCodeFirst : CodeFirstProvider + { + public OracleCodeFirst() + { + if (DefultLength == 0) + DefultLength = 40; + } + protected override int DefultLength { get; set; } + + protected override void GetDbType(EntityColumnInfo item, Type propertyType, DbColumnInfo result) + { + if (!string.IsNullOrEmpty(item.DataType)) + { + result.DataType = item.DataType; + } + else if (item.DataType == null && item.UnderType == UtilConstants.LongType) + { + result.Length = 0; + result.DecimalDigits = 0; + result.DataType = "NUMBER(19,0)"; + } + else if (item.DataType == null && item.UnderType == UtilConstants.BoolType) + { + result.Length = 0; + result.DecimalDigits = 0; + result.DataType = "NUMBER(1,0)"; + } + //else if (item.DataType == null && item.UnderType == UtilConstants.IntType) + //{ + // result.Length = 0; + // result.DecimalDigits = 0; + // result.DataType = "NUMBER(9,0)"; + //} + else if (propertyType.IsEnum()) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(item.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name); + } + else + { + if (propertyType.Name.Equals("Guid", StringComparison.CurrentCultureIgnoreCase)) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(UtilConstants.StringType.Name); + if (result.Length <= 1) + { + result.Length = 36; + } + } + else + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(propertyType.Name); + } + } + } + + protected override void KeyAction(EntityColumnInfo item, DbColumnInfo dbColumn, out bool pkDiff, out bool idEntityDiff) + { + pkDiff = item.IsPrimarykey != dbColumn.IsPrimarykey; + idEntityDiff = false; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbBind/OracleDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbBind/OracleDbBind.cs new file mode 100644 index 000000000..47deba041 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbBind/OracleDbBind.cs @@ -0,0 +1,136 @@ +namespace SqlSugar +{ + public class OracleDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "blob"; + if (csharpTypeName.Equals("int32", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "int"; + if (csharpTypeName.Equals("int16", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "short"; + if (csharpTypeName.Equals("int64", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "long"; + if (csharpTypeName.ToLower().IsIn("boolean", "bool")) + csharpTypeName = "bool"; + if (csharpTypeName == "Guid") + csharpTypeName = "string"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)); + return mappings.HasValue() ? mappings.First().Key : "varchar"; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (dbTypeName == "int32") + { + return "int"; + } + else if (dbTypeName == "int64") + { + return "long"; + } + else if (dbTypeName == "int16") + { + return "short"; + } + else if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "xml" || dbTypeName == "string") + { + return "string"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes?.Any() != true) + { + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>() + { + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("interval year to month",CSharpDataType.@int), + new KeyValuePair("interval day to second",CSharpDataType.TimeSpan), + new KeyValuePair("intervalds",CSharpDataType.TimeSpan), + + new KeyValuePair("number",CSharpDataType.@int), + new KeyValuePair("number",CSharpDataType.@float), + new KeyValuePair("number",CSharpDataType.@short), + new KeyValuePair("number",CSharpDataType.@byte), + new KeyValuePair("number",CSharpDataType.@double), + new KeyValuePair("binaryfloat",CSharpDataType.@float), + new KeyValuePair("binarydouble",CSharpDataType.@double), + new KeyValuePair("number",CSharpDataType.@long), + new KeyValuePair("number",CSharpDataType.@bool), + new KeyValuePair("number",CSharpDataType.@decimal), + new KeyValuePair("number",CSharpDataType.Single), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("decimal",CSharpDataType.Single), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("varchar2",CSharpDataType.@string), + new KeyValuePair("nvarchar2",CSharpDataType.@string), + new KeyValuePair("xmltype",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("nchar",CSharpDataType.@string), + new KeyValuePair("clob",CSharpDataType.@string), + new KeyValuePair("long",CSharpDataType.@string), + new KeyValuePair("nclob",CSharpDataType.@string), + new KeyValuePair("rowid",CSharpDataType.@string), + + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("timestamptz",CSharpDataType.DateTime), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("timestamp with local time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + + new KeyValuePair("float",CSharpDataType.@decimal), + + new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("long raw",CSharpDataType.byteArray), + new KeyValuePair("longraw",CSharpDataType.byteArray), + new KeyValuePair("raw",CSharpDataType.byteArray), + new KeyValuePair("bfile",CSharpDataType.byteArray), + new KeyValuePair("varbinary",CSharpDataType.byteArray) }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbFirst/OracleDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbFirst/OracleDbFirst.cs new file mode 100644 index 000000000..8ae9f9760 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbFirst/OracleDbFirst.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class OracleDbFirst : DbFirstProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs new file mode 100644 index 000000000..23a5320f0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs @@ -0,0 +1,702 @@ +using System.Data; +using System.Data.Common; + +namespace SqlSugar +{ + public class OracleDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string GetTableInfoListSql + { + get + { + return @"SELECT table_name name , + (select COMMENTS from user_tab_comments where t.table_name=table_name ) as Description + + from user_tables t where + table_name!='HELP' + AND table_name NOT LIKE '%$%' + AND table_name NOT LIKE 'LOGMNRC_%' + AND table_name!='LOGMNRP_CTAS_PART_MAP' + AND table_name!='LOGMNR_LOGMNR_BUILDLOG' + AND table_name!='SQLPLUS_PRODUCT_PROFILE' + "; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select view_name name from user_views + WHERE VIEW_name NOT LIKE '%$%' + AND VIEW_NAME !='PRODUCT_PRIVS' + AND VIEW_NAME NOT LIKE 'MVIEW_%' "; + } + } + #endregion + + #region DDL + protected override string IsAnyIndexSql + { + get + { + return "SELECT NVL2((SELECT INDEX_NAME FROM ALL_INDEXES WHERE INDEX_NAME=UPPER('{0}') AND OWNER = USER ),1,0)+NVL2((SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE CONSTRAINT_NAME=UPPER('{0}') AND OWNER = USER),2,0) AS ROWCOUNT FROM DUAL"; + } + } + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0}({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} MODIFY({1} DEFAULT '{2}')"; + } + } + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY({2})"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD ({1} {2}{3} {4} {5} {6})"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "ALTER TABLE {0} modify ({1} {2}{3} {4} {5} {6}) "; + } + } + protected override string BackupDataBaseSql + { + get + { + return @"USE master;BACKUP DATABASE {0} TO disk = '{1}'"; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1})"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {1} as select * from {2} where ROWNUM<={0}"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} rename column {1} to {2}"; + } + } + protected override string AddColumnRemarkSql + { + get + { + return "comment on column {1}.{0} is '{2}'"; + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + return "comment on column {1}.{0} is ''"; + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + return "select * from user_col_comments where Table_Name='{1}' AND COLUMN_NAME='{0}' order by column_name"; + } + } + + protected override string AddTableRemarkSql + { + get + { + return "comment on table {0} is '{1}'"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "comment on table {0} is ''"; + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + return "select * from user_tab_comments where Table_Name='{0}'order by Table_Name"; + } + } + + protected override string RenameTableSql + { + get + { + return "alter table {0} rename to {1}"; + } + } + protected override string IsAnyProcedureSql + { + get + { + return "SELECT COUNT(*) FROM user_objects WHERE OBJECT_TYPE = 'PROCEDURE' AND OBJECT_NAME ='{0}'"; + } + } + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select t.table_name from user_tables t where rownum=1"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return " NULL "; + } + } + protected override string CreateTableNotNull + { + get + { + return " NOT NULL "; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return ""; + } + } + #endregion + + #region Methods + public override bool IsAnyTable(string tableName, bool isCache = true) + { + if (isCache) + { + return base.IsAnyTable(tableName, isCache); + } + else + { + if (tableName.Contains('"')) + { + tableName = SqlBuilder.GetNoTranslationColumnName(tableName); + } + return this.Context.Ado.GetInt(@" + SELECT COUNT(table_name) + FROM user_tables + WHERE UPPER(table_name) = UPPER(@p)", new { p = tableName }) > 0; + } + } + public override bool UpdateColumn(string tableName, DbColumnInfo column) + { + ConvertCreateColumnInfo(column); + var oldColumn = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName, false) + .FirstOrDefault(it => it.DbColumnName.EqualCase(column.DbColumnName)); + if (oldColumn != null) + { + if (oldColumn.IsNullable == column.IsNullable) + { + var sql = GetUpdateColumnSqlOnlyType(tableName, column); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + } + return base.UpdateColumn(tableName, column); + } + protected virtual string GetUpdateColumnSqlOnlyType(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + public override bool RenameTable(string oldTableName, string newTableName) + { + return base.RenameTable(SqlBuilder.GetTranslationColumnName(oldTableName), SqlBuilder.GetTranslationColumnName(newTableName)); + } + public override List GetDbTypes() + { + var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT DATA_TYPE +FROM DBA_TAB_COLUMNS +WHERE OWNER = user "); + result.Add("TIMESTAMP"); + result.Add("NCLOB"); + return result.Distinct().ToList(); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT trigger_name +FROM all_triggers +WHERE table_name = '" + tableName + "'"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery(" SELECT object_name\r\nFROM all_objects\r\nWHERE object_type = 'FUNCTION' AND owner = USER "); + } + public override List GetIndexList(string tableName) + { + var sql = $"SELECT index_name FROM user_ind_columns\r\nWHERE upper(table_name) = upper('{tableName}')"; + return this.Context.Ado.SqlQuery(sql).Distinct().ToList(); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OBJECT_TYPE = 'PROCEDURE' AND OWNER =user "; + return this.Context.Ado.SqlQuery(sql); + } + public override bool AddColumn(string tableName, DbColumnInfo columnInfo) + { + if (columnInfo.DataType == "varchar" && columnInfo.Length == 0) + { + columnInfo.DataType = "varchar2"; + columnInfo.Length = 50; + } + ConvertCreateColumnInfo(columnInfo); + return base.AddColumn(tableName, columnInfo); + } + public override bool CreateIndex(string tableName, string[] columnNames, bool isUnique = false) + { + string sql = string.Format(CreateIndexSql, tableName, string.Join(",", columnNames), string.Join("_", columnNames.Select(it => (it + "abc").Substring(0, 3))), isUnique ? "UNIQUE" : ""); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + columnName = SqlBuilder.GetTranslationColumnName(columnName); + tableName = SqlBuilder.GetTranslationColumnName(tableName); + + if (defaultValue == "''") + { + defaultValue = ""; + } + if (defaultValue.ToLower().IsIn("sysdate")) + { + var template = AddDefaultValueSql.Replace("'", ""); + string sql = string.Format(template, tableName, columnName, defaultValue); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + else + { + return base.AddDefaultValue(tableName, columnName, defaultValue); + } + } + public override bool CreateDatabase(string databaseDirectory = null) + { + if (this.Context.Ado.IsValidConnection()) + { + return true; + } + Check.ExceptionEasy("Oracle no support create database ", "Oracle不支持建库方法,请写有效连接字符串可以正常运行该方法。"); + return true; + } + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + if (this.Context.Ado.IsValidConnection()) + { + return true; + } + Check.ExceptionEasy("Oracle no support create database ", "Oracle不支持建库方法,请写有效连接字符串可以正常运行该方法。"); + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + //column remak + if (db.DbMaintenance.IsAnyColumnRemark(item.DbColumnName.ToUpper(IsUppper), item.DbTableName.ToUpper(IsUppper))) + { + db.DbMaintenance.DeleteColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), this.SqlBuilder.GetTranslationColumnName(item.DbTableName)); + db.DbMaintenance.AddColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), this.SqlBuilder.GetTranslationColumnName(item.DbTableName), item.ColumnDescription); + } + else + { + db.DbMaintenance.AddColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), this.SqlBuilder.GetTranslationColumnName(item.DbTableName), item.ColumnDescription); + } + } + } + + //table remak + if (entity.TableDescription != null) + { + if (db.DbMaintenance.IsAnyTableRemark(entity.DbTableName)) + { + db.DbMaintenance.DeleteTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName)); + db.DbMaintenance.AddTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName), entity.TableDescription); + } + else + { + db.DbMaintenance.AddTableRemark(SqlBuilder.GetTranslationColumnName(entity.DbTableName), entity.TableDescription); + } + } + return true; + } + 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) + { + List columns = GetOracleDbType(tableName); + string sql = "select * /* " + Guid.NewGuid() + " */ from " + SqlBuilder.GetTranslationTableName(SqlBuilder.GetNoTranslationColumnName(tableName)) + " WHERE 1=2 "; + if (!IsAnyTable(tableName, false) && !GetViewInfoList(false).Any(it => it.Name.EqualCase(tableName))) + { + return new List(); + } + 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 (DbDataReader reader = (DbDataReader)this.Context.Ado.GetDataReader(sql)) + { + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + List result = new List(); + var schemaTable = reader.GetSchemaTable(); + 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 = GetPrimaryKeyByTableNames(tableName).Any(it => it.Equals(row["ColumnName"].ToString(), StringComparison.CurrentCultureIgnoreCase)), + Length = row["ColumnSize"].ObjToInt(), + Scale = row["numericscale"].ObjToInt() + }; + var current = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(column.DbColumnName)); + if (current != null) + { + column.OracleDataType = current.DataType; + if (current.DataType.EqualCase("number")) + { + column.Length = row["numericprecision"].ObjToInt(); + column.Scale = row["numericscale"].ObjToInt(); + column.DecimalDigits = row["numericscale"].ObjToInt(); + if (column.Length == 38 && column.Scale == 0) + { + column.Length = 22; + } + } + if (current.DefaultValue != null) + { + column.DefaultValue = current.DefaultValue.TrimEnd('\'').TrimStart('\''); + } + } + result.Add(column); + } + return result; + } + } + + private List GetOracleDbType(string tableName) + { + var sql0 = $@"select + t1.table_name as TableName, + t6.comments, + t1.column_id, + t1.column_name as DbColumnName, + t5.comments, + t1.data_type as DataType, + t1.data_length as Length, + t1.char_length, + t1.data_precision, + t1.data_scale, + t1.nullable, + t1.data_default as DefaultValue, + t4.index_name, + t4.column_position, + t4.descend + from user_tab_columns t1 + left join (select t2.table_name, + t2.column_name, + t2.column_position, + t2.descend, + t3.index_name + from user_ind_columns t2 + left join user_indexes t3 + on t2.table_name = t3.table_name and t2.index_name = t3.index_name + and t3.status = 'valid' and t3.uniqueness = 'unique') t4 --unique:唯一索引 + on t1.table_name = t4.table_name and t1.column_name = t4.column_name + left join user_col_comments t5 on t1.table_name = t5.table_name and t1.column_name = t5.column_name + left join user_tab_comments t6 on t1.table_name = t6.table_name + where upper(t1.table_name)=upper('{tableName}') + order by t1.table_name, t1.column_id"; + + var columns = this.Context.Ado.SqlQuery(sql0); + return columns; + } + + private List GetPrimaryKeyByTableNames(string tableName) + { + string cacheKey = "DbMaintenanceProvider.GetPrimaryKeyByTableNames." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower(); + cacheKey = GetCacheKey(cacheKey); + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + string sql = @" select distinct cu.COLUMN_name KEYNAME from user_cons_columns cu, user_constraints au + where cu.constraint_name = au.constraint_name + and au.constraint_type = 'P' and au.table_name = '" + tableName.ToUpper(IsUppper) + @"'"; + var pks = this.Context.Ado.SqlQuery(sql); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return pks; + }); + } + + public string GetTableComment(string tableName) + { + string cacheKey = "DbMaintenanceProvider.GetTableComment." + tableName; + var comments = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + string sql = "SELECT COMMENTS FROM USER_TAB_COMMENTS WHERE TABLE_NAME =@tableName ORDER BY TABLE_NAME"; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var pks = this.Context.Ado.SqlQuery(sql, new { tableName = tableName.ToUpper(IsUppper) }); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return pks; + }); + return comments.HasValue() ? comments.First() : ""; + } + + public string GetFieldComment(string tableName, string filedName) + { + string cacheKey = "DbMaintenanceProvider.GetFieldComment." + tableName; + var comments = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + () => + { + string sql = "SELECT TABLE_NAME AS TableName, COLUMN_NAME AS DbColumnName,COMMENTS AS ColumnDescription FROM user_col_comments WHERE TABLE_NAME =@tableName ORDER BY TABLE_NAME"; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var pks = this.Context.Ado.SqlQuery(sql, new { tableName = tableName.ToUpper(IsUppper) }); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + return pks; + }); + return comments.HasValue() ? comments.FirstOrDefault(it => it.DbColumnName.EqualCase(filedName))?.ColumnDescription : ""; + + } + + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + ConvertCreateColumnInfo(item); + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + item.Length = 50; + } + if (item.DataType == "varchar" && item.Length == 0) + { + item.Length = 50; + } + if (item.IsIdentity && this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true) + { + item.DataType = "NUMBER GENERATED ALWAYS AS IDENTITY"; + } + if (item.DataType != null && this.Context.CurrentConnectionConfig?.MoreSettings?.OracleCodeFirstNvarchar2 == true) + { + if (!item.DataType.Contains("nvarchar2", StringComparison.CurrentCultureIgnoreCase)) + { + item.DataType = item.DataType.ToLower().Replace("varchar", "nvarchar2"); + } + } + } + } + string sql = GetCreateTableSql(tableName, columns); + this.Context.Ado.ExecuteCommand(sql); + if (isCreatePrimaryKey) + { + var pkColumns = columns.Where(it => it.IsPrimarykey).ToList(); + if (pkColumns.Count <= 1) + { + foreach (var item in pkColumns) + { + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + } + else + { + var addItems = pkColumns.Select(it => it.DbColumnName).ToArray(); + this.Context.DbMaintenance.AddPrimaryKeys(tableName, addItems); + } + } + return true; + } + public override bool IsAnyIndex(string indexName) + { + string sql = string.Format(this.IsAnyIndexSql, indexName); + return this.Context.Ado.GetInt(sql) == 1; + } + public override bool IsAnyConstraint(string constraintName) + { + string sql = string.Format(this.IsAnyIndexSql, constraintName); + int res = this.Context.Ado.GetInt(sql); + return res == 2 || res == 3; + } + public override bool DropIndex(string indexName, string tableName) + { + return DropIndex(indexName); + } + #endregion + + #region Helper + public bool IsUppper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + private static void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "int", "date", "clob", "nclob" }; + if (x.OracleDataType.HasValue()) + { + x.DataType = x.OracleDataType; + } + if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + if (x.DecimalDigits > 0 && x.DataType?.ToLower()?.IsIn("varchar", "clob", "varchar2", "nvarchar2", "nvarchar") == true) + { + x.DecimalDigits = 0; + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Deleteable/OracleDeleteable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Deleteable/OracleDeleteable.cs new file mode 100644 index 000000000..75112813c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Deleteable/OracleDeleteable.cs @@ -0,0 +1,10 @@ +namespace SqlSugar +{ + public class OracleDeleteable : DeleteableProvider where T : class, new() + { + protected override List GetIdentityKeys() + { + return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.DbColumnName).ToList(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Insertable/OracleInsertable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Insertable/OracleInsertable.cs new file mode 100644 index 000000000..ef89e87c0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Insertable/OracleInsertable.cs @@ -0,0 +1,219 @@ +using System.Text; + +namespace SqlSugar +{ + public class OracleInsertable : InsertableProvider where T : class, new() + { + + protected override List GetIdentityKeys() + { + return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.DbColumnName).ToList(); + } + protected string GetSeqName() + { + return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.OracleSequenceName).First(); + } + protected List GetSeqNames() + { + return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.OracleSequenceName).ToList(); + } + public override int ExecuteReturnIdentity() + { + bool oldIsAuto = AutoBegin(); + + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString(); + if (isIdEntityEnable()) + { + if (sql?.StartsWith("INSERT ALL") == true) + { + return this.UseParameter().ExecuteCommand(); + } + else + { + sql = sql + " RETURNING ID INTO :newId01 "; + } + InsertBuilder.Parameters.Add(new SugarParameter(":newId01", 0, true)); + } + RestoreMapping(); + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var count = Ado.ExecuteCommand(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : GetSeqValue(GetSeqName()).ObjToInt(); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + After(sql, result); + AutoEnd(oldIsAuto); + if (isIdEntityEnable()) + { + return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToInt() ?? 0; + } + return result; + } + private bool isIdEntityEnable() + { + return this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true; + } + + public override long ExecuteReturnBigIdentity() + { + bool oldIsAuto = AutoBegin(); + + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString(); + if (isIdEntityEnable()) + { + if (sql?.StartsWith("INSERT ALL") == true) + { + return this.UseParameter().ExecuteCommand(); + } + else + { + sql = sql + " RETURNING ID INTO :newId01 "; + } + InsertBuilder.Parameters.Add(new SugarParameter(":newId01", Convert.ToInt64(0), true)); + } + RestoreMapping(); + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var count = Ado.ExecuteCommand(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : Convert.ToInt64(GetSeqValue(GetSeqName())); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + After(sql, result); + AutoEnd(oldIsAuto); + if (isIdEntityEnable()) + { + return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToLong() ?? 0; + } + return result; + } + + public async override Task ExecuteReturnIdentityAsync() + { + bool oldIsAuto = AutoBegin(); + + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString(); + if (isIdEntityEnable()) + { + if (sql?.StartsWith("INSERT ALL") == true) + { + return await UseParameter().ExecuteCommandAsync().ConfigureAwait(false); + } + else + { + sql = sql + " RETURNING ID INTO :newId01 "; + } + InsertBuilder.Parameters.Add(new SugarParameter(":newId01", 0, true)); + } + RestoreMapping(); + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var count = await Ado.ExecuteCommandAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : GetSeqValue(GetSeqName()).ObjToInt(); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + After(sql, result); + AutoEnd(oldIsAuto); + if (isIdEntityEnable()) + { + return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToInt() ?? 0; + } + return result; + } + + public async override Task ExecuteReturnBigIdentityAsync() + { + bool oldIsAuto = AutoBegin(); + + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString(); + if (isIdEntityEnable()) + { + if (sql?.StartsWith("INSERT ALL") == true) + { + return await UseParameter().ExecuteCommandAsync().ConfigureAwait(false); + } + else + { + sql = sql + " RETURNING ID INTO :newId01 "; + } + InsertBuilder.Parameters.Add(new SugarParameter(":newId01", Convert.ToInt64(0), true)); + } + RestoreMapping(); + var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation; + this.Context.Ado.IsDisableMasterSlaveSeparation = true; + var count = await Ado.ExecuteCommandAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : Convert.ToInt64(GetSeqValue(GetSeqName())); + this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + After(sql, result); + AutoEnd(oldIsAuto); + if (isIdEntityEnable()) + { + return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToLong() ?? 0; + } + return result; + } + + private void AutoEnd(bool oldIsAuto) + { + if (oldIsAuto) + { + this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection = oldIsAuto; + if (this.Ado.Transaction == null) + this.Context.Ado.Close(); + } + } + + private bool AutoBegin() + { + var oldIsAuto = this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection; + if (this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection) + { + this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection = false; + } + + return oldIsAuto; + } + private object GetSeqValue(string seqName) + { + return Ado.GetScalar(" SELECT " + seqName + ".currval FROM DUAL"); + } + protected override void PreToSql() + { + var identities = GetSeqNames(); + var insertCount = InsertObjs.Length; + InsertBuilder.OracleSeqInfoList = new Dictionary(); + if ((identities.HasValue() && insertCount > 1) || InsertBuilder.IsBlukCopy) + { + Check.Exception(identities.Count != identities.Distinct().Count(), "The field sequence needs to be unique"); + foreach (var seqName in identities) + { + int seqBeginValue = 0; + seqBeginValue = this.Ado.GetInt("select " + seqName + ".Nextval from dual"); + //Console.WriteLine(seqBeginValue); + var nextLength = insertCount - 1; + if (nextLength > 0) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine(" select " + seqName + ".nextval,t.* from ("); + for (int i = 0; i < nextLength; i++) + { + sb.AppendLine(" select 1 from dual"); + if (i < (nextLength - 1)) + { + sb.AppendLine("union all"); + } + } + sb.AppendLine(" )t"); + this.Ado.SqlQuery(sb.ToString()); + } + InsertBuilder.OracleSeqInfoList.Add(seqName, seqBeginValue); + } + } + base.PreToSql(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/OracleProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/OracleProvider.cs new file mode 100644 index 000000000..000310789 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/OracleProvider.cs @@ -0,0 +1,341 @@ +using Oracle.ManagedDataAccess.Client; + +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public class OracleProvider : AdoProvider + { + public OracleProvider() + { + //this.FormatSql = sql => + //{ + // sql = sql.Replace("+@", "+:"); + // if (sql.HasValue()&&sql.Contains('@')) { + // var exceptionalCaseInfo = Regex.Matches(sql, @"\'[^\=]*?\@.*?\'|[\.,\w]+\@[\.,\w]+ | [\.,\w]+\@[\.,\w]+|[\.,\w]+\@[\.,\w]+ |\d+\@\d|\@\@|\w{1,25}\.""\w{1,25}""\@\w{1,25}"); + // if (exceptionalCaseInfo != null) { + // foreach (var item in exceptionalCaseInfo.Cast()) + // { + // if (item.Value != null && item.Value.IndexOf(",") == 1&&Regex.IsMatch(item.Value, @"^ \,\@\w+$")) + // { + // continue; + // } + // else if (item.Value != null &&Regex.IsMatch(item.Value.Trim(), @"^\w+\,\@\w+\,$")) + // { + // continue; + // } + // else if (item.Value != null && item.Value.ObjToString().Contains("||") && Regex.IsMatch(item.Value.Replace(" ","").Trim(), @"\|\|@\w+\|\|")) + // { + // continue; + // } + // else if (item.Value != null&& Regex.IsMatch(item.Value.Replace(" ", "").Trim(), @"\(\@\w+\,")) + // { + // continue; + // } + // else if (item.Value != null &&item.Value.Contains("=")&& Regex.IsMatch(item.Value, @"\w+ \@\w+[ ]{0,1}\=[ ]{0,1}\'")) + // { + // continue; + // } + // sql = sql.Replace(item.Value, item.Value.Replace("@", UtilConstants.ReplaceKey)); + // } + // } + // sql = sql .Replace("@",":"); + // sql = sql.Replace(UtilConstants.ReplaceKey, "@"); + // } + // return sql; + //}; + } + public override string SqlParameterKeyWord + { + get + { + return ":"; + } + } + public override IDbConnection Connection + { + get + { + try + { + if (base._DbConnection == null) + { + base._DbConnection = new OracleConnection(base.Context.CurrentConnectionConfig.ConnectionString); + } + } + catch (Exception ex) + { + + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + /// + /// Only SqlServer + /// + /// + public override void BeginTran(string transactionName) + { + ((OracleConnection)this.Connection).BeginTransaction(); + } + + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + ((OracleConnection)this.Connection).BeginTransaction(iso); + } + + public override Func> ProcessingEventStartingSQL => (sql, parameter) => + { + + if (sql == "-- No table ") + { + sql = " SELECT 'No table' FROM DUAL WHERE 1=2 "; + } + if (base.ProcessingEventStartingSQL != null) + { + return base.ProcessingEventStartingSQL(sql, parameter); + } + else + { + return new KeyValuePair(sql, parameter); + } + }; + + + public override IDataAdapter GetAdapter() + { + return new MyOracleDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + sql = ReplaceKeyWordParameterName(sql, parameters); + if (sql?.EndsWith(';') == true && sql?.TrimStart()?.ToLower().StartsWith("begin", StringComparison.CurrentCultureIgnoreCase) != true && sql?.TrimStart()?.ToLower().Contains("begin", StringComparison.CurrentCultureIgnoreCase) != true) + { + sql = sql.TrimEnd(';'); + } + OracleCommand sqlCommand = new OracleCommand(sql, (OracleConnection)this.Connection); + sqlCommand.BindByName = true; + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + sqlCommand.InitialLONGFetchSize = -1; + if (this.Transaction != null) + { + sqlCommand.Transaction = (OracleTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((OracleParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + private static string[] KeyWord = new string[] { "@month", ":month", ":day", "@day", "@group", ":group", ":index", "@index", "@order", ":order", "@user", "@level", ":user", ":level", ":type", "@type", ":year", "@year", "@date", ":date" }; + private string ReplaceKeyWordParameterName(string sql, SugarParameter[] parameters) + { + sql = ReplaceKeyWordWithAd(sql, parameters); + if (parameters.HasValue() && this.CommandType != CommandType.StoredProcedure) + { + foreach (var Parameter in parameters.OrderByDescending(x => x.ParameterName?.Length)) + { + if (Parameter.ParameterName?.ToLower().IsContainsStartWithIn(KeyWord) == true) + { + if (parameters.Count(it => it.ParameterName.StartsWith(Parameter.ParameterName)) == 1) + { + var newName = Parameter.ParameterName + "_01"; + newName = newName.Insert(1, "KW"); + sql = Regex.Replace(sql, Parameter.ParameterName, newName, RegexOptions.IgnoreCase); + Parameter.ParameterName = newName; + } + else if (Parameter.ParameterName.ToLower().IsContainsIn(KeyWord)) + { + Check.ExceptionEasy($" {Parameter.ParameterName} is key word", $"{Parameter.ParameterName}ǹؼ"); + } + } + } + } + + return sql; + } + + private static string ReplaceKeyWordWithAd(string sql, SugarParameter[] parameters) + { + if (parameters != null && sql?.Contains('@') == true) + { + foreach (var item in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + if (item.ParameterName.StartsWith('@')) + { + item.ParameterName = ":" + item.ParameterName.TrimStart('@'); + } + sql = Regex.Replace(sql, "@" + item.ParameterName.TrimStart(':'), item.ParameterName, RegexOptions.IgnoreCase); + } + } + + return sql; + } + + public override Action ErrorEvent => it => + { + if (base.ErrorEvent != null) + { + base.ErrorEvent(it); + } + if (it.Message?.Contains("Ч/󶨱") == true) + { + Check.ExceptionEasy(it.Message, $"{it.Message}ԭ 1.DzΪؼʣ @user 2. SQL"); + } + }; + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((MyOracleDataAdapter)dataAdapter).SelectCommand = (OracleCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + OracleParameter[] result = new OracleParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new OracleParameter(); + sqlParameter.Size = parameter.Size == -1 ? 0 : parameter.Size; + sqlParameter.ParameterName = parameter.ParameterName; + if (sqlParameter.ParameterName[0] == '@') + { + sqlParameter.ParameterName = string.Concat(":", sqlParameter.ParameterName.AsSpan(1, sqlParameter.ParameterName.Length - 1)); + } + if (this.CommandType == CommandType.StoredProcedure) + { + sqlParameter.ParameterName = sqlParameter.ParameterName.TrimStart(':'); + } + if (parameter.IsRefCursor) + { + sqlParameter.OracleDbType = OracleDbType.RefCursor; + } + if (parameter.IsNvarchar2 && parameter.DbType == System.Data.DbType.String) + { + sqlParameter.OracleDbType = OracleDbType.NVarchar2; + } + if (parameter.IsClob) + { + sqlParameter.OracleDbType = OracleDbType.Clob; + sqlParameter.Value = parameter.Value; + } + if (parameter.IsNClob) + { + sqlParameter.OracleDbType = OracleDbType.NClob; + sqlParameter.Value = parameter.Value; + } + if (parameter.IsArray) + { + sqlParameter.OracleDbType = OracleDbType.Varchar2; + sqlParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; + } + if (sqlParameter.DbType == System.Data.DbType.Guid) + { + sqlParameter.DbType = System.Data.DbType.String; + sqlParameter.Value = sqlParameter.Value.ObjToString(); + } + else if (parameter.DbType == System.Data.DbType.DateTimeOffset) + { + if (parameter.Value != DBNull.Value) + sqlParameter.Value = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)parameter.Value); + sqlParameter.DbType = System.Data.DbType.DateTime; + } + else if (parameter.DbType == System.Data.DbType.Boolean) + { + sqlParameter.DbType = System.Data.DbType.Int16; + if (parameter.Value == DBNull.Value) + { + parameter.Value = 0; + } + else + { + sqlParameter.Value = (bool)parameter.Value ? 1 : 0; + } + } + else if (parameter.DbType == System.Data.DbType.DateTime) + { + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = System.Data.DbType.DateTime; + } + else if (parameter.DbType == System.Data.DbType.Date) + { + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = System.Data.DbType.Date; + } + else if (parameter.DbType == System.Data.DbType.AnsiStringFixedLength) + { + sqlParameter.DbType = System.Data.DbType.AnsiStringFixedLength; + sqlParameter.Value = parameter.Value; + } + else if (parameter.DbType == System.Data.DbType.AnsiString) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + sqlParameter.Value = parameter.Value; + } + else if (parameter.DbType == System.Data.DbType.UInt32) + { + sqlParameter.DbType = System.Data.DbType.Int32; + sqlParameter.Value = parameter.Value; + } + else if (parameter.DbType == System.Data.DbType.UInt16) + { + sqlParameter.DbType = System.Data.DbType.Int16; + sqlParameter.Value = parameter.Value; + } + else if (parameter.DbType == System.Data.DbType.UInt64) + { + sqlParameter.DbType = System.Data.DbType.Int64; + sqlParameter.Value = parameter.Value; + } + else + { + if (parameter.Value != null && parameter.Value.GetType() == UtilConstants.GuidType) + { + parameter.Value = parameter.Value.ToString(); + } + sqlParameter.Value = parameter.Value; + } + if (parameter.Direction != 0) + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + if (parameter.CustomDbType != null && parameter.CustomDbType is OracleDbType) + { + sqlParameter.OracleDbType = ((OracleDbType)parameter.CustomDbType); + } + ++index; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Queryable/OracleQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Queryable/OracleQueryable.cs new file mode 100644 index 000000000..d12764276 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Queryable/OracleQueryable.cs @@ -0,0 +1,60 @@ +using SqlSugar; + +namespace SqlSugar +{ + public class OracleQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + protected override List GetIdentityKeys() + { + return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.DbColumnName).ToList(); + } + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleBlukCopy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleBlukCopy.cs new file mode 100644 index 000000000..6b3ce18d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleBlukCopy.cs @@ -0,0 +1,318 @@ +using Oracle.ManagedDataAccess.Client; + +using System.Data; + + +namespace SqlSugar +{ + + public partial class OracleBlukCopy + + { + + 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(); + + OracleBulkCopy bulkCopy = GetBulkCopyInstance(); + + bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString; + + try + + { + + bulkCopy.WriteToServer(dt); + + } + + catch (Exception) + + { + + CloseDb(); + + throw; + + } + + 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(); + + OracleBulkCopy bulkCopy = GetBulkCopyInstance(); + + bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString; + + try + + { + + await Task.Run(() => bulkCopy.WriteToServer(dt)).ConfigureAwait(false); + + } + + catch (Exception) + + { + + CloseDb(); + + throw; + + } + + 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); + + OracleBulkCopy 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 * from " + this.Builder.GetTranslationColumnName(dt.TableName) + " where 1 > 2 "); + + 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 OracleBulkCopy GetBulkCopyInstance() + + { + if (this.Context.Ado.Connection.State == ConnectionState.Closed) + + { + + this.Context.Ado.Connection.Open(); + + } + + OracleBulkCopy copy; + + if (this.Context.Ado.Transaction == null) + + { + + copy = new OracleBulkCopy((OracleConnection)this.Context.Ado.Connection, Oracle.ManagedDataAccess.Client.OracleBulkCopyOptions.Default); + + } + + else + + { + + copy = new OracleBulkCopy((OracleConnection)this.Context.Ado.Connection, OracleBulkCopyOptions.UseInternalTransaction); + + } + return copy; + + } + + private DataTable GetCopyData() + + { + + var dt = this.Context.Ado.GetDataTable("select * from " + InsertBuilder.GetTableNameString + " where 1 > 2 "); + + foreach (var rowInfos in DbColumnInfoList) + + { + + var dr = dt.NewRow(); + + foreach (DataColumn item in dt.Columns) + + { + + var rows = rowInfos.ToList(); + + var value = rows.FirstOrDefault(it => + + it.DbColumnName.Equals(item.ColumnName, StringComparison.CurrentCultureIgnoreCase) || + + it.PropertyName.Equals(item.ColumnName, StringComparison.CurrentCultureIgnoreCase) + + ); + + if (value != null) + + { + + 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("1900/01/01"); + + } + + } + + if (value.Value == null) + + { + + value.Value = DBNull.Value; + + } + + dr[item.ColumnName] = value.Value; + + } + + } + + dt.Rows.Add(dr); + + } + if (this.InsertBuilder.OracleSeqInfoList != null && this.InsertBuilder.OracleSeqInfoList.Count != 0) + { + var ids = this.InsertBuilder.OracleSeqInfoList.Select(it => it.Value).ToList(); + var columnInfo = this.InsertBuilder.EntityInfo.Columns.Where(it => !string.IsNullOrEmpty(it.OracleSequenceName)).First(); + var identityName = columnInfo.DbColumnName; + ids.Add(this.Context.Ado.GetInt(" select " + columnInfo.OracleSequenceName + ".nextval from dual")); + int i = 0; + foreach (DataRow item in dt.Rows) + { + item[identityName] = ids[i]; + ++i; + } + } + return dt; + + } + + private void CloseDb() + + { + + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) + + { + + this.Context.Ado.Connection.Close(); + + } + + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs new file mode 100644 index 000000000..db9c642e2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs @@ -0,0 +1,85 @@ +using System.Text; + +namespace SqlSugar +{ + public class OracleBuilder : SqlBuilderProvider + { + public override string SqlParameterKeyWord + { + get + { + return ":"; + } + } + public override string SqlDateNow + { + get + { + return "sysdate"; + } + } + public override string FullSqlDateNow + { + get + { + return "select systimestamp from dual"; + } + } + public override string SqlTranslationLeft { get { return "\""; } } + public override string SqlTranslationRight { get { return "\""; } } + public override string GetTranslationTableName(string name) + { + var result = base.GetTranslationTableName(name); + if (result.Contains('(') && result.Contains(')')) + return result; + else + return result.ToUpper(IsUppper); + } + public override string GetTranslationColumnName(string entityName, string propertyName) + { + var result = base.GetTranslationColumnName(entityName, propertyName); + return result.ToUpper(IsUppper); + } + public override string GetTranslationColumnName(string propertyName) + { + var result = base.GetTranslationColumnName(propertyName); + return result.ToUpper(IsUppper); + } + public override string RemoveParentheses(string sql) + { + if (sql.StartsWith('(') && sql.EndsWith(')')) + { + sql = sql.Substring(1, sql.Length - 2); + } + + return sql; + } + public override void FormatSaveQueueSql(StringBuilder sqlBuilder) + { + var sql = sqlBuilder?.ToString(); + if (sql?.TrimStart()?.Substring(0, 5)?.EqualCase("begin") != true) + { + sqlBuilder.Clear(); + sqlBuilder.AppendLine("begin"); + sqlBuilder.Append(sql); + sqlBuilder.AppendLine("end; "); + } + } + #region Helper + public bool IsUppper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs new file mode 100644 index 000000000..4c0815f9a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class OracleDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs new file mode 100644 index 000000000..00ed75b7e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs @@ -0,0 +1,453 @@ +using System.Collections; + +namespace SqlSugar +{ + public partial class OracleExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public OracleExpressionContext() + { + base.DbMehtods = new OracleMethod(); + } + public override string SqlParameterKeyWord + { + get + { + return ":"; + } + } + public override string SqlTranslationLeft { get { return "\""; } } + public override string SqlTranslationRight { get { return "\""; } } + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + return base.GetTranslationTableName(entityName, isMapping).ToUpper(IsUppper); + } + public override string GetTranslationColumnName(string columnName) + { + if (columnName == "systimestamp") + { + return columnName; + } + if (columnName.Contains(':')) + return base.GetTranslationColumnName(columnName); + else if (columnName.Contains("\".\"")) + { + return columnName; + } + else + return base.GetTranslationColumnName(columnName).ToUpper(IsUppper); + } + public override string GetDbColumnName(string entityName, string propertyName) + { + return base.GetDbColumnName(entityName, propertyName).ToUpper(IsUppper); + } + public override bool IsTranslationText(string name) + { + if (!string.IsNullOrEmpty(name) && name.Equals("sysdate", StringComparison.CurrentCultureIgnoreCase)) + { + return true; + } + var result = name.IsContainsIn(SqlTranslationLeft, SqlTranslationRight, UtilConstants.Space, ExpressionConst.LeftParenthesis, ExpressionConst.RightParenthesis); + return result; + } + public bool IsUppper + { + get + { + if (this.SugarContext?.Context?.Context?.CurrentConnectionConfig?.MoreSettings == null) + { + return true; + } + else + { + return this.SugarContext?.Context?.Context?.CurrentConnectionConfig?.MoreSettings.IsAutoToUpper == true; + } + } + } + } + public partial class OracleMethod : DefaultDbMethod, IDbMethods + { + public override string UNIX_TIMESTAMP(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + return $" (CAST({parameterNameA} AS DATE) - DATE '1970-01-01') * 86400 "; + } + public override string IsNullOrEmpty(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NULL )", parameter.MemberName); + } + public override string WeekOfYear(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $"TO_NUMBER(TO_CHAR({parameterNameA}, 'WW')) "; + } + public override string BitwiseAnd(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" BITAND({0},{1}) ", parameter.MemberName, parameter2.MemberName); + } + public override string BitwiseInclusiveOR(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" BITOR({0},{1}) ", parameter.MemberName, parameter2.MemberName); + } + public override string ParameterKeyWord { get; set; } = ":"; + public override string Modulo(MethodCallExpressionModel model) + { + return " MOD(" + model.Args[0].MemberName + " , " + model.Args[1].MemberName + ")"; + } + public override string GetStringJoinSelector(string result, string separator) + { + if (result.Contains(',')) + { + return $"listagg(to_char({result.Split(',').First()}),'{separator}') within group(order by {result.Split(',').Last()}) "; + } + else + { + return $"listagg(to_char({result}),'{separator}') within group(order by {result}) "; + } + } + public override string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL ) ", parameter.MemberName); + } + + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString())); + var begin = model.Args[1].MemberName; + var end = model.Args[2].MemberName; + switch (parameter) + { + case DateType.Year: + return $" ( cast((months_between( {end} , {begin}))/12 as number(9,0) ) )"; + case DateType.Month: + return $" ( cast((months_between( {end} , {begin})) as number(9,0) ) )"; + case DateType.Day: + return $" ( ROUND(TO_NUMBER(cast({end} as date) - cast({begin} as date))) )"; + case DateType.Hour: + return $" ( ROUND(TO_NUMBER(cast({end} as date) - cast({begin} as date)) * 24) )"; + case DateType.Minute: + return $" ( ROUND(TO_NUMBER(cast({end} as date) - cast({begin} as date)) * 24 * 60) )"; + case DateType.Second: + return $" ( ROUND(TO_NUMBER(cast({end} as date) - cast({begin} as date)) * 24 * 60 * 60) )"; + case DateType.Millisecond: + return $" ( ROUND(TO_NUMBER(cast({end} as date) - cast({begin} as date)) * 24 * 60 * 60 * 60) )"; + default: + break; + } + throw new Exception(parameter + " datediff no support"); + } + private void PageEach(IEnumerable pageItems, int pageSize, Action> action) + { + if (pageItems?.Any() == true) + { + int totalRecord = pageItems.Count(); + int pageCount = (totalRecord + pageSize - 1) / pageSize; + for (int i = 1; i <= pageCount; i++) + { + var list = pageItems.Skip((i - 1) * pageSize).Take(pageSize).ToList(); + action(list); + } + } + } + public override string ContainsArray(MethodCallExpressionModel model) + { + if (model.Args[0].MemberValue == null) + { + return base.ContainsArray(model); + } + var inValueIEnumerable = ((IEnumerable)model.Args[0].MemberValue).Cast().ToArray(); + if (inValueIEnumerable.Length < 1000) + { + return base.ContainsArray(model); + } + else + { + string result = ""; + PageEach(inValueIEnumerable, 999, it => + { + model.Args.First().MemberValue = it; + result += (base.ContainsArray(model) + " OR "); + + }); + return " ( " + result.TrimEnd(' ').TrimEnd('R').TrimEnd('O') + " ) "; + } + } + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS Number)", parameter.MemberName); + } + + public override string ToTime(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" to_timestamp({0},'0000-01-01 hh24:mi:ss') ", parameter.MemberName); + } + public override string Substring(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format("SUBSTR({0},1 + {1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + 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 string.Format("(CAST(TO_CHAR({0},'yyyy') AS NUMBER))", parameter.MemberName); + case DateType.Month: + return string.Format("(CAST(TO_CHAR({0},'mm') AS NUMBER))", parameter.MemberName); + case DateType.Hour: + return string.Format("(CAST(TO_CHAR({0},'hh24') AS NUMBER))", parameter.MemberName); + case DateType.Second: + return string.Format("(CAST(TO_CHAR({0},'ss') AS NUMBER))", parameter.MemberName); + case DateType.Minute: + return string.Format("(CAST(TO_CHAR({0},'mi') AS NUMBER))", parameter.MemberName); + case DateType.Millisecond: + return string.Format("(CAST(TO_CHAR({0},'ff3') AS NUMBER))", parameter.MemberName); + case DateType.Quarter: + return string.Format("(CAST(TO_CHAR({0},'q') AS NUMBER))", parameter.MemberName); + case DateType.Weekday: + return $" (TO_NUMBER(TO_CHAR({parameter.MemberName}, 'D'))-1) "; + case DateType.Day: + default: + return string.Format("(CAST(TO_CHAR({0},'dd') AS NUMBER))", parameter.MemberName); + } + } + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + var type = (DateType)Enum.Parse(typeof(DateType), parameter3.MemberValue.ObjToString(), false); + double time = 1; + switch (type) + { + case DateType.Year: + // 每年 = 12 个月 + return $"ADD_MONTHS({parameter.MemberName}, ({parameter2.MemberName}) * 12)"; + case DateType.Month: + return $"ADD_MONTHS({parameter.MemberName}, {parameter2.MemberName})"; + case DateType.Day: + break; + case DateType.Hour: + time = 1 / 24.0; + break; + case DateType.Second: + time = 1 / 24.0 / 60.0 / 60.0; + break; + case DateType.Minute: + time = 1 / 24.0 / 60.0; + break; + case DateType.Millisecond: + time = 1 / 24.0 / 60.0 / 60.0 / 1000; + break; + } + return string.Format("({0}+({1}*{2})) ", parameter.MemberName, time, parameter2.MemberName); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format("({0}+(1*{1})) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR2(4000))", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS Number)", parameter.MemberName); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" TO_TIMESTAMP({0}, 'YYYY-MM-DD HH24:MI:SS.FF') ", parameter.MemberName); + } + + public override string ToDateShort(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" TRUNC({0},'dd') ", parameter.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 Trim(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" trim({0}) ", parameter.MemberName); + } + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( cast({0} as date)= cast( {1} as date) ) ", parameter.MemberName, parameter2.MemberName); ; + } + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + + var dateType = parameter3.MemberValue.ObjToString().ToLower(); + var date1 = parameter.MemberName; + var date2 = parameter2.MemberName; + + if (dateType == "year") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}))", date1, date2); + } + else if (dateType == "month") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}) AND EXTRACT(MONTH FROM {0}) = EXTRACT(MONTH FROM {1}))", date1, date2); + } + else if (dateType == "day") + { + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } + else if (dateType == "hour") + { + return string.Format("(TRUNC({0}, 'HH24') = TRUNC({1}, 'HH24'))", date1, date2); + } + else if (dateType == "minute") + { + return string.Format("(TRUNC({0}, 'MI') = TRUNC({1}, 'MI'))", date1, date2); + } + else if (dateType == "second") + { + return string.Format("(TRUNC({0}, 'SS') = TRUNC({1}, 'SS'))", date1, date2); + } + else if (dateType == "week" || dateType == "weekday") + { + return string.Format("(TRUNC({0}, 'IW') = TRUNC({1}, 'IW'))", date1, date2); + } + else + { + // 默认按天比较 + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } + } + public override string Length(MethodCallExpressionModel model) + { + 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) + { + return string.Join("||", strings); + } + + public override string GetDate() + { + return "systimestamp"; + } + + public override string GetRandom() + { + return "dbms_random.value"; + } + + public override string Collate(MethodCallExpressionModel model) + { + var name = model.Args[0].MemberName; + return $" NLSSORT({0}, 'NLS_SORT = Latin_CI') "; + } + + public override string JsonField(MethodCallExpressionModel model) + { + return $"JSON_VALUE({model.Args[0].MemberName}, '$.{model.Args[1].MemberValue.ToString().ToSqlFilter()}')"; + //"JSON_VALUE(j.kingorder, '$.Id') = '1'"; + } + + 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 TrimEnd(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" RTRIM({parameterNameA}, {parameterNameB}) "; + } + public override string TrimStart(MethodCallExpressionModel mode) + { + + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" LTRIM({parameterNameA}, {parameterNameB}) "; + } + public override string Left(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" SUBSTR({parameterNameA}, 1, {parameterNameB}) "; + } + public override string Right(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" SUBSTR({parameterNameA}, (LENGTH({parameterNameA})-2), {parameterNameB}) "; + } + + public override string Ceil(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" CEIL({parameterNameA}) "; + } + + public override string NewUid(MethodCallExpressionModel mode) + { + return " SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 1, 8) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 9, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 13, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 17, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 21) "; + } + public override string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = "(" + string.Join(",", mode.Args[0].MemberValue as List) + ")"; + } + var searchWord = mode.Args[1].MemberName; + return $" CONTAINS({columns}, {searchWord}, 1) "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs new file mode 100644 index 000000000..689058f70 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs @@ -0,0 +1,122 @@ +using Oracle.ManagedDataAccess.Client; + +using System.Data; + +namespace SqlSugar +{ + public class OracleFastBuilder : FastBuilder, IFastBuilder + { + public override bool IsActionUpdateColumns { get; set; } = true; + public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() + { + IsMerge = true + }; + private EntityInfo entityInfo; + + public OracleFastBuilder(EntityInfo entityInfo) + { + this.entityInfo = entityInfo; + } + + public override string UpdateSql { get; set; } = "UPDATE (SELECT {4} FROM {2} TM,{3} TE WHERE {1})SET {0}"; + public override async Task CreateTempAsync(DataTable dt) + { + var sqlBuilder = this.Context.Queryable().SqlBuilder; + var dts = dt.Columns.Cast().Select(it => sqlBuilder.GetTranslationColumnName(it.ColumnName)).ToList(); + //await Task.FromResult(0); + //throw new Exception("Oracle no support BulkUpdate"); + var oldTableName = dt.TableName; + var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + dt.TableName = "Temp" + SnowFlakeSingle.instance.getID().ToString(); + if (columns.Count == 0 && DbFastestProperties?.WhereColumns.HasValue() == true) + { + columns.AddRange(DbFastestProperties.WhereColumns); + } + var sql = this.Context.Queryable().AS(oldTableName).Where(it => false).Select(string.Join(",", dts)).ToSql().Key; + await Context.Ado.ExecuteCommandAsync($"create table {dt.TableName} as {sql} ").ConfigureAwait(false); + this.Context.DbMaintenance.AddPrimaryKeys(dt.TableName, columns.ToArray(), "Pk_" + SnowFlakeSingle.instance.getID().ToString()); + } + public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlBuilder = this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(updateColumns.Length == 0, "update columns count is 0"); + Check.ArgumentNullException(whereColumns.Length == 0, "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"TM{it}=TE{it}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"TM.{sqlBuilder.GetTranslationColumnName(it)}=TE.{sqlBuilder.GetTranslationColumnName(it)}")); + var forms = string.Join(",", updateColumns.Select(it => $" TM.{sqlBuilder.GetTranslationColumnName(it)} TM{it},TE.{sqlBuilder.GetTranslationColumnName(it)} TE{it}")); ; + string sql = string.Format(UpdateSql, sets, wheres, tableName, tempName, forms); + return await Context.Ado.ExecuteCommandAsync(sql).ConfigureAwait(false); + } + private OracleBulkCopy GetBulkCopyInstance() + + { + if (this.Context.Ado.Connection.State == ConnectionState.Closed) + { + this.Context.Ado.Connection.Open(); + } + + OracleBulkCopy copy; + if (this.Context.Ado.Transaction == null) + { + copy = new OracleBulkCopy((OracleConnection)this.Context.Ado.Connection, Oracle.ManagedDataAccess.Client.OracleBulkCopyOptions.Default); + } + else + { + copy = new OracleBulkCopy((OracleConnection)this.Context.Ado.Connection, OracleBulkCopyOptions.UseInternalTransaction); + } + copy.BulkCopyTimeout = this.Context.Ado.CommandTimeOut; + return copy; + + } + + public override Task Merge(string tableName, DataTable dt, EntityInfo entityInfo, string[] whereColumns, string[] updateColumns, List datas) where T : class + { + Check.Exception(this.entityInfo.Columns.Any(it => it.OracleSequenceName.HasValue()), "The BulkMerge method cannot be used for sequence", "BulkMerge方法不能用序列"); + var sqlBuilder = this.Context.Queryable().SqlBuilder; + var insertColumns = entityInfo.Columns + .Where(it => it.IsIgnore == false) + .Where(it => it.IsIdentity == false) + .Where(it => it.InsertServerTime == false) + .Where(it => it.InsertSql == null) + .Where(it => it.OracleSequenceName == null) + .Where(it => it.IsOnlyIgnoreInsert == false); + var whereSql = string.Join(" AND ", whereColumns.Select(it => $"tgt.{sqlBuilder.GetTranslationColumnName(it)}=src.{sqlBuilder.GetTranslationColumnName(it)}")); + var updateColumnsSql = string.Join(" , ", updateColumns.Select(it => $"tgt.{sqlBuilder.GetTranslationColumnName(it)}=src.{sqlBuilder.GetTranslationColumnName(it)}")); + var insertColumnsSqlTgt = string.Join(" , ", insertColumns.Select(it => "tgt." + sqlBuilder.GetTranslationColumnName(it.DbColumnName))); + var insertColumnsSqlsrc = string.Join(" , ", insertColumns.Select(it => "src." + sqlBuilder.GetTranslationColumnName(it.DbColumnName))); + var sql = $@"MERGE INTO {sqlBuilder.GetTranslationColumnName(tableName)} tgt +USING {sqlBuilder.GetTranslationColumnName(dt.TableName)} src +ON ({whereSql}) +WHEN MATCHED THEN + UPDATE SET {updateColumnsSql} +WHEN NOT MATCHED THEN + INSERT ({insertColumnsSqlTgt}) + VALUES ({insertColumnsSqlsrc})"; + + return this.Context.Ado.ExecuteCommandAsync(sql); + } + public Task ExecuteBulkCopyAsync(DataTable dt) + { + var identityColumnInfo = this.entityInfo.Columns.FirstOrDefault(it => it.IsIdentity); + if (identityColumnInfo != null) + { + throw new Exception("Oracle bulkcopy no support identity"); + } + OracleBulkCopy copy = GetBulkCopyInstance(); + try + { + copy.DestinationTableName = dt.TableName; + copy.WriteToServer(dt); + } + catch (Exception) + { + throw; + } + finally + { + CloseDb(); + } + return Task.FromResult(dt.Rows.Count); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs new file mode 100644 index 000000000..78319b993 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs @@ -0,0 +1,222 @@ +using System.Text; + +namespace SqlSugar +{ + public class OracleInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) "; + + } + } + public override string SqlTemplateBatch + { + get + { + return "INSERT INTO {0} ({1})"; + } + } + public override string ToSqlString() + { + var identities = this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).ToList(); + if (IsNoInsertNull) + { + DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList(); + } + if (this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true) + { + this.DbColumnInfoList = this.DbColumnInfoList.Where(it => it.IsIdentity == false).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 && this.EntityInfo.EntityName != "Dictionary`2") + { + + string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => base.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName))); + if (identities.HasValue()) + { + columnsString = columnsString.TrimEnd(',') + "," + string.Join(",", identities.Select(it => Builder.GetTranslationColumnName(it.DbColumnName))); + columnParametersString = columnParametersString.TrimEnd(',') + "," + string.Join(",", identities.Select(it => it.OracleSequenceName + ".nextval")); + } + ActionMinDate(); + return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + var bigSize = 500; + if (groupList.Count < bigSize || this.Context?.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true) + { + string result = Small(identities, groupList, columnsString); + return result; + } + else + { + string result = Big(identities, groupList, columnsString); + return result; + } + } + } + private string Big(List identities, List> groupList, string columnsString) + { + this.Context.Utilities.PageEach(groupList, 100, groupListPasge => + { + this.Parameters = new List(); + var sql = Small(identities, groupListPasge, columnsString); + this.Context.Ado.ExecuteCommand(sql, this.Parameters); + }); + if (identities?.Count > 0 && this.OracleSeqInfoList != null && this.OracleSeqInfoList.Count != 0) + { + return $"SELECT {this.OracleSeqInfoList.First().Value - 1} FROM DUAL"; + } + else + { + return $"SELECT {groupList.Count} FROM DUAL"; + } + } + + private string Small(List identities, List> groupList, string columnsString) + { + StringBuilder batchInsetrSql = new StringBuilder(); + batchInsetrSql.AppendLine("INSERT ALL"); + foreach (var item in groupList) + { + batchInsetrSql.Append("INTO " + GetTableNameString + " "); + string insertColumns = ""; + + batchInsetrSql.Append('('); + batchInsetrSql.Append(columnsString); + if (identities.HasValue() && this.IsOffIdentity == false) + { + batchInsetrSql.Append("," + string.Join(",", identities.Select(it => Builder.GetTranslationColumnName(it.DbColumnName)))); + } + batchInsetrSql.Append(") VALUES"); + + + batchInsetrSql.Append('('); + insertColumns = string.Join(",", item.Select(it => GetDbColumn(it, FormatValue(it.Value, it.PropertyName)))); + batchInsetrSql.Append(insertColumns); + if (this.IsOffIdentity == false) + { + if (identities.HasValue()) + { + batchInsetrSql.Append(','); + foreach (var idn in identities) + { + var seqvalue = this.OracleSeqInfoList[idn.OracleSequenceName]; + this.OracleSeqInfoList[idn.OracleSequenceName] = this.OracleSeqInfoList[idn.OracleSequenceName] + 1; + if (identities.Last() == idn) + { + batchInsetrSql.Append(seqvalue); + } + else + { + batchInsetrSql.Append(seqvalue + ","); + } + } + } + } + batchInsetrSql.AppendLine(") "); + + } + if (identities.HasValue()) + { + batchInsetrSql.AppendLine("SELECT " + (this.OracleSeqInfoList.First().Value - 1) + " FROM DUAL"); + } + else + { + batchInsetrSql.AppendLine("SELECT 1 FROM DUAL"); + } + var result = batchInsetrSql.ToString(); + return result; + } + + int i = 0; + public object FormatValue(object value, string name) + { + if (value == null) + { + return "NULL"; + } + else + { + string N = this.Context.GetN(); + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.StringType && value.ToString().Contains("{SugarSeq:=}")) + { + return value.ToString().Replace("{SugarSeq:=}", ""); + } + if (type == UtilConstants.DateType) + { + 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 "to_date('" + date.ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; + } + else + { + return "to_timestamp('" + date.ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + } + } + else if (type.IsEnum()) + { + return Convert.ToInt64(value); + } + else if (value is TimeSpan ts) + { + return string.Format( + "INTERVAL '{0} {1:D2}:{2:D2}:{3:D2}.{4:D3}' DAY TO SECOND(3)", + ts.Days, + ts.Hours, + ts.Minutes, + ts.Seconds, + ts.Milliseconds); + } + else if (type == UtilConstants.ByteArrayType) + { + ++i; + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + this.Parameters.Add(new SugarParameter(parameterName, value, System.Data.DbType.Binary)); + return parameterName; + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "to_timestamp('" + date.ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + if (value.ToString().Length > 1000) + { + ++i; + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else + { + return N + "'" + value.ToString().ToSqlFilter() + "'"; + } + } + else + { + return N + "'" + value.ToString() + "'"; + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs new file mode 100644 index 000000000..5e0b1636c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs @@ -0,0 +1,136 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class OracleQueryBuilder : QueryBuilder + { + public override bool IsSelectNoAll { get; set; } = true; + public override bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS ""\w+\.\w+""") || Regex.IsMatch(sql, @"AS ""\w+\.\w+\.\w+"""); + } + public override string SqlTemplate + { + get + { + return "SELECT {0}{" + UtilConstants.ReplaceKey + "} FROM {1}{2}{3}{4}"; + } + } + public override string ToSqlString() + { + if (this.Offset == "true") + { + return OffsetPage(); + } + var oldTake = Take; + var oldSkip = Skip; + var isDistinctPage = IsDistinct && (Take > 1 || Skip > 1); + if (isDistinctPage) + { + return OffsetPage(); + } + var result = _ToSqlString(); + //if (isDistinctPage) + //{ + // if (this.OrderByValue.HasValue()) + // { + // Take = int.MaxValue; + // result = result.Replace("DISTINCT", $" DISTINCT TOP {int.MaxValue} "); + // } + // Take = oldTake; + // Skip = oldSkip; + // result = this.Context.SqlQueryable(result).Skip(Skip??0).Take(Take??0).ToSql().Key; + + + //} + if (TranLock != null) + { + result = result + TranLock; + } + return result; + } + + private string OffsetPage() + { + var skip = this.Skip ?? 1; + var take = this.Take; + this.Skip = null; + this.Take = null; + this.Offset = null; + var pageSql = $"SELECT * FROM ( SELECT PAGETABLE1.*,ROWNUM PAGEINDEX FROM( {this.ToSqlString()}) PAGETABLE1 WHERE ROWNUM<={skip + take}) WHERE PAGEINDEX>={(skip == 0 ? skip : (skip + 1))}"; + return pageSql; + } + + public string _ToSqlString() + { + string oldOrderBy = this.OrderByValue; + string externalOrderBy = oldOrderBy; + var isIgnoreOrderBy = this.IsCount && this.PartitionByValue.IsNullOrEmpty(); + AppendFilter(); + sql = new StringBuilder(); + if (this.OrderByValue == null && (Skip != null || Take != null)) this.OrderByValue = " ORDER BY " + this.Builder.SqlDateNow + " "; + if (this.PartitionByValue.HasValue()) + { + this.OrderByValue = this.PartitionByValue + this.OrderByValue; + } + var isRowNumber = Skip != null || Take != null; + var rowNumberString = string.Format(",ROW_NUMBER() OVER({0}) AS RowIndex ", GetOrderByString); + string groupByValue = GetGroupByString + HavingInfos; + string orderByValue = (!isRowNumber && this.OrderByValue.HasValue()) ? GetOrderByString : null; + if (isIgnoreOrderBy) { orderByValue = null; } + sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, groupByValue, orderByValue); + sql.Replace(UtilConstants.ReplaceKey, isRowNumber ? (isIgnoreOrderBy ? null : rowNumberString) : null); + if (isIgnoreOrderBy) { this.OrderByValue = oldOrderBy; return sql.ToString(); } + var result = ToPageSql(sql.ToString(), this.Take, this.Skip); + if (this.GetGroupByString == null && this.Take == 1 && this.Skip == 0 && oldOrderBy == "ORDER BY sysdate ") + { + result = $" {sql.ToString()} {(this.WhereInfos.Count != 0 ? "AND" : "WHERE")} ROWNUM = 1 "; + result = result.Replace(rowNumberString, " "); + } + if (ExternalPageIndex > 0) + { + if (externalOrderBy.IsNullOrEmpty()) + { + externalOrderBy = " ORDER BY " + this.Builder.SqlDateNow + " "; + } + result = string.Format("SELECT ExternalTable.*,ROW_NUMBER() OVER({0}) AS RowIndex2 FROM ({1}) ExternalTable ", GetExternalOrderBy(externalOrderBy), result); + result = ToPageSql2(result, ExternalPageIndex, ExternalPageSize, true); + } + this.OrderByValue = oldOrderBy; + result = GetSqlQuerySql(result); + if (result.IndexOf("-- No table") > 0) + { + return "-- No table"; + } + return result; + } + public override string ToPageSql(string sql, int? take, int? skip, bool isExternal = false) + { + string temp = isExternal ? ExternalPageTempalte : PageTempalte; + if (skip != null && take == null) + { + return string.Format(temp, sql.ToString(), skip.ObjToInt() + 1, long.MaxValue); + } + else if (skip == null && take != null) + { + return string.Format(temp, sql.ToString(), 1, take.ObjToInt()); + } + else if (skip != null && take != null) + { + return string.Format(temp, sql.ToString(), skip.ObjToInt() + 1, skip.ObjToInt() + take.ObjToInt()); + } + else + { + return sql.ToString(); + } + } + + public override string ToPageSql2(string sql, int? pageIndex, int? pageSize, bool isExternal = false) + { + string temp = isExternal ? ExternalPageTempalte : PageTempalte; + return string.Format(temp, sql.ToString(), (pageIndex - 1) * pageSize + 1, pageIndex * pageSize); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs new file mode 100644 index 000000000..115e0b2e9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs @@ -0,0 +1,168 @@ +using System.Text; + +namespace SqlSugar +{ + public class OracleUpdateBuilder : UpdateBuilder + { + public override string ReSetValueBySqlExpListType { get; set; } = "oracle"; + protected override string TomultipleSqlString(List> groupList) + { + if (groupList.Count == 0) + { + return " select 0 from dual"; + } + StringBuilder sb = new StringBuilder(); + sb.AppendLine("Begin"); + sb.AppendLine(string.Join("\r\n", groupList.Select(t => + { + var updateTable = string.Format("UPDATE {0} SET", base.GetTableNameStringNoWith); + var setValues = string.Join(",", t.Where(s => !s.IsPrimarykey).Where(s => OldPrimaryKeys?.Contains(s.DbColumnName) != true).Select(m => GetOracleUpdateColums(m)).ToArray()); + var pkList = t.Where(s => s.IsPrimarykey).ToList(); + if (this.IsWhereColumns && this.PrimaryKeys?.Count > 0) + { + var whereColumns = pkList.Where(it => this.PrimaryKeys?.Any(p => p.EqualCase(it.PropertyName) || p.EqualCase(it.DbColumnName)) == true).ToList(); + if (whereColumns.Count != 0) + { + pkList = whereColumns; + } + } + List whereList = new List(); + foreach (var item in pkList) + { + var isFirst = pkList.First() == item; + var whereString = isFirst ? " " : " AND "; + whereString += GetOracleUpdateColums(item, true); + whereList.Add(whereString); + } + return string.Format("{0} {1} WHERE {2};", updateTable, setValues, string.Join("", whereList)); + }).ToArray())); + sb.AppendLine("End;"); + return sb.ToString(); + } + + private string GetOracleUpdateColums(DbColumnInfo m, bool isWhere = false) + { + + var result = string.Format("\"{0}\"={1} ", m.DbColumnName.ToUpper(IsUppper), base.GetDbColumn(m, FormatValue(m.Value, m.IsPrimarykey, m.PropertyName))); + if (isWhere && m.Value == null) + { + result = result.Replace("=NULL ", " is NULL "); + } + return result; + } + int i = 0; + public object FormatValue(object value, bool isPrimaryKey, string name) + { + if (value == null) + { + return "NULL"; + } + else + { + string N = this.Context.GetN(); + if (isPrimaryKey) + { + N = ""; + } + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + 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 "to_date('" + date.ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; + } + else + { + return "to_timestamp('" + date.ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + } + } + else if (type.IsEnum()) + { + return Convert.ToInt64(value); + } + else if (type.IsIn(UtilConstants.IntType, UtilConstants.LongType, UtilConstants.ShortType)) + { + return value; + } + else if (type == UtilConstants.GuidType) + { + return "'" + value.ToString() + "'"; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + Convert.ToHexString((byte[])value); + return bytesString; + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (value is TimeSpan ts) + { + return string.Format( + "INTERVAL '{0} {1:D2}:{2:D2}:{3:D2}.{4:D3}' DAY TO SECOND(3)", + ts.Days, + ts.Hours, + ts.Minutes, + ts.Seconds, + ts.Milliseconds); + } + else if (type == UtilConstants.DateTimeOffsetType) + { + var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value); + return "to_timestamp('" + date.ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + if (value.ToString().Length > 1000) + { + ++i; + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else + { + return N + "'" + value.ToString().ToSqlFilter() + "'"; + } + } + else + { + return N + "'" + value.ToString() + "'"; + } + } + } + protected override string GetJoinUpdate(string columnsString, ref string whereString) + { + var joinString = $" {Builder.GetTranslationColumnName(this.TableName)} {Builder.GetTranslationColumnName(this.ShortName)} "; + foreach (var item in this.JoinInfos) + { + joinString += $"\r\n USING {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} ON {item.JoinWhere} "; + } + var tableName = joinString + "\r\n "; + var newTemp = SqlTemplate.Replace("UPDATE", "MERGE INTO").Replace("SET", "WHEN MATCHED THEN \r\nUPDATE SET"); + return string.Format(newTemp, tableName, columnsString, whereString); + } + #region Helper + public bool IsUppper + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) + { + return true; + } + else + { + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true; + } + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Updateable/OracleUpdateable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Updateable/OracleUpdateable.cs new file mode 100644 index 000000000..54c9d1d42 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oracle/Updateable/OracleUpdateable.cs @@ -0,0 +1,58 @@ +namespace SqlSugar +{ + public class OracleUpdateable : UpdateableProvider where T : class, new() + { + protected override List GetIdentityKeys() + { + return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.DbColumnName).ToList(); + } + public override int ExecuteCommand() + { + if (base.UpdateObjs.Length == 1) + { + var resultl = base.ExecuteCommand(); + if (resultl == -1) + { + return 1; + } + else + { + return resultl; + } + } + else if (base.UpdateObjs.Length == 0) + { + return 0; + } + else + { + base.ExecuteCommand(); + return base.UpdateObjs.Length; + } + } + public async override Task ExecuteCommandAsync() + { + if (base.UpdateObjs.Length == 1) + { + var result = await base.ExecuteCommandAsync().ConfigureAwait(false); + if (result == -1) + { + return 1; + } + else + { + return result; + } + } + else if (base.UpdateObjs.Length == 0) + { + return 0; + } + else + { + await base.ExecuteCommandAsync().ConfigureAwait(false); + return base.UpdateObjs.Length; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/CodeFirst/OscarCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/CodeFirst/OscarCodeFirst.cs new file mode 100644 index 000000000..166b9c10d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/CodeFirst/OscarCodeFirst.cs @@ -0,0 +1,73 @@ +namespace SqlSugar +{ + public class OscarCodeFirst : CodeFirstProvider + { + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + } + } + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length + }; + if (propertyType == UtilConstants.DecType) + { + result.Scale = item.DecimalDigits; + result.DecimalDigits = item.DecimalDigits; + } + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + //this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + //if (!item.IsPrimarykey) + // this.Context.DbMaintenance.DropConstraint(tableName,null); + //if (item.IsPrimarykey) + // this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbBind/OscarDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbBind/OscarDbBind.cs new file mode 100644 index 000000000..a584bd88d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbBind/OscarDbBind.cs @@ -0,0 +1,136 @@ +namespace SqlSugar +{ + public class OscarDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "bytea"; + + var result = base.GetDbTypeName(csharpTypeName); + return result; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json") + { + return "string"; + } + else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + { + return "char"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes?.Any() != true) + { + if (dbTypeName.StartsWith('_')) + { + var dbTypeName2 = dbTypeName.TrimStart('_'); + return MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName2, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName2, StringComparison.CurrentCultureIgnoreCase)).Select(it => it.Value + "[]").First(); + } + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("int2",CSharpDataType.@short), + new KeyValuePair("int1",CSharpDataType.@byte), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("int4",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("int8",CSharpDataType.@long), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("float4",CSharpDataType.@float), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("float8",CSharpDataType.@double), + new KeyValuePair("double precision",CSharpDataType.@int), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("path",CSharpDataType.@decimal), + new KeyValuePair("point",CSharpDataType.@decimal), + new KeyValuePair("polygon",CSharpDataType.@decimal), + + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("bool",CSharpDataType.@bool), + new KeyValuePair("box",CSharpDataType.@bool), + new KeyValuePair("bytea",CSharpDataType.byteArray), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("character varying",CSharpDataType.@string), + new KeyValuePair("geometry",CSharpDataType.@string), + new KeyValuePair("name",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("clob",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("character",CSharpDataType.@string), + new KeyValuePair("cidr",CSharpDataType.@string), + new KeyValuePair("circle",CSharpDataType.@string), + new KeyValuePair("tsquery",CSharpDataType.@string), + new KeyValuePair("tsvector",CSharpDataType.@string), + new KeyValuePair("txid_snapshot",CSharpDataType.@string), + new KeyValuePair("uuid",CSharpDataType.Guid), + new KeyValuePair("xml",CSharpDataType.@string), + new KeyValuePair("json",CSharpDataType.@string), + + new KeyValuePair("interval",CSharpDataType.@decimal), + new KeyValuePair("lseg",CSharpDataType.@decimal), + new KeyValuePair("macaddr",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamptz",CSharpDataType.DateTime), + new KeyValuePair("timestamp without time zone",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("time with time zone",CSharpDataType.DateTime), + new KeyValuePair("timetz",CSharpDataType.DateTime), + new KeyValuePair("time without time zone",CSharpDataType.DateTime), + + new KeyValuePair("bit",CSharpDataType.byteArray), + new KeyValuePair("bit varying",CSharpDataType.byteArray), + new KeyValuePair("varbit",CSharpDataType.@byte), + new KeyValuePair("time",CSharpDataType.TimeSpan), + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbFirst/OscarDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbFirst/OscarDbFirst.cs new file mode 100644 index 000000000..23a27c7e9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbFirst/OscarDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class OscarDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbMaintenance/OscarDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbMaintenance/OscarDbMaintenance.cs new file mode 100644 index 000000000..d3e8c2170 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/DbMaintenance/OscarDbMaintenance.cs @@ -0,0 +1,415 @@ +using System.Data.Common; + +namespace SqlSugar +{ + public class OscarDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + return "SELECT datname FROM sys_database "; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string sql = @" SELECT + A.COLUMN_NAME AS DbColumnName, + A.TABLE_NAME AS TableName, + A.DATA_TYPE AS DataType, + case when DATA_DEFAULT like 'NEXTVAL%' then true else false end as IsIdentity, + case when A.NULLABLE = 'Y' then true else false end as IsNullable , + A.DATA_LENGTH AS LENGTH, + B.COMMENTS AS ColumnDescription, + CASE WHEN K.COLUMN_NAME IS NULL THEN FALSE ELSE TRUE END AS IsPrimarykey, + DATA_SCALE AS DecimalDigits, + A.DATA_PRECISION AS SCALE, + A.DATA_DEFAULT as DefaultValue + FROM + INFO_SCHEM.ALL_TAB_COLUMNS A + LEFT JOIN INFO_SCHEM.SYS_CLASS T ON T.RELNAME=A.TABLE_NAME + LEFT JOIN INFO_SCHEM.ALL_COL_COMMENTS B ON A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME + LEFT JOIN INFO_SCHEM.SYS_ATTRIBUTE C ON C.ATTNAME=A.COLUMN_NAME AND C.ATTRELID=T.OID + LEFT JOIN INFO_SCHEM.V_SYS_PRIMARY_KEYS K ON A.TABLE_NAME=K.TABLE_NAME AND K.COLUMN_NAME=A.COLUMN_NAME + WHERE upper(A.TABLE_NAME)=upper('{0}') + ORDER BY c.ATTNUM + "; + return sql; + } + } + protected override string GetTableInfoListSql + { + get + { + //AND t.relnamespace=1 表空间限制。 + return @" select cast(relname as varchar(500)) as Name , DESCRIPTION AS Description FROM sys_class t + LEFT JOIN sys_description d ON t.OID=d.OBJOID AND d.OBJSUBID=0 + WHERE t.relvbase>0 AND t.relkind = 'r' AND t.relnamespace=(SELECT OID FROM sys_namespace WHERE nspname =USER) + order by relname"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @" select cast(relname as varchar(500)) as Name , DESCRIPTION AS Description FROM sys_class t + LEFT JOIN sys_description d ON t.OID=d.OBJOID AND d.OBJSUBID=0 + WHERE t.relvbase>0 AND t.relkind = 'v' AND t.relnamespace=(SELECT OID FROM sys_namespace WHERE nspname =USER) + order by relname"; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "alter table {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return "mysqldump.exe {0} -uroot -p > {1} "; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {0} as (select * from {1} limit {2} offset 0)"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} RENAME {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 { throw new NotSupportedException(); } } + + protected override string AddTableRemarkSql => "comment on table {0} is '{1}'"; + + protected override string DeleteTableRemarkSql => "comment on table {0} is ''"; + + protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } } + + protected override string RenameTableSql => "alter table 表名 {0} to {1}"; + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}"; + } + } + protected override string IsAnyIndexSql + { + get + { + return " Select count(1) from (SELECT to_regclass('{0}') as c ) t where t.c is not null"; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select 1 from INFO_SCHEM.ALL_TAB_COLUMNS limit 1 offset 0"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "DEFAULT NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "serial"; + } + } + #endregion + + #region Methods + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + string type = GetType(tableName, columnInfo); + //this.Context.Ado.ExecuteCommand(sql); + + string sql = @"ALTER TABLE {table} ALTER TYPE {column} {type};ALTER TABLE {table} ALTER COLUMN {column} {null}"; + + var isnull = columnInfo.IsNullable ? " DROP NOT NULL " : " SET NOT NULL "; + + sql = sql.Replace("{table}", tableName) + .Replace("{type}", type) + .Replace("{column}", columnName) + .Replace("{null}", isnull); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + + protected string GetType(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + //if (!string.IsNullOrEmpty(dataType)) + //{ + // dataType = dataType; + //} + return dataType + "" + dataSize; + } + protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + if (!string.IsNullOrEmpty(dataType)) + { + dataType = " type " + dataType; + } + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + + /// + ///by current connection string + /// + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + throw new NotSupportedException("Not Supported CreateDatabase"); + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + + } + } + //table remak + if (entity.TableDescription != null) + { + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + item.Length = 10; + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower())))); + + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + 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 = item.DbColumnName; + string dataType = item.DataType; + if (dataType == "varchar" && item.Length == 0) + { + item.Length = 1; + } + if (dataType == "uuid") + { + item.Length = 50; + dataType = "varchar"; + } + string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + if (item.DecimalDigits > 0 && item.Length > 0 && dataType == "numeric") + { + dataSize = $"({item.Length},{item.DecimalDigits})"; + } + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower()), dataType, dataSize, nullType, primaryKey, ""); + if (item.IsIdentity) + { + string length = dataType.Substring(dataType.Length - 1); + string identityDataType = "serial" + length; + addItem = addItem.Replace(dataType, identityDataType); + } + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName.ToLower()), string.Join(",\r\n", columnArray)); + return tableString; + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported"); + return false; + } + + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + var result = base.GetColumnInfosByTableName(tableName.TrimStart('"').TrimEnd('"'), isCache); + foreach (var columnInfo in result) + { + if (columnInfo.IsIdentity && !columnInfo.DataType.ObjToString().Contains("int", StringComparison.CurrentCultureIgnoreCase)) + { + columnInfo.IsIdentity = false; + } + } + string sql = "select * from " + SqlBuilder.GetTranslationTableName(tableName) + " WHERE 1=2 "; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + using (DbDataReader reader = (DbDataReader)this.Context.Ado.GetDataReader(sql)) + { + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + var schemaTable = reader.GetSchemaTable(); + foreach (System.Data.DataRow row in schemaTable.Rows) + { + var name = row["columnname"] + ""; + var data = result.First(it => it.DbColumnName.Equals(name, StringComparison.OrdinalIgnoreCase)); + data.IsPrimarykey = row["iskey"].ToString() == "True" ? true : false; + } + } + return result; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/Insertable/OscarInserttable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/Insertable/OscarInserttable.cs new file mode 100644 index 000000000..b2e87c471 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/Insertable/OscarInserttable.cs @@ -0,0 +1,67 @@ +namespace SqlSugar +{ + public class OscarInserttable : InsertableProvider where T : class, new() + { + public override int ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + var result = Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ObjToInt(); + return result; + } + public override async Task ExecuteReturnIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + var obj = await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + var result = obj.ObjToInt(); + return result; + } + public override KeyValuePair> ToSql() + { + var result = base.ToSql(); + return new KeyValuePair>(result.Key.Replace("$PrimaryKey", GetPrimaryKeys().FirstOrDefault()), result.Value); + } + + public override long ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + var result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0"); + return result; + } + public override async Task ExecuteReturnBigIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + var result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false) ?? "0"); + return result; + } + + public override bool ExecuteCommandIdentityIntoEntity() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (identityKeys.Count == 0) { return this.ExecuteCommand() > 0; } + var idValue = ExecuteReturnBigIdentity(); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else + setValue = Convert.ToInt32(idValue); + var propertyName = this.Context.EntityMaintenance.GetPropertyName(identityKey); + typeof(T).GetProperties().First(t => t.Name.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)).SetValue(result, setValue, null); + return idValue > 0; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/OscarProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/OscarProvider.cs new file mode 100644 index 000000000..8fbebcd60 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/OscarProvider.cs @@ -0,0 +1,158 @@ +using System.Data; +using System.Data.Common; +using System.Data.OscarClient; + +namespace SqlSugar +{ + public partial class OscarProvider : AdoProvider + { + public OscarProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var OscarConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + base._DbConnection = new OscarConnection(OscarConnectionString); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new OscarDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + OscarCommand sqlCommand = new OscarCommand(sql, (OscarConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (OscarTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((OscarParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((OscarDataAdapter)dataAdapter).SelectCommand = (OscarCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + OscarParameter[] result = new OscarParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new OscarParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + if (parameter.IsJson) + { + sqlParameter.OscarDbType = OscarDbType.Text; + } + if (parameter.IsArray) + { + // sqlParameter.Value = this.Context.Utilities.SerializeObject(sqlParameter.Value); + var type = sqlParameter.Value.GetType(); + if (ArrayMapping.TryGetValue(type, out OscarDbType value)) + { + sqlParameter.OscarDbType = value | OscarDbType.Array; + } + else + { + Check.Exception(true, sqlParameter.Value.GetType().Name + " No Support"); + } + } + if (sqlParameter.Direction == 0) + { + sqlParameter.Direction = ParameterDirection.Input; + } + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + ++index; + } + return result; + } + + + static readonly Dictionary ArrayMapping = new Dictionary() + { + { typeof(int[]),OscarDbType.Integer}, + { typeof(short[]),OscarDbType.SmallInt}, + { typeof(long[]),OscarDbType.BigInt}, + { typeof(decimal[]),OscarDbType.Numeric}, + { typeof(char[]),OscarDbType.Text}, + { typeof(byte[]),OscarDbType.Bytea}, + { typeof(bool[]),OscarDbType.Boolean}, + {typeof(DateTime[]),OscarDbType.Date}, + {typeof(float[]),OscarDbType.Real}, + + + { typeof(int?[]),OscarDbType.Integer}, + { typeof(short?[]),OscarDbType.SmallInt}, + { typeof(long?[]),OscarDbType.BigInt}, + { typeof(decimal?[]),OscarDbType.Numeric}, + { typeof(char?[]),OscarDbType.Text}, + { typeof(byte?[]),OscarDbType.Bytea}, + { typeof(bool?[]),OscarDbType.Boolean}, + {typeof(DateTime?[]),OscarDbType.Date}, + + + { typeof(string[]), OscarDbType.Text}, + {typeof(float?[]),OscarDbType.Real}, + }; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/Queryable/OscarQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/Queryable/OscarQueryable.cs new file mode 100644 index 000000000..216a2056c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/Queryable/OscarQueryable.cs @@ -0,0 +1,63 @@ +namespace SqlSugar +{ + public class OscarQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + this.GroupBy(groupFileds); + return this; + } + } + public class OscarQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } + public class OscarQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarBuilder.cs new file mode 100644 index 000000000..f18ea4e20 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarBuilder.cs @@ -0,0 +1,97 @@ +namespace SqlSugar +{ + public class OscarBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string SqlDateNow + { + get + { + return "current_date"; + } + } + public override string FullSqlDateNow + { + get + { + return "select current_date"; + } + } + + public bool isAutoToUpper + { + get + { + if (this.Context?.CurrentConnectionConfig?.MoreSettings == null) return true; + return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper; + } + } + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains('.') && !propertyName.Contains(SqlTranslationLeft)) + { + return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToUpper(isAutoToUpper)}{SqlTranslationRight}")); + } + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + else + return SqlTranslationLeft + propertyName.ToUpper(isAutoToUpper) + SqlTranslationRight; + } + + //public override string GetNoTranslationColumnName(string name) + //{ + // return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower(); + //} + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToUpper(isAutoToUpper) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToUpper(isAutoToUpper) + SqlTranslationRight); + } + + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table 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.Contains('.') && !name.Contains('(')) + { + return string.Join(".", name.ToUpper(isAutoToUpper).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else if (name.Contains('(')) + { + return name; + } + else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else + { + return SqlTranslationLeft + name.ToUpper(isAutoToUpper).TrimEnd('"').TrimStart('"') + SqlTranslationRight; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarDeleteBuilder.cs new file mode 100644 index 000000000..2b3f59941 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class OscarDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarExpressionContext.cs new file mode 100644 index 000000000..20f8e6548 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarExpressionContext.cs @@ -0,0 +1,258 @@ +namespace SqlSugar +{ + public class OscarExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public bool isAutoToUpper + { + get + { + if (this?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings == null) return true; + return this.SugarContext.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper; + } + } + public OscarExpressionContext() + { + base.DbMehtods = new OscarLMethod(); + } + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string GetTranslationText(string name) + { + return SqlTranslationLeft + name.ToUpper(isAutoToUpper) + SqlTranslationRight; + } + + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + + var tableName = mappingInfo?.DbTableName + ""; + if (tableName.Contains('.')) + { + tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + return tableName; + } + + return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToUpper(isAutoToUpper) + SqlTranslationRight; + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public override string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord) + { + return columnName; + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public override string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToUpper(isAutoToUpper); + } + else + { + return propertyName.ToUpper(isAutoToUpper); + } + } + } + public class OscarLMethod : DefaultDbMethod, IDbMethods + { + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter.Type == UtilConstants.BoolType) + { + parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); + parameter2.MemberName = false; + parameter3.MemberName = true; + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + if (parameter.MemberName != null && parameter.MemberName is DateTime) + { + return string.Format(" datepart({0},'{1}') ", parameter2.MemberValue, parameter.MemberName); + } + else + { + return string.Format(" datepart({0},{1}) ", parameter2.MemberValue, parameter.MemberName); + } + } + + public override string Contains(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string StartsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat({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 concat('%',{1}))", parameter.MemberName, parameter2.MemberName); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" (date_part('day',{0}-{1})=0) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" (date_part('{2}',{0}-{1})=0) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS timestamp)", parameter.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT4)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT8)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR(1024))", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS boolean)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string MergeString(params string[] strings) + { + return " concat(" + string.Join(",", strings).Replace("+", "") + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName); + } + public override string GetDate() + { + return "SYSDATE()"; + } + public override string GetRandom() + { + return "RANDOM()"; + } + + public override string EqualTrue(string fieldName) + { + return "( " + fieldName + "=true )"; + } + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" DATEDIFF('{0}',{1},{2}) ", parameter.MemberValue?.ToString().ToSqlFilter(), parameter2.MemberName, parameter3.MemberName); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarInsertBuilder.cs new file mode 100644 index 000000000..e387d39e3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarInsertBuilder.cs @@ -0,0 +1,95 @@ +using System.Text; + +namespace SqlSugar +{ + public class OscarInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) returning $PrimaryKey"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + public override string SqlTemplateBatchUnion => " VALUES "; + + public override string SqlTemplateBatchSelect => " {0} "; + + 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 => base.GetDbColumn(it, Builder.GetTranslationColumnName(it.DbColumnName)))); + if (isSingle) + { + string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => Builder.SqlParameterKeyWord + it.DbColumnName)); + return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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 ( " + string.Join(",", columns.Select(it => + { + if (it.InsertServerTime || it.InsertSql.HasValue()) + { + return GetDbColumn(it, null); + } + object value = null; + if (it.Value is DateTime) + { + value = ((DateTime)it.Value).ToString("O"); + } + else + { + value = it.Value; + } + if (value == null || value == DBNull.Value) + { + return string.Format(SqlTemplateBatchSelect, "NULL"); + } + return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToString().ToSqlFilter() + "'"); + })) + "),"); + ++i; + } + pageIndex++; + batchInsetrSql.Remove(batchInsetrSql.Length - 1, 1).Append("\r\n;\r\n"); + } + return batchInsetrSql.ToString(); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarQueryBuilder.cs new file mode 100644 index 000000000..9efdfd344 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarQueryBuilder.cs @@ -0,0 +1,93 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class OscarQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 10 offset 0 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {6} offset {5}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override bool IsComplexModel(string sql) + { + return 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 (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); + return result; + } + + #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)); + } + return result; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarUpdateBuilder.cs new file mode 100644 index 000000000..a612f2153 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Oscar/SqlBuilder/OscarUpdateBuilder.cs @@ -0,0 +1,104 @@ +using System.Text; + +namespace SqlSugar +{ + public class OscarUpdateBuilder : UpdateBuilder + { + public override string SqlTemplateBatch + { + get + { + return @"UPDATE {1} {2} SET {0} FROM ${{0}} "; + } + } + public override string SqlTemplateJoin + { + get + { + return @" (VALUES + {0} + + ) AS T ({2}) WHERE {1} + "; + } + } + + public override string SqlTemplateBatchUnion + { + get + { + return ","; + } + } + + public override object FormatValue(object value) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = value.GetType(); + if (type == UtilConstants.DateType) + { + var date = value.ObjToDate(); + if (date < Convert.ToDateTime("1900-1-1")) + { + date = Convert.ToDateTime("1900-1-1"); + } + return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + return bytesString; + } + else if (type.IsEnum()) + { + return Convert.ToInt64(value); + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + protected override string TomultipleSqlString(List> groupList) + { + StringBuilder sb = new StringBuilder(); + int i = 0; + sb.AppendLine(string.Join("\r\n", 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)).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); + whereList.Add(whereString); + } + i++; + return string.Format("{0} {1} WHERE {2};", updateTable, setValues, string.Join("AND", whereList)); + }).ToArray())); + return sb.ToString(); + } + private string GetOracleUpdateColums(int i, DbColumnInfo m) + { + return string.Format("\"{0}\"={1}", m.DbColumnName.ToUpper(), base.GetDbColumn(m, FormatValue(m.Value))); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/CodeFirst/PostgreSQLCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/CodeFirst/PostgreSQLCodeFirst.cs new file mode 100644 index 000000000..7594b889f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/CodeFirst/PostgreSQLCodeFirst.cs @@ -0,0 +1,85 @@ +namespace SqlSugar +{ + public class PostgreSQLCodeFirst : CodeFirstProvider + { + 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()); + } + } + } + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + } + } + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + CreateTableFieldSort = item.CreateTableFieldSort + }; + if (propertyType == UtilConstants.DecType) + { + result.Scale = item.DecimalDigits; + result.DecimalDigits = item.DecimalDigits; + } + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName, null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbBind/PostgreSQLDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbBind/PostgreSQLDbBind.cs new file mode 100644 index 000000000..433ca562a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbBind/PostgreSQLDbBind.cs @@ -0,0 +1,189 @@ +namespace SqlSugar +{ + public class PostgreSQLDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + csharpTypeName = GetValidCsharpTypeName(csharpTypeName); + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "bytea"; + if (csharpTypeName.Equals("int32", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "int"; + if (csharpTypeName.Equals("int16", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "short"; + if (csharpTypeName.Equals("int64", StringComparison.CurrentCultureIgnoreCase)) + csharpTypeName = "long"; + if (csharpTypeName.ToLower().IsIn("boolean", "bool")) + csharpTypeName = "bool"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + if (mappings?.Count > 0) + return mappings.First().Key; + else + return "varchar"; + } + + private string GetValidCsharpTypeName(string csharpTypeName) + { + if (csharpTypeName?.StartsWith("ora") == true && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase) + { + csharpTypeName = csharpTypeName.Replace("ora", ""); + } + else if (csharpTypeName?.StartsWith("mssql_") == true && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase) + { + csharpTypeName = csharpTypeName.Replace("mssql_", ""); + } + else if (csharpTypeName?.StartsWith("sys.") == true) + { + csharpTypeName = csharpTypeName.Replace("sys.", ""); + } + return csharpTypeName; + } + + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + dbTypeName = GetValidCsharpTypeName(dbTypeName); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json") + { + return "string"; + } + else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + { + return "char"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes?.Any() != true) + { + if (dbTypeName.StartsWith('_')) + { + var dbTypeName2 = dbTypeName.TrimStart('_'); + return MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName2, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName2, StringComparison.CurrentCultureIgnoreCase)).Select(it => it.Value + "[]").First(); + } + else if (dbTypeName.EndsWith("geometry") || dbTypeName.EndsWith("geography")) + { + return CSharpDataType.@string.ToString(); + } + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("int2",CSharpDataType.@short), + //new KeyValuePair("int1",CSharpDataType.@byte), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("smallint",CSharpDataType.@byte), + new KeyValuePair("int4",CSharpDataType.@int), + new KeyValuePair("serial",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("int8",CSharpDataType.@long), + new KeyValuePair("long",CSharpDataType.@long), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("float4",CSharpDataType.@float), + new KeyValuePair("float4",CSharpDataType.Single), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("float8",CSharpDataType.@double), + new KeyValuePair("double precision",CSharpDataType.@int), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("path",CSharpDataType.@decimal), + new KeyValuePair("point",CSharpDataType.@decimal), + new KeyValuePair("polygon",CSharpDataType.@decimal), + + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("bool",CSharpDataType.@bool), + new KeyValuePair("box",CSharpDataType.@bool), + new KeyValuePair("bytea",CSharpDataType.byteArray), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("clob",CSharpDataType.@string), + new KeyValuePair("nvarchar2",CSharpDataType.@string), + new KeyValuePair("varchar2",CSharpDataType.@string), + new KeyValuePair("character varying",CSharpDataType.@string), + new KeyValuePair("geometry",CSharpDataType.@string), + new KeyValuePair("name",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("character",CSharpDataType.@string), + new KeyValuePair("cidr",CSharpDataType.@string), + new KeyValuePair("circle",CSharpDataType.@string), + new KeyValuePair("tsquery",CSharpDataType.@string), + new KeyValuePair("tsvector",CSharpDataType.@string), + new KeyValuePair("txid_snapshot",CSharpDataType.@string), + new KeyValuePair("uuid",CSharpDataType.Guid), + new KeyValuePair("xml",CSharpDataType.@string), + new KeyValuePair("json",CSharpDataType.@string), + + new KeyValuePair("interval",CSharpDataType.@decimal), + new KeyValuePair("lseg",CSharpDataType.@decimal), + new KeyValuePair("macaddr",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamptz",CSharpDataType.DateTime), + new KeyValuePair("timestamp without time zone",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("time with time zone",CSharpDataType.DateTime), + new KeyValuePair("timetz",CSharpDataType.DateTime), + new KeyValuePair("time without time zone",CSharpDataType.DateTime), + + new KeyValuePair("bit",CSharpDataType.byteArray), + new KeyValuePair("bit varying",CSharpDataType.byteArray), + new KeyValuePair("varbit",CSharpDataType.@byte), + new KeyValuePair("time",CSharpDataType.TimeSpan), + new KeyValuePair("public.geometry",CSharpDataType.@object), + new KeyValuePair("public.geography",CSharpDataType.@object), + new KeyValuePair("inet",CSharpDataType.@object), + + new KeyValuePair("number",CSharpDataType.@int), + new KeyValuePair("number",CSharpDataType.@float), + new KeyValuePair("number",CSharpDataType.@short), + new KeyValuePair("number",CSharpDataType.@byte), + new KeyValuePair("number",CSharpDataType.@double), + new KeyValuePair("number",CSharpDataType.@long), + new KeyValuePair("number",CSharpDataType.@bool), + new KeyValuePair("number",CSharpDataType.@decimal), + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbFirst/PostgreSQLDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbFirst/PostgreSQLDbFirst.cs new file mode 100644 index 000000000..f9bf212ca --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbFirst/PostgreSQLDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class PostgreSQLDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs new file mode 100644 index 000000000..0a1e47221 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs @@ -0,0 +1,656 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class PostgreSQLDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + return "SELECT datname FROM pg_database"; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string schema = GetSchema(); + string sql = @"select cast (pclass.oid as int4) as TableId,cast(ptables.tablename as varchar) as TableName, + pcolumn.column_name as DbColumnName,pcolumn.udt_name as DataType, + CASE WHEN pcolumn.numeric_scale >0 THEN pcolumn.numeric_precision ELSE pcolumn.character_maximum_length END as Length, + pcolumn.column_default as DefaultValue, + pcolumn.numeric_scale as DecimalDigits, + pcolumn.numeric_scale as Scale, + col_description(pclass.oid, pcolumn.ordinal_position) as ColumnDescription, + case when pkey.colname = pcolumn.column_name + then true else false end as IsPrimaryKey, + CASE + WHEN (current_setting('server_version_num')::INT >= 100000 AND pcolumn.is_identity = 'YES') THEN true + WHEN pcolumn.column_default LIKE 'nextval%' THEN true + ELSE false + END AS IsIdentity, + case when pcolumn.is_nullable = 'YES' + then true else false end as IsNullable + from (select * from pg_tables where upper(tablename) = upper('{0}') and schemaname='" + schema + @"') ptables inner join pg_class pclass + on ptables.tablename = pclass.relname inner join (SELECT * + FROM information_schema.columns where table_schema='" + schema + @"' + ) pcolumn on pcolumn.table_name = ptables.tablename and upper(pcolumn.table_name) = upper('{0}') + left join ( + select pg_class.relname,pg_attribute.attname as colname from + pg_constraint inner join pg_class + on pg_constraint.conrelid = pg_class.oid + inner join pg_attribute on pg_attribute.attrelid = pg_class.oid + and pg_attribute.attnum = pg_constraint.conkey[1] + inner join pg_type on pg_type.oid = pg_attribute.atttypid + where pg_constraint.contype='p' + ) pkey on pcolumn.table_name = pkey.relname + order by table_catalog, table_schema, ordinal_position"; + return sql; + } + } + + protected override string GetTableInfoListSql + { + get + { + var schema = GetSchema(); + return @"select cast(relname as varchar) as Name, + cast(obj_description(c.oid,'pg_class') as varchar) as Description from pg_class c + inner join + pg_namespace n on n.oid = c.relnamespace and nspname='" + schema + @"' + inner join + pg_tables z on z.tablename=c.relname + where relkind in('p', 'r') and relname not like 'pg\_%' and relname not like 'sql\_%' and schemaname='" + schema + "' order by relname"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select table_name as name from information_schema.views where table_schema ='" + GetSchema() + "' "; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "alter table {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return "mysqldump.exe {0} -uroot -p > {1} "; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {0} as (select * from {1} limit {2} offset 0)"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} RENAME {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 { throw new NotSupportedException(); } } + + protected override string AddTableRemarkSql => "comment on table {0} is '{1}'"; + + protected override string DeleteTableRemarkSql => "comment on table {0} is ''"; + + protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } } + + protected override string RenameTableSql => "alter table {0} rename to {1}"; + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}"; + } + } + protected override string IsAnyIndexSql + { + get + { + return " SELECT count(1) WHERE upper('{0}') IN ( SELECT upper(indexname) FROM pg_indexes )"; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select 1 from information_schema.columns limit 1 offset 0"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "DEFAULT NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "serial"; + } + } + #endregion + + #region Methods + public override bool IsAnyTable(string tableName, bool isCache = true) + { + if (isCache == false) + { + var sql = $" SELECT 1 FROM pg_catalog.pg_tables \r\n WHERE schemaname = '" + GetSchema() + "' \r\n AND Lower(tablename) = '" + tableName.ToLower() + "' "; + return this.Context.Ado.GetInt(sql) > 0; + } + else + { + return base.IsAnyTable(tableName, isCache); + } + } + public override List GetDbTypes() + { + var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT data_type +FROM information_schema.columns"); + result.Add("varchar"); + result.Add("timestamp"); + result.Add("uuid"); + result.Add("int2"); + result.Add("int4"); + result.Add("int8"); + result.Add("time"); + result.Add("date"); + result.Add("float8"); + result.Add("float4"); + result.Add("json"); + result.Add("jsonp"); + return result.Distinct().ToList(); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT tgname +FROM pg_trigger +WHERE tgrelid = '" + tableName + "'::regclass"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery(" SELECT routine_name\r\nFROM information_schema.routines\r\nWHERE lower( routine_schema ) = '" + GetSchema().ToLower() + "' AND routine_type = 'FUNCTION' "); + } + public override List GetIndexList(string tableName) + { + var sql = $"SELECT indexname, indexdef FROM pg_indexes WHERE upper(tablename) = upper('{tableName}') AND upper(schemaname) = upper('{GetSchema()}')"; + return this.Context.Ado.SqlQuery(sql); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT proname FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname = '{dbName}'"; + return this.Context.Ado.SqlQuery(sql); + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue?.StartsWith('\'') == true && defaultValue?.EndsWith('\'') == true && defaultValue?.Contains('(') == false + && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue.EqualCase("current_timestamp") || defaultValue.EqualCase("current_date")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.Contains('(') == false + && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), "'" + defaultValue + "'"); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.ToLower()?.Contains("cast(") == true && defaultValue?.StartsWith('\'') == true && defaultValue?.EndsWith('\'') == true) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue.Replace("''", "'").TrimEnd('\'').TrimStart('\'')); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.ToLower()?.Contains("now()") == true) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue.TrimEnd('\'').TrimStart('\'')); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else + { + return base.AddDefaultValue(this.SqlBuilder.GetTranslationTableName(tableName), this.SqlBuilder.GetTranslationTableName(columnName), defaultValue); + } + } + + public override bool RenameTable(string oldTableName, string newTableName) + { + return base.RenameTable(this.SqlBuilder.GetTranslationTableName(oldTableName), this.SqlBuilder.GetTranslationTableName(newTableName)); + } + + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string sql = string.Format(this.AddColumnRemarkSql, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddTableRemark(string tableName, string description) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + return base.AddTableRemark(tableName, description); + } + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + ConvertCreateColumnInfo(columnInfo); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + string sql = GetUpdateColumnSql(tableName, columnInfo); + this.Context.Ado.ExecuteCommand(sql); + var isnull = columnInfo.IsNullable ? " DROP NOT NULL " : " SET NOT NULL "; + this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}", tableName, columnName, isnull)); + return true; + } + + protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + if (!string.IsNullOrEmpty(dataType)) + { + dataType = " type " + dataType; + } + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + + /// + ///by current connection string + /// + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + if (databaseDirectory != null) + { + if (!FileHelper.IsExistDirectory(databaseDirectory)) + { + FileHelper.CreateDirectory(databaseDirectory); + } + } + var oldDatabaseName = this.Context.Ado.Connection.Database; + var connection = this.Context.CurrentConnectionConfig.ConnectionString; + if (Regex.Matches(connection, oldDatabaseName).Count > 1) + { + var builder = new Npgsql.NpgsqlConnectionStringBuilder(connection); + builder.Database = "postgres"; + connection = builder.ConnectionString; + } + else + { + connection = connection.Replace(oldDatabaseName, "postgres"); + } + var newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = connection + }); + if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) + { + var isVast = this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase; + var dbcompatibility = ""; + if (isVast) + { + dbcompatibility = " dbcompatibility = 'PG'"; + } + newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft + databaseName + this.SqlBuilder.SqlTranslationRight, databaseDirectory) + dbcompatibility); + } + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + + } + } + //table remak + if (entity.TableDescription != null) + { + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + ConvertCreateColumnInfo(item); + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + if (item.DataType?.ToLower() != "uuid") + { + item.Length = 10; + } + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower(isAutoToLowerCodeFirst))))); + + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + protected override bool IsAnyDefaultValue(string tableName, string columnName, List columns) + { + var defaultValue = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)).First().DefaultValue; + if (defaultValue?.StartsWith("NULL::") == true) + { + return false; + } + return defaultValue.HasValue(); + } + 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 = item.DbColumnName; + string dataType = item.DataType; + if (dataType == "varchar" && item.Length == 0) + { + item.Length = 1; + } + //if (dataType == "uuid") + //{ + // item.Length = 50; + // dataType = "varchar"; + //} + string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + if (item.DecimalDigits > 0 && item.Length > 0 && dataType == "numeric") + { + dataSize = $"({item.Length},{item.DecimalDigits})"; + } + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), dataType, dataSize, nullType, primaryKey, ""); + if (item.IsIdentity) + { + if (dataType?.ToLower() == "int") + { + dataSize = "int4"; + } + else if (dataType?.ToLower() == "long") + { + dataSize = "int8"; + } + string length = dataType.Substring(dataType.Length - 1); + string identityDataType = "serial" + length; + addItem = addItem.Replace(dataType, identityDataType); + } + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName.ToLower(isAutoToLowerCodeFirst)), string.Join(",\r\n", columnArray)); + return tableString; + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported"); + return false; + } + + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + var result = base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); + if (result == null || result.Count == 0) + { + result = base.GetColumnInfosByTableName(tableName, isCache); + } + try + { + string sql = $@"select + kcu.column_name as key_column + from information_schema.table_constraints tco + join information_schema.key_column_usage kcu + on kcu.constraint_name = tco.constraint_name + and kcu.constraint_schema = tco.constraint_schema + and kcu.constraint_name = tco.constraint_name + where tco.constraint_type = 'PRIMARY KEY' + and kcu.table_schema='{GetSchema()}' and + upper(kcu.table_name)=upper('{tableName.TrimEnd('"').TrimStart('"')}')"; + List pkList = new List(); + if (isCache) + { + pkList = GetListOrCache("GetColumnInfosByTableName_N_Pk" + tableName, sql); + } + else + { + pkList = this.Context.Ado.SqlQuery(sql); + } + if (pkList.Count > 1) + { + foreach (var item in result) + { + if (pkList.Select(it => it.ToUpper()).Contains(item.DbColumnName.ToUpper())) + { + item.IsPrimarykey = true; + } + } + } + } + catch + { + + } + return result; + } + #endregion + + #region Helper + private bool isAutoToLowerCodeFirst + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true; + else if ( + this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower == false && + this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLowerCodeFirst == false) + { + return false; + } + else + { + return true; + } + } + } + private string GetSchema() + { + var schema = "public"; + var pgSqlIsAutoToLowerSchema = this.Context?.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLowerSchema == false; + if (pgSqlIsAutoToLowerSchema) + { + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString, "searchpath=", RegexOptions.IgnoreCase)) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString, @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString, "search path=", RegexOptions.IgnoreCase)) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + } + else + { + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + } + return schema; + } + private static void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "uuid", "int4", "text", "int2", "int8", "date", "bit", "text", "timestamp" }; + + if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/Insertable/PostgreSQLInserttable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/Insertable/PostgreSQLInserttable.cs new file mode 100644 index 000000000..fd2c3c042 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/Insertable/PostgreSQLInserttable.cs @@ -0,0 +1,98 @@ +namespace SqlSugar +{ + public class PostgreSQLInserttable : InsertableProvider where T : class, new() + { + public override int ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string identityColumn = GetIdentityColumn(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn)); + RestoreMapping(); + AutoRemoveDataCache(); + var result = Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ObjToInt(); + After(sql, result); + return result; + } + public override async Task ExecuteReturnIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string identityColumn = GetIdentityColumn(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn)); + RestoreMapping(); + AutoRemoveDataCache(); + var obj = await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + var result = obj.ObjToInt(); + After(sql, result); + return result; + } + public override KeyValuePair> ToSql() + { + var result = base.ToSql(); + var primaryKey = GetPrimaryKeys().FirstOrDefault(); + if (primaryKey != null) + { + primaryKey = this.SqlBuilder.GetTranslationColumnName(primaryKey); + } + else if (result.Key?.EndsWith(" returning $PrimaryKey") == true) + { + result = new KeyValuePair>(result.Key.Replace(" returning $PrimaryKey", null), result.Value); + } + return new KeyValuePair>(result.Key.Replace("$PrimaryKey", primaryKey), result.Value); + } + + public override long ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + AutoRemoveDataCache(); + var result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0"); + After(sql, result); + return result; + } + public override async Task ExecuteReturnBigIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + AutoRemoveDataCache(); + var result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false) ?? "0"); + After(sql, result); + return result; + } + + public override bool ExecuteCommandIdentityIntoEntity() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (identityKeys.Count == 0) { return this.ExecuteCommand() > 0; } + var idValue = ExecuteReturnBigIdentity(); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else + setValue = Convert.ToInt32(idValue); + var propertyName = this.Context.EntityMaintenance.GetPropertyName(identityKey); + typeof(T).GetProperties().First(t => t.Name.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)).SetValue(result, setValue, null); + return idValue > 0; + } + + private string GetIdentityColumn() + { + var identityColumn = GetIdentityKeys().FirstOrDefault(); + if (identityColumn == null) + { + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(InsertBuilder.GetTableNameString); + identityColumn = columns.First(it => it.IsIdentity || it.IsPrimarykey).DbColumnName; + } + return identityColumn; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/PostgreSQLProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/PostgreSQLProvider.cs new file mode 100644 index 000000000..7e367e872 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/PostgreSQLProvider.cs @@ -0,0 +1,275 @@ +using Npgsql; + +using NpgsqlTypes; + +using System.Data; +using System.Data.Common; + +namespace SqlSugar +{ + public partial class PostgreSQLProvider : AdoProvider + { + public PostgreSQLProvider() + { + + if (StaticConfig.AppContext_ConvertInfinityDateTime == false) + { + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); + AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true); + } + + } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var npgsqlConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + base._DbConnection = new NpgsqlConnection(npgsqlConnectionString); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new NpgsqlDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + NpgsqlCommand sqlCommand = new NpgsqlCommand(sql, (NpgsqlConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (NpgsqlTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((NpgsqlParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((NpgsqlDataAdapter)dataAdapter).SelectCommand = (NpgsqlCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + NpgsqlParameter[] result = new NpgsqlParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.DbType == System.Data.DbType.Int64 && parameter.Value?.Equals("Result%") == true) + { + parameter.DbType = System.Data.DbType.AnsiString; + } + UNumber(parameter); + if (parameter.Value == null) parameter.Value = DBNull.Value; + if (parameter.Value is System.Data.SqlTypes.SqlDateTime && parameter.DbType == System.Data.DbType.AnsiString) + { + parameter.DbType = System.Data.DbType.DateTime; + parameter.Value = DBNull.Value; + } + var sqlParameter = new NpgsqlParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + if (parameter.IsJson) + { + sqlParameter.NpgsqlDbType = NpgsqlDbType.Json; + } + if (parameter.IsArray) + { + Array(parameter, sqlParameter); + } + if (sqlParameter.Direction == 0) + { + sqlParameter.Direction = ParameterDirection.Input; + } + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + else if (sqlParameter.Value is DateTime && sqlParameter.DbType == System.Data.DbType.AnsiString) + { + sqlParameter.DbType = System.Data.DbType.DateTime; + } + ++index; + if (parameter.CustomDbType != null && parameter.CustomDbType is NpgsqlDbType) + { + sqlParameter.NpgsqlDbType = ((NpgsqlDbType)parameter.CustomDbType); + } + } + return result; + } + + //private static void ConvertUNumber(SugarParameter parameter) + //{ + // if (parameter.DbType == System.Data.DbType.UInt32) + // { + // parameter.DbType = System.Data.DbType.Int32; + // } + // else if (parameter.DbType == System.Data.DbType.UInt64) + // { + // parameter.DbType = System.Data.DbType.UInt64; + // } + //} + + private static void Array(SugarParameter parameter, NpgsqlParameter sqlParameter) + { + // sqlParameter.Value = this.Context.Utilities.SerializeObject(sqlParameter.Value); + var type = sqlParameter.Value.GetType(); + if (ArrayMapping.TryGetValue(type, out NpgsqlDbType value)) + { + sqlParameter.NpgsqlDbType = value | NpgsqlDbType.Array; + } + else if (type == DBNull.Value.GetType()) + { + DbNullParametrerArray(parameter, sqlParameter); + + } + else + { + Check.Exception(true, sqlParameter.Value.GetType().Name + " No Support"); + } + } + + private static void DbNullParametrerArray(SugarParameter parameter, NpgsqlParameter sqlParameter) + { + if (parameter.DbType.IsIn(System.Data.DbType.Int32)) + { + sqlParameter.NpgsqlDbType = NpgsqlDbType.Integer | NpgsqlDbType.Array; + } + else if (parameter.DbType.IsIn(System.Data.DbType.Int16)) + { + sqlParameter.NpgsqlDbType = NpgsqlDbType.Smallint | NpgsqlDbType.Array; + } + else if (parameter.DbType.IsIn(System.Data.DbType.Int64)) + { + sqlParameter.NpgsqlDbType = NpgsqlDbType.Bigint | NpgsqlDbType.Array; + } + else if (parameter.DbType.IsIn(System.Data.DbType.Guid)) + { + sqlParameter.NpgsqlDbType = NpgsqlDbType.Uuid | NpgsqlDbType.Array; + } + else + { + sqlParameter.NpgsqlDbType = NpgsqlDbType.Text | NpgsqlDbType.Array; + } + } + + private static void UNumber(SugarParameter parameter) + { + if (parameter.DbType == System.Data.DbType.UInt16) + { + parameter.DbType = System.Data.DbType.Int16; + parameter.Value = Convert.ToInt16(parameter.Value); + } + else if (parameter.DbType == System.Data.DbType.UInt32) + { + parameter.DbType = System.Data.DbType.Int32; + parameter.Value = Convert.ToInt32(parameter.Value); + } + else if (parameter.DbType == System.Data.DbType.UInt64) + { + parameter.DbType = System.Data.DbType.Int64; + parameter.Value = Convert.ToInt64(parameter.Value); + } + if (parameter.Value is uint) + { + parameter.Value = Convert.ToInt32(parameter.Value); + } + else if (parameter.Value is ulong) + { + parameter.Value = Convert.ToInt64(parameter.Value); + } + } + public override Action ErrorEvent => it => + { + if (base.ErrorEvent != null) + { + base.ErrorEvent(it); + } + if (it.Message?.StartsWith("42883: function uuid_generate_v4() does not exist") == true) + { + Check.ExceptionEasy(it.Message, $"使用uuid_generate_v4()函数需要创建 CREATE EXTENSION IF NOT EXISTS pgcrypto;CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\" "); + } + }; + + static readonly Dictionary ArrayMapping = new Dictionary() + { + { typeof(int[]),NpgsqlDbType.Integer}, + { typeof(short[]),NpgsqlDbType.Smallint}, + { typeof(long[]),NpgsqlDbType.Bigint}, + { typeof(decimal[]),NpgsqlDbType.Numeric}, + { typeof(double[]),NpgsqlDbType.Double}, + { typeof(char[]),NpgsqlDbType.Text}, + { typeof(byte[]),NpgsqlDbType.Bytea}, + { typeof(bool[]),NpgsqlDbType.Boolean}, + {typeof(DateTime[]),NpgsqlDbType.Date}, + {typeof(float[]),NpgsqlDbType.Real}, + {typeof(Guid[]),NpgsqlDbType.Uuid}, + + + { typeof(int?[]),NpgsqlDbType.Integer}, + { typeof(short?[]),NpgsqlDbType.Smallint}, + { typeof(long?[]),NpgsqlDbType.Bigint}, + { typeof(decimal?[]),NpgsqlDbType.Numeric}, + { typeof(double?[]),NpgsqlDbType.Double}, + { typeof(char?[]),NpgsqlDbType.Text}, + { typeof(byte?[]),NpgsqlDbType.Bytea}, + { typeof(bool?[]),NpgsqlDbType.Boolean}, + {typeof(DateTime?[]),NpgsqlDbType.Date}, + {typeof(Guid?[]),NpgsqlDbType.Uuid}, + + + { typeof(string[]), NpgsqlDbType.Text}, + {typeof(float?[]),NpgsqlDbType.Real}, + }; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/Queryable/PostgreSqlQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/Queryable/PostgreSqlQueryable.cs new file mode 100644 index 000000000..f9306301a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/Queryable/PostgreSqlQueryable.cs @@ -0,0 +1,63 @@ +namespace SqlSugar +{ + public class PostgreSQLQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + this.GroupBy(groupFileds); + return this; + } + } + public class PostgreSQLQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLBuilder.cs new file mode 100644 index 000000000..f60c3ce7c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLBuilder.cs @@ -0,0 +1,124 @@ +namespace SqlSugar +{ + public class PostgreSQLBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string SqlDateNow + { + get + { + return "CURRENT_TIMESTAMP"; + } + } + public override string FullSqlDateNow + { + get + { + return "select CURRENT_TIMESTAMP"; + } + } + + public bool isAutoToLower + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true; + return this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + } + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains('.') && !propertyName.Contains(SqlTranslationLeft)) + { + return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToLower(isAutoToLower)}{SqlTranslationRight}")); + } + + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + else + return SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight; + } + + //public override string GetNoTranslationColumnName(string name) + //{ + // return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower(); + //} + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToLower(isAutoToLower) + SqlTranslationRight); + } + + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + var context = this.Context; + + var mappingInfo = context + .MappingTables + .FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo == null && name.Contains('.') && name.Contains('"')) + { + return name; + } + name = (mappingInfo == null ? name : mappingInfo.DbTableName); + if (name.Contains('.') && !name.Contains('(') && !name.Contains("\".\"")) + { + return string.Join(".", name.ToLower(isAutoToLower).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else if (name.Contains('(')) + { + return name; + } + else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else + { + return SqlTranslationLeft + name.ToLower(isAutoToLower).TrimEnd('"').TrimStart('"') + SqlTranslationRight; + } + } + public override string GetUnionFomatSql(string sql) + { + return " ( " + sql + " ) "; + } + + public override Type GetNullType(string tableName, string columnName) + { + if (tableName != null) + tableName = tableName.Trim(); + var columnInfo = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName).FirstOrDefault(z => z.DbColumnName.EqualCase(columnName)); + if (columnInfo != null) + { + var cTypeName = this.Context.Ado.DbBind.GetCsharpTypeNameByDbTypeName(columnInfo.DataType); + var value = UtilMethods.GetTypeByTypeName(cTypeName); + if (value != null) + { + var key = "GetNullType_" + tableName + columnName; + return new ReflectionInoCacheService().GetOrCreate(key, () => value); + } + } + return null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLDeleteBuilder.cs new file mode 100644 index 000000000..57f4ba33a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class PostgreSQLDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLExpressionContext.cs new file mode 100644 index 000000000..3fdc3a94c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLExpressionContext.cs @@ -0,0 +1,521 @@ +namespace SqlSugar +{ + public partial class PostgreSQLExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public PostgreSQLExpressionContext() + { + base.DbMehtods = new PostgreSQLMethod(); + } + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string GetTranslationText(string name) + { + return SqlTranslationLeft + name.ToLower(isAutoToLower) + SqlTranslationRight; + } + public bool isAutoToLower + { + get + { + return base.PgSqlIsAutoToLower; + } + } + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + + var tableName = mappingInfo?.DbTableName + ""; + if (tableName.Contains('.')) + { + tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + return tableName; + } + + return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToLower(isAutoToLower) + SqlTranslationRight; + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public override string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord) + { + return columnName; + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public override string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToLower(isAutoToLower); + } + else + { + return propertyName.ToLower(isAutoToLower); + } + } + + public string GetValue(object entityValue) + { + if (entityValue == null) + return null; + var type = UtilMethods.GetUnderType(entityValue.GetType()); + if (UtilConstants.NumericalTypes.Contains(type)) + { + return entityValue.ToString(); + } + else if (type == UtilConstants.DateType) + { + return this.DbMehtods.ToDate(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + else + { + return this.DbMehtods.ToString(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + } + } + public class PostgreSQLMethod : DefaultDbMethod, IDbMethods + { + public override string UNIX_TIMESTAMP(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + return $" EXTRACT(EPOCH FROM {parameterNameA})::BIGINT "; + } + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string CharIndexNew(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({0},{1}))", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string TrueValue() + { + return "true"; + } + public override string FalseValue() + { + return "false"; + } + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString())); + var begin = model.Args[1].MemberName; + var end = model.Args[2].MemberName; + switch (parameter) + { + case DateType.Year: + return $" ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) )"; + case DateType.Month: + return $" ( ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) ) * 12 + (DATE_PART('month', {end}) - DATE_PART('month', {begin})) )"; + case DateType.Day: + return $" ( DATE_PART('day', {end} - {begin}) )"; + case DateType.Hour: + return $" ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) )"; + case DateType.Minute: + return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) )"; + case DateType.Second: + return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) ) * 60 + DATE_PART('second', {end} - {begin} )"; + case DateType.Millisecond: + break; + default: + break; + } + throw new Exception(parameter + " datediff no support"); + } + public override string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter.Type == UtilConstants.BoolType) + { + parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); + parameter2.MemberName = false; + parameter3.MemberName = true; + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var format = "dd"; + if (parameter2.MemberValue.ObjToString() == DateType.Year.ToString()) + { + format = "yyyy"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Month.ToString()) + { + format = "MM"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Day.ToString()) + { + format = "dd"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Hour.ToString()) + { + format = "hh24"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Minute.ToString()) + { + format = "mi"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Second.ToString()) + { + format = "ss"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Millisecond.ToString()) + { + format = "ms"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Quarter.ToString()) + { + format = "q"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Weekday.ToString()) + { + return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) "; + } + + return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName); + } + + public override string Contains(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string StartsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter2Info = model.Parameters?.FirstOrDefault(it => it.ParameterName.EqualCase(parameter2.MemberName + "")); + if (parameter2Info != null && parameter2.MemberName?.ToString()?.StartsWith("@MethodConst") == true) + { + parameter2Info.Value = parameter2.MemberValue + "%"; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } + return string.Format(" ({0} like concat({1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string EndsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter2Info = model.Parameters?.FirstOrDefault(it => it.ParameterName.EqualCase(parameter2.MemberName + "")); + if (parameter2Info != null && parameter2.MemberName?.ToString()?.StartsWith("@MethodConst") == true) + { + parameter2Info.Value = "%" + parameter2.MemberValue; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } + return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName, parameter2.MemberName); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL )", parameter.MemberName); + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + DateType dateType = (DateType)parameter3.MemberValue; + var format = "yyyy-MM-dd"; + if (dateType == DateType.Quarter) + { + return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName, format); + } + switch (dateType) + { + case DateType.Year: + format = "yyyy"; + break; + case DateType.Month: + format = "yyyy-MM"; + break; + case DateType.Day: + break; + case DateType.Hour: + format = "yyyy-MM-dd HH"; + break; + case DateType.Second: + format = "yyyy-MM-dd HH:mm:ss"; + break; + case DateType.Minute: + format = "yyyy-MM-dd HH:mm"; + break; + case DateType.Millisecond: + format = "yyyy-MM-dd HH:mm.ms"; + break; + default: + break; + } + return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS timestamp)", parameter.MemberName); + } + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" ({1} + ({2}||'{0}')::INTERVAL) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} + ({1}||'day')::INTERVAL) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT4)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT8)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS UUID)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS boolean)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string IsNullOrEmpty(MethodCallExpressionModel model) + { + if ( + model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase || + model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.GaussDB) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NULL )", parameter.MemberName); + } + else + { + return base.IsNullOrEmpty(model); + } + } + public override string MergeString(params string[] strings) + { + var key = Guid.NewGuid() + ""; + return " concat(" + string.Join(",", strings.Select(it => it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName); + } + public override string GetDate() + { + return "NOW()"; + } + public override string GetRandom() + { + return "RANDOM()"; + } + + public override string EqualTrue(string fieldName) + { + return "( " + fieldName + "=true )"; + } + + public override string JsonField(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + //var parameter2 = model.Args[2]; + //var parameter3= model.Args[3]; + var result = GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count == 2); + if (model.Args.Count > 2) + { + result = GetJson(result, model.Args[2].MemberName, model.Args.Count == 3); + } + if (model.Args.Count > 3) + { + result = GetJson(result, model.Args[3].MemberName, model.Args.Count == 4); + } + if (model.Args.Count > 4) + { + result = GetJson(result, model.Args[4].MemberName, model.Args.Count == 5); + } + if (model.Args.Count > 5) + { + result = GetJson(result, model.Args[5].MemberName, model.Args.Count == 6); + } + return result; + } + + public override string JsonContainsFieldName(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})"; + } + + private string GetJson(object memberName1, object memberName2, bool isLast) + { + if (isLast) + { + return $"({memberName1}::json->>{memberName2})"; + } + else + { + return $"({memberName1}->{memberName2})"; + } + } + + public override string JsonArrayLength(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" json_array_length({parameter.MemberName}::json) "; + } + + public override string JsonParse(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" ({parameter.MemberName}::json) "; + } + + public override string JsonArrayAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name)) + { + return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb "; + } + else + { + return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb "; + } + } + public override string GetStringJoinSelector(string result, string separator) + { + if (result?.ToLower()?.Contains("distinct") == true) + { + return $"string_agg({result},'{separator}') "; + } + return $"string_agg(({result})::text,'{separator}') "; + } + + public override string JsonListObjectAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) + { + return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}]'::jsonb "; + } + else + { + return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}]'::jsonb "; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLFastBuilder.cs new file mode 100644 index 000000000..1725d0d4d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLFastBuilder.cs @@ -0,0 +1,166 @@ +using Npgsql; + +using NpgsqlTypes; + +using System.Data; + +namespace SqlSugar +{ + public class PostgreSQLFastBuilder : FastBuilder, IFastBuilder + { + public static Dictionary PgSqlType = UtilMethods.EnumToDictionary(); + private EntityInfo entityInfo; + + public PostgreSQLFastBuilder(EntityInfo entityInfo) + { + this.entityInfo = entityInfo; + } + + public override string UpdateSql { get; set; } = @"UPDATE {1} SET {0} FROM {2} AS TE WHERE {3} +"; + + //public virtual async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + //{ + // Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + // Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + // var sets = string.Join(",", updateColumns.Select(it => $"TM.{it}=TE.{it}")); + // var wheres = string.Join(",", whereColumns.Select(it => $"TM.{it}=TE.{it}")); + // string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + // return await this.Context.Ado.ExecuteCommandAsync(sql); + //} + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + List lsColNames = new List(); + for (int i = 0; i < dt.Columns.Count; i++) + { + lsColNames.Add($"\"{dt.Columns[i].ColumnName}\""); + } + string copyString = $"COPY {dt.TableName} ( {string.Join(",", lsColNames)} ) FROM STDIN (FORMAT BINARY)"; + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.OpenGauss) + { + copyString = copyString.Replace("(FORMAT BINARY)", "(FORMAT 'BINARY')"); + } + NpgsqlConnection conn = (NpgsqlConnection)this.Context.Ado.Connection; + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(this.entityInfo.DbTableName); + try + { + var identityColumnInfo = this.entityInfo.Columns.FirstOrDefault(it => it.IsIdentity); + if (identityColumnInfo != null) + { + throw new Exception("PgSql bulkcopy no support identity"); + } + BulkCopy(dt, copyString, conn, columns); + } + catch (Exception) + { + throw; + } + finally + { + base.CloseDb(); + } + return await Task.FromResult(dt.Rows.Count).ConfigureAwait(false); + } + + private void BulkCopy(DataTable dt, string copyString, NpgsqlConnection conn, List columns) + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + List columnViews = new List(); + foreach (DataColumn item in dt.Columns) + { + ColumnView result = new ColumnView(); + result.DbColumnInfo = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + result.DataColumn = item; + result.EntityColumnInfo = this.entityInfo.Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + var key = result.DbColumnInfo?.DataType?.ToLower(); + if (result.DbColumnInfo == null) + { + result.Type = null; + } + else if (PgSqlType.TryGetValue(key, out NpgsqlDbType value)) + { + result.Type = value; + } + else if (key?.First() == '_') + { + if (key == "_int4") + { + result.Type = NpgsqlDbType.Array | NpgsqlDbType.Integer; + } + else if (key == "_int2") + { + result.Type = NpgsqlDbType.Array | NpgsqlDbType.Smallint; + } + else if (key == "_int8") + { + result.Type = NpgsqlDbType.Array | NpgsqlDbType.Bigint; + } + else + { + var type = PgSqlType[key.Substring(1)]; + result.Type = NpgsqlDbType.Array | type; + } + } + else + { + result.Type = null; + } + columnViews.Add(result); + } + using (var writer = conn.BeginBinaryImport(copyString)) + { + foreach (DataRow row in dt.Rows) + { + writer.StartRow(); + foreach (var column in columnViews) + { + var value = row[column.DataColumn.ColumnName]; + if (value == null) + { + value = DBNull.Value; + } + //else if (value is double&&this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel==null) + //{ + // column.Type = NpgsqlDbType.Double; + //} + if (column.Type == null) + { + writer.Write(value); + } + else + { + writer.Write(value, column.Type.Value); + } + } + } + writer.Complete(); + } + } + + + public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlquerybulder = this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(updateColumns.Length == 0, "update columns count is 0"); + Check.ArgumentNullException(whereColumns.Length == 0, "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"{tableName}.{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + return await Context.Ado.ExecuteCommandAsync(sql).ConfigureAwait(false); + } + public override async Task CreateTempAsync(DataTable dt) + { + await Context.Queryable().Where(it => false).AS(dt.TableName).Select(" * into temp mytemptable").ToListAsync().ConfigureAwait(false); + dt.TableName = "mytemptable"; + } + + public class ColumnView + { + public DataColumn DataColumn { get; set; } + public EntityColumnInfo EntityColumnInfo { get; set; } + public DbColumnInfo DbColumnInfo { get; set; } + public NpgsqlDbType? Type { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLInsertBuilder.cs new file mode 100644 index 000000000..dcbc2193d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLInsertBuilder.cs @@ -0,0 +1,268 @@ +using System.Globalization; +using System.Text; + +namespace SqlSugar +{ + public class PostgreSQLInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) returning $PrimaryKey"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + public override string SqlTemplateBatchUnion => " VALUES "; + + public override string SqlTemplateBatchSelect => " {0} "; + + public override Func ConvertInsertReturnIdFunc { get; set; } = (name, sql) => + { + return sql.Trim().TrimEnd(';') + $"returning {name} "; + }; + 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))); + ActionMinDate(); + return GetIgnoreSql(string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString)); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 200; + int pageIndex = 1; + if (IsNoPage && IsReturnPkList) + { + pageSize = groupList.Count; + } + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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 ( " + string.Join(",", columns.Select(it => + { + if (it.InsertServerTime || it.InsertSql.HasValue() || it.SqlParameterDbType is Type || it?.PropertyType?.Name == "DateOnly" || it?.PropertyType?.Name == "TimeOnly") + { + return GetDbColumn(it, null); + } + object value = null; + if (it.Value is DateTime) + { + var date = ((DateTime)it.Value); + value = date.ToString("O"); + if (date == DateTime.MaxValue) + { + value = "9999-12-31T23:59:59.999999"; + } + } + else if (it.Value is DateTimeOffset) + { + return FormatDateTimeOffset(it.Value); + } + else if (it.Value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + else if (it.IsArray && it.Value != null) + { + return FormatValue(it.Value, it.PropertyName, i, it); + } + else if (it.Value is byte[]) + { + return FormatValue(it.Value, it.PropertyName, i, it); + } + else + { + value = it.Value; + } + if (value == null || value == DBNull.Value) + { + return string.Format(SqlTemplateBatchSelect, "NULL"); + } + return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToStringNoTrim().ToSqlFilter() + "'"); + })) + "),"); + ++i; + } + pageIndex++; + batchInsetrSql.Remove(batchInsetrSql.Length - 1, 1).Append("\r\n;\r\n"); + } + return GetIgnoreSql(batchInsetrSql.ToString()); + } + } + + public object FormatValue(object value, string name, int i, DbColumnInfo columnInfo) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = value.GetType(); + if (type == UtilConstants.ByteArrayType || type == UtilConstants.DateType || columnInfo.IsArray || columnInfo.IsJson) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + "_" + i; + var paramter = new SugarParameter(parameterName, value); + if (columnInfo.IsJson) + { + paramter.IsJson = true; + } + if (columnInfo.IsArray) + { + paramter.IsArray = true; + } + this.Parameters.Add(paramter); + return parameterName; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + 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.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else if (value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + public override object FormatValue(object value) + { + var N = string.Empty; + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + 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") + "'"; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + Convert.ToHexString((byte[])value); + 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 if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return N + "'" + value.ToString().ToSqlFilter() + "'"; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.FloatType) + { + return N + "'" + Convert.ToDouble(value).ToString() + "'"; + } + else if (value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + else if (value is double dou) + { + return dou.ToString(CultureInfo.InvariantCulture); + } + else + { + return N + "'" + value.ToString() + "'"; + } + } + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + + private string GetIgnoreSql(string sql) + { + if (this.ConflictNothing.Length > 0) + { + sql = sql.Replace(";", $" ON CONFLICT ({string.Join(",", this.ConflictNothing)}) DO NOTHING;"); + } + + return sql; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLQueryBuilder.cs new file mode 100644 index 000000000..97968651d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLQueryBuilder.cs @@ -0,0 +1,129 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class PostgreSQLQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 10 offset 0 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {6} offset {5}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override string GetTableNameString + { + get + { + if (this.TableShortName != null && this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower == false) + { + this.TableShortName = Builder.GetTranslationColumnName(this.TableShortName); + } + return base.GetTableNameString; + } + } + public override bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS ""\w+\.\w+""") || Regex.IsMatch(sql, @"AS ""\w+\.\w+\.\w+"""); + } + public override string ToSqlString() + { + base.AppendFilter(); + string oldOrderValue = this.OrderByValue; + var isNullOrderValue = Skip == 0 && Take == 1 && oldOrderValue == "ORDER BY NOW() "; + if (isNullOrderValue) + { + this.OrderByValue = null; + } + 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 (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; + } + //if (result.Contains("uuid_generate_v4()")) + //{ + // result=" CREATE EXTENSION IF NOT EXISTS pgcrypto;CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"; "+ result; + //} + return result; + } + + #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?.TrimStart()?.StartsWith("distinct ") != true) + { + result = "distinct " + result; + } + if (this.SubToListParameters != null && this.SubToListParameters.Count != 0) + { + result = SubToListMethod(result); + } + return result; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLUpdateBuilder.cs new file mode 100644 index 000000000..662020a31 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/PostgreSQL/SqlBuilder/PostgreSQLUpdateBuilder.cs @@ -0,0 +1,288 @@ +using System.Globalization; +using System.Text; + +namespace SqlSugar +{ + public class PostgreSQLUpdateBuilder : UpdateBuilder + { + public override string SqlTemplateBatch + { + get + { + return @"UPDATE {1} {2} SET {0} FROM ${{0}} "; + } + } + public override string SqlTemplateJoin + { + get + { + return @" (VALUES + {0} + + ) AS T ({2}) WHERE {1} + "; + } + } + + public override string SqlTemplateBatchUnion + { + get + { + return ","; + } + } + + public object FormatValue(object value, string name, int i, DbColumnInfo columnInfo) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.ByteArrayType || type == UtilConstants.DateType || columnInfo.IsArray || columnInfo.IsJson) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + "_" + i; + var paramter = new SugarParameter(parameterName, value); + if (columnInfo.IsJson) + { + paramter.IsJson = true; + } + if (columnInfo.IsArray) + { + paramter.IsArray = true; + } + this.Parameters.Add(paramter); + return parameterName; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + 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 if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else if (value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + else if (value is double dou) + { + return dou.ToString(CultureInfo.InvariantCulture); + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + protected override string TomultipleSqlString(List> groupList) + { + Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List need Primary key"); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + StringBuilder batchUpdateSql = new StringBuilder(); + while (pageCount >= pageIndex) + { + StringBuilder updateTable = new StringBuilder(); + string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = string.Format("{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName)); + return result; + })); + string tempColumnValue = string.Join(",", groupList.First().Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = Builder.GetTranslationColumnName(it.DbColumnName); + return result; + })); + batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString); + int i = 0; + var tableColumnList = this.Context.DbMaintenance.GetColumnInfosByTableName(GetTableNameStringNoWith); + + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) + { + updateTable.Append(SqlTemplateBatchUnion); + } + updateTable.Append("\r\n (" + string.Join(",", columns.Select(it => + { + var columnInfo = tableColumnList.FirstOrDefault(x => x.DbColumnName.Equals(it.DbColumnName, StringComparison.OrdinalIgnoreCase)); + var dbType = columnInfo?.DataType; + if (dbType == null) + { + var typeName = it.PropertyType.Name.ToLower(); + if (columnInfo == null && it.PropertyType.IsEnum) + { + if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString != true) + { + typeName = "int"; + } + } + if (typeName == "int32") + typeName = "int"; + if (typeName == "int64") + typeName = "long"; + if (typeName == "int16") + typeName = "short"; + if (typeName == "boolean") + typeName = "bool"; + + var isAnyType = PostgreSQLDbBind.MappingTypesConst.Where(x => x.Value.ToString().Equals(typeName, StringComparison.CurrentCultureIgnoreCase)).Any(); + if (isAnyType) + { + dbType = PostgreSQLDbBind.MappingTypesConst.Where(x => x.Value.ToString().Equals(typeName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault().Key; + } + else + { + dbType = "varchar"; + } + } + if (it?.PropertyType?.FullName == "NetTopologySuite.Geometries.Geometry") + { + return string.Format(" {0} ", base.GetDbColumn(it, FormatValue(it.Value, it.DbColumnName, i + (pageIndex - 1) * 100000, it)), dbType); + } + return string.Format("CAST({0} AS {1})", base.GetDbColumn(it, FormatValue(it.Value, it.DbColumnName, i + (pageIndex - 1) * 100000, it)), dbType); + + })) + ")"); + ++i; + } + pageIndex++; + updateTable.Append("\r\n"); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += item; + } + } + else if (PrimaryKeys.HasValue()) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += string.Format("{0}.{1}=T.{1}", GetTableNameStringNoWith, Builder.GetTranslationColumnName(item)); + } + } + var format = string.Format(SqlTemplateJoin, updateTable, whereString, tempColumnValue); + batchUpdateSql.Replace("${0}", format); + batchUpdateSql.Append(';'); + } + batchUpdateSql = GetBatchUpdateSql(batchUpdateSql); + return batchUpdateSql.ToString(); + } + + private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql) + { + if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null) + { + var result = batchUpdateSql.ToString(); + foreach (var item in ReSetValueBySqlExpList) + { + var dbColumnName = item.Value.DbColumnName; + if (item.Value.Type == ReSetValueBySqlExpListModelType.List) + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={GetTableNameString}.{dbColumnName}{item.Value.Sql}T.{dbColumnName}"); + } + else + { + if (item.Value?.Sql?.StartsWith("( CASE WHEN") == true) + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(" \"", $" {Builder.GetTranslationColumnName(this.TableName)}.\"")}"); + } + else + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(dbColumnName, $"{Builder.GetTranslationColumnName(this.TableName)}.{dbColumnName}")}"); + } + } + batchUpdateSql = new StringBuilder(result); + } + } + + return batchUpdateSql; + } + protected override string GetJoinUpdate(string columnsString, ref string whereString) + { + if (this.JoinInfos?.Count > 1) + { + return this.GetJoinUpdateMany(columnsString, whereString); + } + var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} "; + var joinString = ""; + foreach (var item in this.JoinInfos) + { + whereString += " AND " + item.JoinWhere; + joinString += $"\r\n FROM {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} "; + } + var tableName = formString + "\r\n "; + columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName) + ".", "") + joinString; + return string.Format(SqlTemplate, tableName, columnsString, whereString); + } + private string GetJoinUpdateMany(string columnsString, string where) + { + var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} "; + var joinString = ""; + var i = 0; + foreach (var item in this.JoinInfos) + { + var whereString = " ON " + item.JoinWhere; + joinString += $"\r\n JOIN {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} "; + joinString = joinString + whereString; + i++; + } + var tableName = Builder.GetTranslationColumnName(this.TableName) + "\r\n "; + columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName) + ".", "") + $" FROM {Builder.GetTranslationColumnName(this.TableName)} {Builder.GetTranslationColumnName(this.ShortName)}\r\n " + joinString; + return string.Format(SqlTemplate, tableName, columnsString, where); + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/CodeFirst/QuestDBCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/CodeFirst/QuestDBCodeFirst.cs new file mode 100644 index 000000000..23058ae0a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/CodeFirst/QuestDBCodeFirst.cs @@ -0,0 +1,101 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class QuestDBCodeFirst : CodeFirstProvider + { + 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()); + } + } + } + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + } + } + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + foreach (var propety in entityInfo.Type.GetProperties()) + { + var timeAttr = propety.GetCustomAttribute(); + if (timeAttr != null) + { + var colName = columns.FirstOrDefault(it => it.PropertyName == propety.Name)?.DbColumnName; + tableName += $"_TIMESTAMP({colName}) PARTITION BY {timeAttr.DateType} "; + } + } + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + PropertyName = item.PropertyName, + Length = item.Length, + CreateTableFieldSort = item.CreateTableFieldSort + }; + if (propertyType == UtilConstants.DecType) + { + result.Scale = item.DecimalDigits; + result.DecimalDigits = item.DecimalDigits; + } + GetDbType(item, propertyType, result); + if (item.IsJson) + { + result.DataType = "string"; + } + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName, null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbBind/QuestDBDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbBind/QuestDBDbBind.cs new file mode 100644 index 000000000..c2f7d57c4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbBind/QuestDBDbBind.cs @@ -0,0 +1,144 @@ +namespace SqlSugar +{ + public class QuestDBDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "binary"; + + var result = base.GetDbTypeName(csharpTypeName); + if (csharpTypeName == "Single") + { + result = "double"; + } + return result; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)); + if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json") + { + return "string"; + } + else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + { + return "char"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes?.Any() != true) + { + if (dbTypeName.StartsWith('_')) + { + var dbTypeName2 = dbTypeName.TrimStart('_'); + return MappingTypes.Where(it => it.Value.ToString().Equals(dbTypeName2, StringComparison.CurrentCultureIgnoreCase) || it.Key.Equals(dbTypeName2, StringComparison.CurrentCultureIgnoreCase)).Select(it => it.Value + "[]").First(); + } + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("byte",CSharpDataType.@byte), + new KeyValuePair("short",CSharpDataType.@short), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("long",CSharpDataType.@long), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("long256",CSharpDataType.@long), + new KeyValuePair("float",CSharpDataType.@float), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("double",CSharpDataType.@double), + new KeyValuePair("double precision",CSharpDataType.@int), + new KeyValuePair("double",CSharpDataType.@decimal), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("path",CSharpDataType.@decimal), + new KeyValuePair("point",CSharpDataType.@decimal), + new KeyValuePair("polygon",CSharpDataType.@decimal), + + //new KeyValuePair("int",CSharpDataType.@bool), + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("bool",CSharpDataType.@bool), + new KeyValuePair("box",CSharpDataType.@bool), + new KeyValuePair("bytea",CSharpDataType.@bool), + + new KeyValuePair("string",CSharpDataType.@string), + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("character varying",CSharpDataType.@string), + new KeyValuePair("geometry",CSharpDataType.@string), + new KeyValuePair("name",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("symbol",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("character",CSharpDataType.@string), + new KeyValuePair("cidr",CSharpDataType.@string), + new KeyValuePair("circle",CSharpDataType.@string), + new KeyValuePair("tsquery",CSharpDataType.@string), + new KeyValuePair("tsvector",CSharpDataType.@string), + new KeyValuePair("txid_snapshot",CSharpDataType.@string), + new KeyValuePair("string",CSharpDataType.Guid), + new KeyValuePair("uuid",CSharpDataType.Guid), + new KeyValuePair("xml",CSharpDataType.@string), + new KeyValuePair("json",CSharpDataType.@string), + + new KeyValuePair("interval",CSharpDataType.@decimal), + new KeyValuePair("lseg",CSharpDataType.@decimal), + new KeyValuePair("macaddr",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("timestamptz",CSharpDataType.DateTime), + new KeyValuePair("timestamp without time zone",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("time with time zone",CSharpDataType.DateTime), + new KeyValuePair("timetz",CSharpDataType.DateTime), + new KeyValuePair("time without time zone",CSharpDataType.DateTime), + + new KeyValuePair("binary",CSharpDataType.byteArray), + new KeyValuePair("bit varying",CSharpDataType.byteArray), + new KeyValuePair("varbit",CSharpDataType.@byte), + new KeyValuePair("time",CSharpDataType.TimeSpan), + //new KeyValuePair("public.geometry",CSharpDataType.@object), + new KeyValuePair("geohash",CSharpDataType.@string) + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbFirst/QuestDBDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbFirst/QuestDBDbFirst.cs new file mode 100644 index 000000000..943dcebf9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbFirst/QuestDBDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class QuestDBDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbMaintenance/QuestDBDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbMaintenance/QuestDBDbMaintenance.cs new file mode 100644 index 000000000..b601890a9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/DbMaintenance/QuestDBDbMaintenance.cs @@ -0,0 +1,503 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class QuestDBDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + return CreateDataBaseSql; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string schema = GetSchema(); + string sql = @"SHOW COLUMNS FROM {0}"; + return sql; + } + } + + protected override string GetTableInfoListSql + { + get + { + var schema = GetSchema(); + return @"SHOW TABLES"; + } + } + protected override string GetViewInfoListSql + { + get + { + return "select * from (select 1 as id) t where id=0"; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "select * from (select 1 as id) t where id=0"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return ""; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD COLUMN {1} {2}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + throw new NotSupportedException("Alter Column "); + } + } + protected override string BackupDataBaseSql + { + get + { + return "BACKUP DATABASE"; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1})"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {0} as (select * from {1} limit {2} offset 0)"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return " "; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} RENAME COLUMN {1} TO {2}"; + } + } + protected override string AddColumnRemarkSql => " "; + + protected override string DeleteColumnRemarkSql => " "; + + protected override string IsAnyColumnRemarkSql { get { throw new NotSupportedException(); } } + + protected override string AddTableRemarkSql => " "; + + protected override string DeleteTableRemarkSql => " "; + + protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } } + + protected override string RenameTableSql => "alter table 表名 {0} to {1}"; + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}"; + } + } + protected override string IsAnyIndexSql + { + get + { + return " Select count(1) from (SELECT to_regclass('{0}') as c ) t where t.c is not null"; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select 1 "; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "DEFAULT NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "serial"; + } + } + #endregion + + #region Methods + public override bool IsAnySystemTablePermissions() + { + return true; + } + public override void AddIndex(EntityInfo entityInfo) + { + if (entityInfo.Indexs != null) + { + foreach (var item in entityInfo.Indexs) + { + CreateIndex(entityInfo.DbTableName, item.IndexFields.Select(it => it.Key).ToArray(), item.IsUnique); + } + } + } + public override bool CreateIndex(string tableName, string[] columnNames, bool isUnique = false) + { + if (isUnique) + { + this.Context.Ado.ExecuteCommand($"ALTER TABLE {tableName} DEDUP ENABLE UPSERT KEYS({string.Join(",", columnNames)})"); + return true; + } + var columnInfos = this.Context.Ado.SqlQuery("SHOW COLUMNS FROM '" + tableName + "'"); + foreach (var columnInfo in columnInfos) + { + if (columnNames.Any(z => z.EqualCase(columnInfo.Column))) + { + if (!columnInfo.Type.EqualCase("SYMBOL")) + { + Check.ExceptionEasy(true, "Only the SYMBOL type can be indexed", $"字段{columnInfo.Column} 不是SYMBOL并且实体是string才能添加索引,CodeFirst需要指定类型: SYMBOL"); + } + if (columnInfo.Indexed == false) + { + var indexSql = $"ALTER TABLE '{tableName}' ALTER COLUMN {columnInfo.Column} ADD INDEX "; + this.Context.Ado.ExecuteCommand(indexSql); + } + } + } + return true; + } + public override bool CreateIndex(string tableName, string[] columnNames, string IndexName, bool isUnique = false) + { + if (isUnique) + throw new Exception("no support unique index"); + return CreateIndex(tableName, columnNames, isUnique); + } + + public override bool CreateUniqueIndex(string tableName, string[] columnNames) + { + throw new Exception("no support unique index"); + } + public override bool IsAnyIndex(string indexName) + { + return false; + } + public override List GetTableInfoList(bool isCache = true) + { + var dt = this.Context.Ado.GetDataTable(GetTableInfoListSql); + List result = new List(); + foreach (System.Data.DataRow dr in dt.Rows) + { + DbTableInfo di = new DbTableInfo(); + di.Name = dr[0] + ""; + if (!di.Name.Contains("sys.") && !di.Name.IsIn("telemetry", "telemetry_config")) + { + result.Add(di); + } + + } + return result; + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + return base.AddDefaultValue(this.SqlBuilder.GetTranslationTableName(tableName), this.SqlBuilder.GetTranslationTableName(columnName), defaultValue); + } + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + //tableName = this.SqlBuilder.GetTranslationTableName(tableName); + //string sql = string.Format(this.AddColumnRemarkSql, columnName, tableName, description); + //this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddTableRemark(string tableName, string description) + { + //tableName = this.SqlBuilder.GetTranslationTableName(tableName); + //return base.AddTableRemark(tableName, description); + return true; + } + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + //no support + return false; + } + public override bool AddPrimaryKey(string tableName, string columnName) + { + return true; + } + //protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + //{ + // string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + // tableName = this.SqlBuilder.GetTranslationTableName(tableName); + // string dataSize = GetSize(columnInfo); + // string dataType = columnInfo.DataType; + // if (!string.IsNullOrEmpty(dataType)) + // { + // dataType = " type " + dataType; + // } + // string nullType = ""; + // string primaryKey = null; + // string identity = null; + // string result = string.Format(this., tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + // return result; + //} + + /// + ///by current connection string + /// + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + if (databaseDirectory != null) + { + if (!FileHelper.IsExistDirectory(databaseDirectory)) + { + FileHelper.CreateDirectory(databaseDirectory); + } + } + var oldDatabaseName = this.Context.Ado.Connection.Database; + var connection = this.Context.CurrentConnectionConfig.ConnectionString; + connection = connection.Replace(oldDatabaseName, "postgres"); + var newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = connection + }); + if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) + { + newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft + databaseName + this.SqlBuilder.SqlTranslationRight, databaseDirectory)); + } + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + + } + } + //table remak + if (entity.TableDescription != null) + { + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + var splitSql = ""; + if (tableName.Contains("_TIMESTAMP(")) + { + splitSql = Regex.Match(tableName, @"_TIMESTAMP\(.+$").Value; + tableName = tableName.Replace(splitSql, ""); + } + if (columns.HasValue()) + { + foreach (var item in columns) + { + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + item.Length = 10; + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower())))); + + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql + splitSql.TrimStart('_')); + return true; + } + 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 = item.DbColumnName; + string dataType = item.DataType; + //if (dataType == "varchar" && item.Length == 0) + //{ + // item.Length = 1; + //} + //if (dataType == "uuid") + //{ + // item.Length = 50; + // dataType = "varchar"; + //} + string dataSize = ""; + //if (item.DecimalDigits > 0&&item.Length>0 && dataType == "numeric") + //{ + // dataSize = $"({item.Length},{item.DecimalDigits})"; + //} + string nullType = ""; + string primaryKey = null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower()), dataType, dataSize, nullType, primaryKey, ""); + //if (item.IsIdentity) + //{ + // string length = dataType.Substring(dataType.Length - 1); + // string identityDataType = "serial" + length; + // addItem = addItem.Replace(dataType, identityDataType); + //} + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",\r\n", columnArray)); + return tableString; + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported"); + return false; + } + + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + var sql = String.Format(GetColumnInfosByTableNameSql, tableName); + List result = new List(); + var dt = this.Context.Ado.GetDataTable(sql); + foreach (System.Data.DataRow column in dt.Rows) + { + DbColumnInfo dbColumnInfo = new DbColumnInfo(); + dbColumnInfo.DbColumnName = column[0] + ""; + dbColumnInfo.DataType = column[1] + ""; + result.Add(dbColumnInfo); + } + return result; + } + #endregion + + #region Helper + private string GetSchema() + { + var schema = "public"; + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + + return schema; + } + + #endregion + + #region HelperClass + internal class QuestDbColumn + { + public string Column { get; set; } + public string Type { get; set; } + public bool Indexed { get; set; } + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/Queryable/QuestDBQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/Queryable/QuestDBQueryable.cs new file mode 100644 index 000000000..d3e4c27d0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/Queryable/QuestDBQueryable.cs @@ -0,0 +1,67 @@ +namespace SqlSugar +{ + public class QuestDBQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + if (this.QueryBuilder.Take == 1) + { + this.QueryBuilder.Take = null; + } + this.QueryBuilder.PartitionByValue = groupFileds; + return this; + } + } + public class QuestDBQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } + public class QuestDBQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/QuestDBProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/QuestDBProvider.cs new file mode 100644 index 000000000..9009ba421 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/QuestDBProvider.cs @@ -0,0 +1,214 @@ +using Npgsql; + +using NpgsqlTypes; + +using System.Data; +using System.Data.Common; + +namespace SqlSugar +{ + public partial class QuestDBProvider : AdoProvider + { + public QuestDBProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var npgsqlConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + base._DbConnection = new NpgsqlConnection(npgsqlConnectionString); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new NpgsqlDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + if (sql == Environment.NewLine) + { + sql = "SELECT 0"; + } + NpgsqlCommand sqlCommand = new NpgsqlCommand(sql, (NpgsqlConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (NpgsqlTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((NpgsqlParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + /// + /// Check connection + /// + public override void CheckConnection() + { + this.CheckConnectionBefore(this.Connection); + if (this.Connection.State != ConnectionState.Open) + { + try + { + int i = 0; + while (i < 15) + { + try + { + //QuestDb loss problem + this.Connection.Open(); + break; + } + catch + { + i++; + } + } + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + this.CheckConnectionAfter(this.Connection); + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((NpgsqlDataAdapter)dataAdapter).SelectCommand = (NpgsqlCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + NpgsqlParameter[] result = new NpgsqlParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + if (parameter.Value is System.Data.SqlTypes.SqlDateTime && parameter.DbType == System.Data.DbType.AnsiString) + { + parameter.DbType = System.Data.DbType.DateTime; + parameter.Value = DBNull.Value; + } + var sqlParameter = new NpgsqlParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + if (parameter.IsJson) + { + sqlParameter.DbType = System.Data.DbType.String; + } + if (sqlParameter.Direction == 0) + { + sqlParameter.Direction = ParameterDirection.Input; + } + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + else if (sqlParameter.Value is DateTime && sqlParameter.DbType == System.Data.DbType.AnsiString) + { + sqlParameter.DbType = System.Data.DbType.DateTime; + } + else if (sqlParameter.DbType == System.Data.DbType.Decimal) + { + sqlParameter.DbType = System.Data.DbType.Double; + sqlParameter.Value = Convert.ToDouble(sqlParameter.Value); + } + else if (sqlParameter.DbType == System.Data.DbType.Guid) + { + sqlParameter.DbType = System.Data.DbType.String; + if (sqlParameter.Value != null) + { + sqlParameter.Value = (sqlParameter.Value).ToString(); + } + } + else if (sqlParameter.DbType == System.Data.DbType.Boolean) + { + sqlParameter.DbType = System.Data.DbType.String; + if (sqlParameter.Value != null) + { + sqlParameter.Value = sqlParameter.Value.ObjToString().ToLower(); + } + } + ++index; + } + return result; + } + + + static readonly Dictionary ArrayMapping = new Dictionary() + { + { typeof(int[]),NpgsqlDbType.Integer}, + { typeof(short[]),NpgsqlDbType.Smallint}, + { typeof(long[]),NpgsqlDbType.Bigint}, + { typeof(decimal[]),NpgsqlDbType.Numeric}, + { typeof(char[]),NpgsqlDbType.Text}, + { typeof(byte[]),NpgsqlDbType.Bytea}, + { typeof(bool[]),NpgsqlDbType.Boolean}, + {typeof(DateTime[]),NpgsqlDbType.Date}, + {typeof(float[]),NpgsqlDbType.Real}, + + + { typeof(int?[]),NpgsqlDbType.Integer}, + { typeof(short?[]),NpgsqlDbType.Smallint}, + { typeof(long?[]),NpgsqlDbType.Bigint}, + { typeof(decimal?[]),NpgsqlDbType.Numeric}, + { typeof(char?[]),NpgsqlDbType.Text}, + { typeof(byte?[]),NpgsqlDbType.Bytea}, + { typeof(bool?[]),NpgsqlDbType.Boolean}, + {typeof(DateTime?[]),NpgsqlDbType.Date}, + + + { typeof(string[]), NpgsqlDbType.Text}, + {typeof(float?[]),NpgsqlDbType.Real}, + }; + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBBuilder.cs new file mode 100644 index 000000000..a9fce5130 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBBuilder.cs @@ -0,0 +1,113 @@ +namespace SqlSugar +{ + public class QuestDBBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string SqlDateNow + { + get + { + //https://questdb.io/docs/guides/working-with-timestamps-timezones/#using-utc-offset-for-conversions + //https://questdb.io/docs/reference/function/date-time/#to_timezone + //SELECT + // now(), --2022-10-21T07:19:50.680134Z + // systimestamp(), --2022-10-21T07:19:50.680278Z + // sysdate(), --2022-10-21T07:19:50.679Z + // to_timezone(NOW(), 'Asia/ShangHai'), --2022-10-21T15:19:50.680134Z + // to_timezone(NOW(), 'HKT'), --2022-10-21T15:19:50.680134Z + // to_timezone(NOW(),'+08') --2022-10-21T15:19:50.680134Z + return $"to_timezone(NOW(),'{TimeZoneInfo.Local.BaseUtcOffset.Hours:00}')"; + } + } + public override string FullSqlDateNow + { + get + { + //https://questdb.io/docs/guides/working-with-timestamps-timezones/#using-utc-offset-for-conversions + //https://questdb.io/docs/reference/function/date-time/#to_timezone + //SELECT + // now(), --2022-10-21T07:19:50.680134Z + // systimestamp(), --2022-10-21T07:19:50.680278Z + // sysdate(), --2022-10-21T07:19:50.679Z + // to_timezone(NOW(), 'Asia/ShangHai'), --2022-10-21T15:19:50.680134Z + // to_timezone(NOW(), 'HKT'), --2022-10-21T15:19:50.680134Z + // to_timezone(NOW(),'+08') --2022-10-21T15:19:50.680134Z + return $"SELECT to_timezone(NOW(),'{TimeZoneInfo.Local.BaseUtcOffset.Hours:00}')"; + } + } + + public bool isAutoToLower => false; + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains('.') && !propertyName.Contains(SqlTranslationLeft)) + { + return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToLower(isAutoToLower)}{SqlTranslationRight}")); + } + + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + else + return SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight; + } + + //public override string GetNoTranslationColumnName(string name) + //{ + // return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower(); + //} + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToLower(isAutoToLower) + SqlTranslationRight); + } + + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table 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.Contains('.') && !name.Contains('(') && !name.Contains("\".\"")) + { + return string.Join(".", name.ToLower(isAutoToLower).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else if (name.Contains('(')) + { + return name; + } + else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else + { + return SqlTranslationLeft + name.ToLower(isAutoToLower).TrimEnd('"').TrimStart('"') + SqlTranslationRight; + } + } + public override string GetUnionFomatSql(string sql) + { + return " ( " + sql + " ) "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBDeleteBuilder.cs new file mode 100644 index 000000000..904eb59fd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class QuestDBDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBExpressionContext.cs new file mode 100644 index 000000000..42c905bf0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBExpressionContext.cs @@ -0,0 +1,379 @@ +namespace SqlSugar +{ + public class QuestDBExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public QuestDBExpressionContext() + { + base.DbMehtods = new QuestDBMethod(); + } + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string GetTranslationText(string name) + { + return SqlTranslationLeft + name.ToLower(isAutoToLower) + SqlTranslationRight; + } + public bool isAutoToLower + { + get + { + return false; + } + } + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + + var tableName = mappingInfo?.DbTableName + ""; + if (tableName.Contains('.')) + { + tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + return tableName; + } + + return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToLower(isAutoToLower) + SqlTranslationRight; + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public override string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord) + { + return columnName; + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public override string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToLower(isAutoToLower); + } + else + { + return propertyName.ToLower(isAutoToLower); + } + } + + public string GetValue(object entityValue) + { + if (entityValue == null) + return null; + var type = UtilMethods.GetUnderType(entityValue.GetType()); + if (UtilConstants.NumericalTypes.Contains(type)) + { + return entityValue.ToString(); + } + else if (type == UtilConstants.DateType) + { + return this.DbMehtods.ToDate(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + else + { + return this.DbMehtods.ToString(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + } + } + public class QuestDBMethod : DefaultDbMethod, IDbMethods + { + //public override string DateIsSameByType(MethodCallExpressionModel model) + //{ + // var parameter = model.Args[0]; + // var parameter2 = model.Args[1]; + // var parameter3 = model.Args[2]; + + // return string.Format(" (DATEDIFF('{2}',{0},{1})=0) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberValue); + //} + public override string AggregateCount(MethodCallExpressionModel model) + { + return " COUNT(*) "; + } + public override string Contains(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0}~{1} ) ", parameter.MemberName, parameter2.MemberName); + } + + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" DATEDIFF('{0}',{1},{2}) ", parameter.MemberValue.ObjToString().ToLower().First(), parameter2.MemberName, parameter3.MemberName); + } + public override string TrueValue() + { + return "1"; + } + public override string FalseValue() + { + return "0"; + } + //public override string DateDiff(MethodCallExpressionModel model) + //{ + // var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString())); + // var begin = model.Args[1].MemberName; + // var end = model.Args[2].MemberName; + // switch (parameter) + // { + // case DateType.Year: + // return $" ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) )"; + // case DateType.Month: + // return $" ( ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) ) * 12 + (DATE_PART('month', {end}) - DATE_PART('month', {begin})) )"; + // case DateType.Day: + // return $" ( DATE_PART('day', {end} - {begin}) )"; + // case DateType.Hour: + // return $" ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) )"; + // case DateType.Minute: + // return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) )"; + // case DateType.Second: + // return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} )"; + // case DateType.Millisecond: + // break; + // default: + // break; + // } + // throw new Exception(parameter + " datediff no support"); + //} + public override string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter.Type == UtilConstants.BoolType) + { + parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); + parameter2.MemberName = false; + parameter3.MemberName = true; + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var format = parameter2.MemberValue.ObjToString(); + return string.Format(" {0}({1}) ", format, parameter.MemberName); + } + + + public override string StartsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat({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 concat('%',{1}))", parameter.MemberName, parameter2.MemberName); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL )", parameter.MemberName); + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + DateType dateType = (DateType)parameter3.MemberValue; + var format = "yyyy-MM-dd"; + switch (dateType) + { + case DateType.Year: + format = "yyyy"; + break; + case DateType.Month: + format = "yyyy-MM"; + break; + case DateType.Day: + break; + case DateType.Hour: + format = "yyyy-MM-dd HH"; + break; + case DateType.Second: + format = "yyyy-MM-dd HH:mm:ss"; + break; + case DateType.Minute: + format = "yyyy-MM-dd HH:mm"; + break; + case DateType.Millisecond: + format = "yyyy-MM-dd HH:mm.ms"; + break; + default: + break; + } + return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format); + } + public override string ToDateShort(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("to_date (to_str({0}, 'yyyy-MM-dd'),'yyyy-MM-dd')", parameter.MemberName); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("CAST({0} AS timestamp)", parameter.MemberName); + } + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" (DATEADD('{0}',{2}, {1})) ", parameter3.MemberValue.ObjToString().ToLower().First(), parameter.MemberName, parameter2.MemberValue); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" (DATEADD('d',{1}, {0})) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS long)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS double )", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS boolean)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS double )", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string MergeString(params string[] strings) + { + return " concat(" + string.Join(",", strings).Replace("+", "") + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName); + } + public override string GetDate() + { + return "now()"; + } + public override string GetRandom() + { + return "now()"; + } + + public override string EqualTrue(string fieldName) + { + return "( " + fieldName + "=true )"; + } + + public override string GetDateString(string dateValue, string format) + { + return $" to_str({dateValue},'{format}') "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBFastBuilder.cs new file mode 100644 index 000000000..c6f11fe79 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBFastBuilder.cs @@ -0,0 +1,121 @@ +using Npgsql; + +using NpgsqlTypes; + +using System.Data; + +namespace SqlSugar +{ + public class QuestDBFastBuilder : FastBuilder, IFastBuilder + { + public static Dictionary PgSqlType = UtilMethods.EnumToDictionary(); + private EntityInfo entityInfo; + + public QuestDBFastBuilder(EntityInfo entityInfo) + { + this.entityInfo = entityInfo; + } + + public override string UpdateSql { get; set; } = @"UPDATE {1} SET {0} FROM {2} AS TE WHERE {3} +"; + + //public virtual async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + //{ + // Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + // Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + // var sets = string.Join(",", updateColumns.Select(it => $"TM.{it}=TE.{it}")); + // var wheres = string.Join(",", whereColumns.Select(it => $"TM.{it}=TE.{it}")); + // string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + // return await this.Context.Ado.ExecuteCommandAsync(sql); + //} + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + Check.ExceptionEasy( + "Nuget install: SqlSugar.QuestDb.RestAPI, use: await db.RestApi().BulkCopyAsync(list)", + "Nuget安装:SqlSugar.QuestDb.RestAPI ,QuestDb中请使用:await db.RestApi().BulkCopyAsync(list) 注意是db.RestApi()不是db.Fastest"); + return await Task.FromResult(0).ConfigureAwait(false); + } + + private void BulkCopy(DataTable dt, string copyString, NpgsqlConnection conn, List columns) + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + List columnViews = new List(); + foreach (DataColumn item in dt.Columns) + { + ColumnView result = new ColumnView(); + result.DbColumnInfo = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + result.DataColumn = item; + result.EntityColumnInfo = this.entityInfo.Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + var key = result.DbColumnInfo?.DataType?.ToLower(); + if (result.DbColumnInfo == null) + { + result.Type = null; + } + else if (PgSqlType.TryGetValue(key, out NpgsqlDbType value)) + { + result.Type = value; + } + else if (key?.First() == '_') + { + var type = PgSqlType[key.Substring(1)]; + result.Type = NpgsqlDbType.Array | type; + } + else + { + result.Type = null; + } + columnViews.Add(result); + } + using (var writer = conn.BeginBinaryImport(copyString)) + { + foreach (DataRow row in dt.Rows) + { + writer.StartRow(); + foreach (var column in columnViews) + { + var value = row[column.DataColumn.ColumnName]; + if (value == null) + { + value = DBNull.Value; + } + if (column.Type == null) + { + writer.Write(value); + } + else + { + writer.Write(value, column.Type.Value); + } + } + } + writer.Complete(); + } + } + + + public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlquerybulder = this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(updateColumns.Length == 0, "update columns count is 0"); + Check.ArgumentNullException(whereColumns.Length == 0, "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"{tableName}.{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + return await Context.Ado.ExecuteCommandAsync(sql).ConfigureAwait(false); + } + public override async Task CreateTempAsync(DataTable dt) + { + await Context.Queryable().Where(it => false).AS(dt.TableName).Select(" * into temp mytemptable").ToListAsync().ConfigureAwait(false); + dt.TableName = "mytemptable"; + } + + public class ColumnView + { + public DataColumn DataColumn { get; set; } + public EntityColumnInfo EntityColumnInfo { get; set; } + public DbColumnInfo DbColumnInfo { get; set; } + public NpgsqlDbType? Type { get; set; } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBInsertBuilder.cs new file mode 100644 index 000000000..2a6a9e3e0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBInsertBuilder.cs @@ -0,0 +1,115 @@ +using System.Text; + +namespace SqlSugar +{ + public class QuestDBInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2})"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + public override string SqlTemplateBatchUnion => " VALUES "; + + public override string SqlTemplateBatchSelect => " {0} "; + + 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 => + // { + // var spk = Builder.SqlParameterKeyWord + it.DbColumnName; + // //if (it.Value is DateTime) + // //{ + // // return $"to_timestamp('{it.Value.ObjToString("yyyy-MM-ddTHH:mm:ss")}', 'yyyy-MM-ddTHH:mm:ss')"; + // //} + // return GetDbColumn(it, spk); + // } + + // )); + // ActionMinDate(); + // return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + //} + //else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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 ( " + string.Join(",", columns.Select(it => + { + if (it.InsertServerTime || it.InsertSql.HasValue()) + { + return GetDbColumn(it, null); + } + object value = null; + if (it.Value is DateTime) + { + return $" cast('{it.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.ffffff")}' as timestamp)"; + } + else if (it.Value is int || it.Value is long || it.Value is short || it.Value is short || it.Value is byte || it.Value is double) + { + return it.Value; + } + else if (it.Value is bool) + { + return it.Value; + //return it.Value.ObjToString().ToLower(); + } + else + { + value = it.Value; + } + if (value == null || value == DBNull.Value) + { + return string.Format(SqlTemplateBatchSelect, "NULL"); + } + return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToString().ToSqlFilter() + "'"); + })) + "),"); + ++i; + } + pageIndex++; + batchInsetrSql.Remove(batchInsetrSql.Length - 1, 1).Append("\r\n;\r\n"); + } + return batchInsetrSql.ToString(); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBQueryBuilder.cs new file mode 100644 index 000000000..19810f242 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBQueryBuilder.cs @@ -0,0 +1,169 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class QuestDBQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 0,10 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {5},{6}"; + if (this.SampleBy.HasValue()) + { + template = "SELECT {0} FROM {1} {2} " + this.SampleBy + " {3} {4} LIMIT {5},{6}"; + } + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override bool IsComplexModel(string sql) + { + return 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 NOW() ") + { + 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, Skip + 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; + } + if (this.PartitionByValue.HasValue()) + { + var addSql = " LATEST ON " + UtilMethods.ReplaceFirstMatch(this.PartitionByValue, ",", " PARTITION BY "); + result = result + addSql; + } + 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()) + { + 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.Count != 0) + { + result = SubToListMethod(result); + } + return result; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBUpdateBuilder.cs new file mode 100644 index 000000000..54c7ff815 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/QuestDB/SqlBuilder/QuestDBUpdateBuilder.cs @@ -0,0 +1,103 @@ +using System.Text; + +namespace SqlSugar +{ + public class QuestDBUpdateBuilder : UpdateBuilder + { + public override string ReSetValueBySqlExpListType { get; set; } = "questdb"; + protected override string TomultipleSqlString(List> groupList) + { + StringBuilder sb = new StringBuilder(); + int i = 0; + sb.AppendLine(string.Join("\r\n", 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 string GetOracleUpdateColums(int i, DbColumnInfo m, bool iswhere) + { + return string.Format(" \"{0}\"={1}", m.DbColumnName.ToUpper(), 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 decimal || value is double || 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/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/CodeFirst/SqlServerCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/CodeFirst/SqlServerCodeFirst.cs new file mode 100644 index 000000000..699864a11 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/CodeFirst/SqlServerCodeFirst.cs @@ -0,0 +1,50 @@ +namespace SqlSugar +{ + public class SqlServerCodeFirst : CodeFirstProvider + { + 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 SqlServerDbMaintenance() { Context = this.Context }; + var schmes = dbMain.GetSchemas(); + if (!schmes.Any(it => it.EqualCase(tableArray.First()))) + { + return tableArray.Last(); + } + else + { + return dbMain.SqlBuilder.GetTranslationTableName(table); + } + } + else + { + return table; + } + } + + protected override void GetDbType(EntityColumnInfo item, Type propertyType, DbColumnInfo result) + { + if (!string.IsNullOrEmpty(item.DataType)) + { + result.DataType = item.DataType; + } + else if (propertyType.IsEnum()) + { + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(item.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name); + } + else + { + var name = GetType(propertyType.Name); + result.DataType = this.Context.Ado.DbBind.GetDbTypeName(name); + if (result.DataType == "varbinary" && item.Length == 0) + { + result.DataType = "varbinary(max)"; + } + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbBind/SqlServerDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbBind/SqlServerDbBind.cs new file mode 100644 index 000000000..6e10be28e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbBind/SqlServerDbBind.cs @@ -0,0 +1,69 @@ +namespace SqlSugar +{ + public class SqlServerDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == nameof(DateTimeOffset)) + { + return nameof(DateTimeOffset); + } + else + { + return base.GetDbTypeName(csharpTypeName); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>() + { + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("nvarchar",CSharpDataType.@string), + new KeyValuePair("sql_variant",CSharpDataType.@string), + new KeyValuePair("varcharmax",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("ntext",CSharpDataType.@string), + new KeyValuePair("nchar",CSharpDataType.@string), + new KeyValuePair("hierarchyid",CSharpDataType.@string), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("bit",CSharpDataType.@bool), + new KeyValuePair("datetime",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("smalldatetime",CSharpDataType.DateTime), + new KeyValuePair("timestamp",CSharpDataType.byteArray), + new KeyValuePair("datetime2",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("single",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("smallmoney",CSharpDataType.@decimal), + new KeyValuePair("float",CSharpDataType.@double), + new KeyValuePair("float",CSharpDataType.Single), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("tinyint",CSharpDataType.@byte), + new KeyValuePair("uniqueidentifier",CSharpDataType.Guid), + new KeyValuePair("image",CSharpDataType.byteArray), + new KeyValuePair("binary",CSharpDataType.byteArray), + new KeyValuePair("varbinary",CSharpDataType.byteArray), + new KeyValuePair("datetimeoffset", CSharpDataType.DateTimeOffset), + new KeyValuePair("datetimeoffset", CSharpDataType.DateTime)}; + }; + +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbFirst/SqlServerDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbFirst/SqlServerDbFirst.cs new file mode 100644 index 000000000..a79a21d0c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbFirst/SqlServerDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class SqlServerDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs new file mode 100644 index 000000000..b2ab0f5b3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs @@ -0,0 +1,786 @@ +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SqlServerDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + return "SELECT NAME FROM master.dbo.sysdatabases ORDER BY NAME"; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string sql = @"SELECT sysobjects.name AS TableName, + syscolumns.Id AS TableId, + syscolumns.name AS DbColumnName, + systypes.name AS DataType, + COLUMNPROPERTY(syscolumns.id,syscolumns.name,'PRECISION') as [length], + isnull(COLUMNPROPERTY(syscolumns.id,syscolumns.name,'Scale'),0) as Scale, + isnull(COLUMNPROPERTY(syscolumns.id,syscolumns.name,'Scale'),0) as DecimalDigits, + Cast( sys.extended_properties.[value] as nvarchar(2000)) AS [ColumnDescription], + syscomments.text AS DefaultValue, + syscolumns.isnullable AS IsNullable, + columnproperty(syscolumns.id,syscolumns.name,'IsIdentity')as IsIdentity, + (CASE + WHEN EXISTS + ( + select 1 + from sysindexes i + join sysindexkeys k on i.id = k.id and i.indid = k.indid + join sysobjects o on i.id = o.id + join syscolumns c on i.id=c.id and k.colid = c.colid + where o.xtype = 'U' + and exists(select 1 from sysobjects where xtype = 'PK' and name = i.name) + and o.name=sysobjects.name and c.name=syscolumns.name + ) THEN 1 + ELSE 0 + END) AS IsPrimaryKey + FROM syscolumns + INNER JOIN systypes ON syscolumns.xtype = systypes.xtype + LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id + LEFT OUTER JOIN sys.extended_properties ON (sys.extended_properties.minor_id = syscolumns.colid + AND sys.extended_properties.major_id = syscolumns.id) + LEFT OUTER JOIN syscomments ON syscolumns.cdefault = syscomments.id + WHERE syscolumns.id IN + (SELECT id + FROM sysobjects + WHERE upper(xtype) IN('U', + 'V') ) + AND (systypes.name <> 'sysname') + AND sysobjects.name=N'{0}' + AND systypes.name<>'geometry' + AND systypes.name<>'geography' + ORDER BY syscolumns.colid"; + return sql; + } + } + protected override string GetTableInfoListSql + { + get + { + return @"SELECT s.Name,Convert(nvarchar(max),tbp.value) as Description + FROM sysobjects s + LEFT JOIN sys.extended_properties as tbp ON s.id=tbp.major_id and tbp.minor_id=0 AND (tbp.Name='MS_Description' OR tbp.Name is null) WHERE s.xtype IN('U') "; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"SELECT s.Name,Convert(varchar(max),tbp.value) as Description + FROM sysobjects s + LEFT JOIN sys.extended_properties as tbp ON s.id=tbp.major_id and tbp.minor_id=0 AND (tbp.Name='MS_Description' OR tbp.Name is null) WHERE s.xtype IN('V') "; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return @"create database {0} "; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY({2})"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return @"USE master;BACKUP DATABASE {0} TO disk = '{1}'"; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1})"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "SELECT TOP {0} * INTO {1} FROM {2}"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "exec sp_rename '{0}.{1}','{2}','column';"; + } + } + protected override string AddColumnRemarkSql + { + get + { + return "EXECUTE sp_addextendedproperty N'MS_Description', N'{2}', N'user', N'dbo', N'table', N'{1}', N'column', N'{0}'"; ; + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + return "EXEC sp_dropextendedproperty 'MS_Description','user',dbo,'table','{1}','column','{0}'"; + } + + } + + protected override string IsAnyColumnRemarkSql + { + get + { + return @"SELECT" + + " A.name AS table_name," + + " B.name AS column_name," + + " C.value AS column_description" + + " FROM sys.tables A" + + " LEFT JOIN sys.extended_properties C ON C.major_id = A.object_id" + + " LEFT JOIN sys.columns B ON B.object_id = A.object_id AND C.minor_id = B.column_id" + + " INNER JOIN sys.schemas SC ON SC.schema_id = A.schema_id AND SC.name = 'dbo'" + + " WHERE A.name = '{1}' and B.name = '{0}'"; + + } + } + + protected override string AddTableRemarkSql + { + get + { + return "EXECUTE sp_addextendedproperty N'MS_Description', N'{1}', N'user', N'dbo', N'table', N'{0}', NULL, NULL"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "EXEC sp_dropextendedproperty 'MS_Description','user',dbo,'table','{0}' "; + } + + } + + protected override string IsAnyTableRemarkSql + { + get + { + return @"SELECT C.class_desc + FROM sys.tables A + LEFT JOIN sys.extended_properties C ON C.major_id = A.object_id + INNER JOIN sys.schemas SC ON SC.schema_id=A.schema_id AND SC.name='dbo' + WHERE A.name = '{0}' AND minor_id=0"; + } + + } + + protected override string RenameTableSql + { + get + { + return "EXEC sp_rename '{0}','{1}'"; + } + } + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} NONCLUSTERED INDEX Index_{0}_{2} ON {0}({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "alter table {0} ADD DEFAULT '{2}' FOR {1}"; + } + } + protected override string IsAnyIndexSql + { + get + { + return "select count(*) from sys.indexes where name='{0}'"; + } + } + protected override string IsAnyProcedureSql + { + get + { + return "select count(*) from sys.objects where [object_id] = OBJECT_ID(N'{0}') and [type] in (N'P')"; + } + } + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select top 1 id from sysobjects"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "IDENTITY(1,1)"; + } + } + + #endregion + + #region Methods + public override bool DropIndex(string indexName, string tableName) + { + indexName = this.SqlBuilder.GetNoTranslationColumnName(indexName); + tableName = this.SqlBuilder.GetNoTranslationColumnName(tableName); + this.Context.Ado.ExecuteCommand($" DROP INDEX {indexName} ON {tableName}"); + return true; + } + public override bool SetAutoIncrementInitialValue(string tableName, int initialValue) + { + this.Context.Ado.ExecuteCommand($"DBCC CHECKIDENT ('" + tableName + $"', RESEED, {initialValue})"); + return true; + } + public override bool SetAutoIncrementInitialValue(Type entityType, int initialValue) + { + return this.SetAutoIncrementInitialValue(this.Context.EntityMaintenance.GetEntityInfo(entityType).DbTableName, initialValue); + } + public override List GetSchemaTables(EntityInfo entityInfo) + { + if (entityInfo.DbTableName.Contains('.') && this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + var schema = entityInfo.DbTableName.Split('.').First(); + var isAny = GetSchemas().Any(it => it.EqualCase(schema)) || schema.EqualCase("dbo"); + if (isAny) + { + var tableInfos = this.Context.Ado.SqlQuery(@"SELECT schem.name+'.'+tb.name Name,tb.Description from + ( SELECT obj.name,Convert(nvarchar(max),prop.value)as Description,obj.schema_id FROM sys.objects obj + LEFT JOIN sys.extended_properties prop + ON obj.object_id=prop.major_id + and prop.minor_id=0 + AND (prop.Name='MS_Description' OR prop.Name is null) + WHERE obj.type IN('U')) tb + inner join sys.schemas as schem + on tb.schema_id=schem.schema_id "); + return tableInfos; + } + } + return null; + } + + public override bool DropColumn(string tableName, string columnName) + { + if (Regex.IsMatch(tableName, @"^\w+$") && Regex.IsMatch(columnName, @"^\w+$")) + { + var sql = $"SELECT distinct dc.name AS ConstraintName \r\nFROM sys.default_constraints dc\r\nJOIN sys.columns c ON dc.parent_column_id = c.column_id\r\nWHERE dc.parent_object_id = OBJECT_ID('{tableName}')\r\nAND c.name = '{columnName}';"; + var checks = this.Context.Ado.SqlQuery(sql); + foreach (var checkName in checks) + { + if (checkName?.ToUpper()?.StartsWith("DF__") == true) + { + this.Context.Ado.ExecuteCommand($"ALTER TABLE {SqlBuilder.GetTranslationColumnName(tableName)} DROP CONSTRAINT {checkName}"); + } + } + } + return base.DropColumn(tableName, columnName); + } + public override List GetDbTypes() + { + return this.Context.Ado.SqlQuery(@"SELECT name +FROM sys.types +WHERE is_user_defined = 0;"); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT DISTINCT sysobjects.name AS TriggerName +FROM sysobjects +JOIN syscomments ON sysobjects.id = syscomments.id +WHERE sysobjects.xtype = 'TR' +AND syscomments.text LIKE '%" + tableName + "%'"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery("SELECT name\r\nFROM sys.objects\r\nWHERE type_desc IN( 'SQL_SCALAR_FUNCTION','SQL_INLINE_TABLE_VALUED_FUNCTION') "); + } + private bool IsAnySchemaTable(string tableName) + { + if (tableName?.Contains('.') != true) + { + return false; + } + var list = GetSchemas() ?? new List(); + list.Add("dbo"); + var isAnySchemas = list.Any(it => it.EqualCase(tableName?.Split('.').FirstOrDefault())); + return isAnySchemas; + } + public override bool IsAnyColumnRemark(string columnName, string tableName) + { + if (tableName?.Contains('.') == true && tableName.Contains(SqlBuilder.SqlTranslationLeft)) + { + tableName = string.Join(".", tableName.Split('.').Select(it => SqlBuilder.GetNoTranslationColumnName(it))); + } + if (IsAnySchemaTable(tableName)) + { + var schema = tableName.Split('.').First(); + tableName = tableName.Split('.').Last(); + var temp = this.IsAnyColumnRemarkSql.Replace("'dbo'", $"'{schema}'"); + string sql = string.Format(temp, columnName, tableName); + var dt = this.Context.Ado.GetDataTable(sql); + return dt.Rows?.Count > 0; + } + return base.IsAnyColumnRemark(columnName, tableName); + } + public override bool DeleteColumnRemark(string columnName, string tableName) + { + if (tableName?.Contains('.') == true && tableName.Contains(SqlBuilder.SqlTranslationLeft)) + { + tableName = string.Join(".", tableName.Split('.').Select(it => SqlBuilder.GetNoTranslationColumnName(it))); + } + if (IsAnySchemaTable(tableName)) + { + var schema = tableName.Split('.').First(); + tableName = tableName.Split('.').Last(); + var temp = this.DeleteColumnRemarkSql.Replace(",dbo,", $",{schema},"); + if (!schema.EqualCase("dbo")) + { + temp = temp.Replace("N'user'", $"N'schema'"); + temp = temp.Replace("'user'", $"N'schema'"); + } + string sql = string.Format(temp, columnName, tableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + return base.DeleteColumnRemark(columnName, tableName); + } + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + if (tableName?.Contains('.') == true && tableName.Contains(SqlBuilder.SqlTranslationLeft)) + { + tableName = string.Join(".", tableName.Split('.').Select(it => SqlBuilder.GetNoTranslationColumnName(it))); + } + if (IsAnySchemaTable(tableName)) + { + var schema = tableName.Split('.').First(); + tableName = tableName.Split('.').Last(); + var temp = this.AddColumnRemarkSql.Replace("N'dbo'", $"N'{schema}'"); + if (!schema.EqualCase("dbo")) + { + temp = temp.Replace("N'user'", $"N'schema'"); + } + string sql = string.Format(temp, columnName, tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + return base.AddColumnRemark(columnName, tableName, description); + } + + public override void AddDefaultValue(EntityInfo entityInfo) + { + var dbColumns = this.GetColumnInfosByTableName(entityInfo.DbTableName, false); + var db = this.Context; + var columns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + foreach (var item in columns) + { + if (item.DefaultValue.HasValue() || (string.IsNullOrEmpty(item.DefaultValue) && item.UnderType == UtilConstants.StringType)) + { + if (!IsAnyDefaultValue(entityInfo.DbTableName, item.DbColumnName, dbColumns)) + { + this.AddDefaultValue(entityInfo.DbTableName, item.DbColumnName, item.DefaultValue); + } + } + } + } + + public override List GetIndexList(string tableName) + { + return this.Context.Ado.SqlQuery($"SELECT indexname = i.name FROM sys.indexes i\r\nJOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id\r\nJOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id\r\nWHERE i.object_id = OBJECT_ID('{tableName}')"); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT name FROM {dbName}.sys.procedures"; + return this.Context.Ado.SqlQuery(sql); + } + public override bool UpdateColumn(string tableName, DbColumnInfo column) + { + ConvertCreateColumnInfo(column); + if (column.DataType != null && this.Context.CurrentConnectionConfig?.MoreSettings?.SqlServerCodeFirstNvarchar == true) + { + if (!column.DataType.Contains("nvarchar", StringComparison.CurrentCultureIgnoreCase)) + { + column.DataType = column.DataType.ToLower().Replace("varchar", "nvarchar"); + } + } + return base.UpdateColumn(tableName, column); + } + public override bool IsAnyTable(string tableName, bool isCache = true) + { + if (tableName.Contains('.')) + { + var schemas = GetSchemas(); + var first = this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').First()); + var schemaInfo = schemas.FirstOrDefault(it => it.EqualCase(first)); + if (schemaInfo == null) + { + return base.IsAnyTable(tableName, isCache); + } + else + { + var result = this.Context.Ado.GetInt($"select object_id(N'{tableName}')"); + return result > 0; + } + } + else if (isCache) + { + return base.IsAnyTable(tableName, isCache); + } + else + { + if (tableName.Contains(SqlBuilder.SqlTranslationLeft)) + { + tableName = SqlBuilder.GetNoTranslationColumnName(tableName); + } + var sql = @"IF EXISTS (SELECT * FROM sys.objects with(nolock) + WHERE type='u' AND name=N'" + tableName.ToSqlFilter() + @"') + SELECT 1 AS res ELSE SELECT 0 AS res;"; + return this.Context.Ado.GetInt(sql) > 0; + } + } + public List GetSchemas() + { + return this.Context.Ado.SqlQuery("SELECT name FROM sys.schemas where name <> 'dbo'"); + } + public override bool DeleteTableRemark(string tableName) + { + string sql = string.Format(this.DeleteTableRemarkSql, tableName); + if (tableName.Contains('.')) + { + var schemas = GetSchemas(); + var tableSchemas = this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').First()); + if (schemas.Any(y => y.EqualCase(tableSchemas))) + { + sql = string.Format(this.DeleteTableRemarkSql, this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').Last())); + if (tableSchemas.EqualCase("user")) + { + sql = sql.Replace("'user'", "'SCHEMA'").Replace("dbo", $"'{tableSchemas}'"); + } + else + { + sql = sql.Replace(",dbo,", $",{tableSchemas},").Replace("'user'", "'SCHEMA'"); + } + } + } + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool IsAnyTableRemark(string tableName) + { + string sql = string.Format(this.IsAnyTableRemarkSql, tableName); + if (tableName.Contains('.')) + { + var schemas = GetSchemas(); + var tableSchemas = this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').First()); + if (schemas.Any(y => y.EqualCase(tableSchemas))) + { + sql = string.Format(this.IsAnyTableRemarkSql, this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').Last())); + sql = sql.Replace("'dbo'", $"'{tableSchemas}'"); + } + } + var dt = this.Context.Ado.GetDataTable(sql); + return dt.Rows?.Count > 0; + } + public override bool AddTableRemark(string tableName, string description) + { + string sql = string.Format(this.AddTableRemarkSql, tableName, description); + if (tableName.Contains('.')) + { + var schemas = GetSchemas(); + var tableSchemas = this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').First()); + if (schemas.Any(y => y.EqualCase(tableSchemas))) + { + sql = string.Format(this.AddTableRemarkSql, this.SqlBuilder.GetNoTranslationColumnName(tableName.Split('.').Last()), description); + if (tableSchemas.EqualCase("user")) + { + sql = sql.Replace("N'user', N'dbo'", $"N'user', '{tableSchemas}'").Replace("N'user'", "N'SCHEMA'"); + } + else + { + sql = sql.Replace("N'dbo'", $"N'{tableSchemas}'").Replace("N'user'", "N'SCHEMA'"); + } + } + } + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue == "''") + { + defaultValue = ""; + } + var template = AddDefaultValueSql; + if (defaultValue?.Replace(" ", "").Contains("()") == true) + { + template = template.Replace("'{2}'", "{2}"); + } + tableName = SqlBuilder.GetTranslationTableName(tableName); + columnName = SqlBuilder.GetTranslationTableName(columnName); + 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) + { + if (databaseDirectory != null) + { + try + { + if (!FileHelper.IsExistDirectory(databaseDirectory)) + { + if (FileHelper.IsExistDirectory(Path.GetPathRoot(databaseDirectory))) + { + FileHelper.CreateDirectory(databaseDirectory); + } + } + } + catch + { + //Databases and sites are not in the same service + } + } + var oldDatabaseName = this.Context.Ado.Connection.Database; + var connection = this.Context.CurrentConnectionConfig.ConnectionString; + if (Regex.Split(connection, oldDatabaseName).Length > 2) + { + var name = Regex.Match(connection, @"database\=\w+|datasource\=\w+", RegexOptions.IgnoreCase).Value; + if (!string.IsNullOrEmpty(name)) + { + connection = connection.Replace(name, "database=master"); + } + else + { + Check.ExceptionEasy("Failed to create the database. The database name has a keyword. Please change the name", "建库失败,库名存在关键字,请换一个名字"); + } + } + else + { + connection = connection.Replace(oldDatabaseName, "master"); + } + var newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = connection + }); + if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) + { + var separatorChar = UtilMethods.GetSeparatorChar(); + var sql = CreateDataBaseSql; + if (databaseDirectory.HasValue()) + { + sql += @"on primary + ( + name = N'{0}', + filename = N'{1}\{0}.mdf', + size = 10mb, + maxsize = 5000mb, + filegrowth = 1mb + ), + ( + name = N'{0}_ndf', + filename = N'{1}\{0}.ndf', + size = 10mb, + maxsize = 5000mb, + filegrowth =10mb + ) + log on + ( + name = N'{0}_log', + filename = N'{1}\{0}.ldf', + size = 100mb, + maxsize = 1gb, + filegrowth = 10mb + ); "; + databaseDirectory = databaseDirectory.Replace("\\", separatorChar); + } + if (databaseName.Contains('.')) + { + databaseName = $"[{databaseName}]"; + } + else if (Regex.IsMatch(databaseName, @"^\d.*")) + { + databaseName = $"[{databaseName}]"; + } + newDb.Ado.ExecuteCommand(string.Format(sql, databaseName, databaseDirectory)); + } + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + foreach (var item in columns) + { + ConvertCreateColumnInfo(item); + if (item.DataType == "decimal" && item.DecimalDigits == 0 && item.Length == 0) + { + item.DecimalDigits = 4; + item.Length = 18; + } + else if (item.DataType != null && this.Context.CurrentConnectionConfig?.MoreSettings?.SqlServerCodeFirstNvarchar == true) + { + if (!item.DataType.Contains("nvarchar", StringComparison.CurrentCultureIgnoreCase)) + { + item.DataType = item.DataType.ToLower().Replace("varchar", "nvarchar"); + } + } + + } + 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; + } + + private static void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "int", "text", "image", "smallint", "bigint", "date", "bit", "ntext", "datetime", "datetime2", "uniqueidentifier", "tinyint", "rowversion", "timestamp", "money" }; + if (x.DataType.EqualCase("nvarchar") || x.DataType.EqualCase("varchar")) + { + if (x.Length < 1) + { + x.DataType = $"{x.DataType}(max)"; + } + } + else if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + } + + 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; + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/Queryable/SqlServerQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/Queryable/SqlServerQueryable.cs new file mode 100644 index 000000000..ba7278fcf --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/Queryable/SqlServerQueryable.cs @@ -0,0 +1,51 @@ +namespace SqlSugar +{ + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } + public class SqlServerQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerBlukCopy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerBlukCopy.cs new file mode 100644 index 000000000..8e1976400 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerBlukCopy.cs @@ -0,0 +1,150 @@ +using Microsoft.Data.SqlClient; + +using System.Data; + +namespace SqlSugar +{ + public partial class SqlServerBlukCopy + { + 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) + { + CloseDb(); + throw; + } + 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).ConfigureAwait(false); + } + catch (Exception) + { + CloseDb(); + throw; + } + 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/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerBuilder.cs new file mode 100644 index 000000000..601974322 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerBuilder.cs @@ -0,0 +1,33 @@ +namespace SqlSugar +{ + public class SqlServerBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft { get { return "["; } } + public override string SqlTranslationRight { get { return "]"; } } + public override bool SupportReadToken { get; set; } = true; + + public override string RemoveParentheses(string sql) + { + if (sql.Contains("ORDER BY") && !sql.StartsWith("(SELECT TOP 1") && !sql.Contains("(SELECT TOP 1000000")) + { + sql = $"SELECT * FROM {sql.Replace("(SELECT ", "(SELECT TOP 1000000")} TEMP"; + } + else if (sql.Contains("ORDER BY") && sql.StartsWith("(SELECT TOP 1")) + { + sql = $"SELECT * FROM ({sql}) TEMP"; + } + return sql; + } + public override void ChangeJsonType(SugarParameter paramter) + { + if (paramter.DbType == System.Data.DbType.AnsiString) + { + paramter.DbType = System.Data.DbType.String; + } + } + public override Task GetReaderByToken(System.Data.IDataReader dataReader, System.Threading.CancellationToken cancellationToken) + { + return ((Microsoft.Data.SqlClient.SqlDataReader)dataReader).ReadAsync(this.Context.Ado.CancellationToken.Value); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerDeleteBuilder.cs new file mode 100644 index 000000000..bf9398faa --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class SqlServerDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerExpressionContext.cs new file mode 100644 index 000000000..fd8977ee5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerExpressionContext.cs @@ -0,0 +1,192 @@ +namespace SqlSugar +{ + public partial class SqlServerExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public SqlServerExpressionContext() + { + base.DbMehtods = new SqlServerMethod(); + } + + } + public partial class SqlServerMethod : DefaultDbMethod, IDbMethods + { + public override string UNIX_TIMESTAMP(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + return $" DATEDIFF(SECOND, '1970-01-01', {parameterNameA}) "; + } + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,6)) ", parameter.MemberName); + } + public override string JsonArrayLength(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return $" (SELECT COUNT(*) FROM OPENJSON({parameter.MemberName})) "; + } + + public override string JsonIndex(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"JSON_VALUE({parameter.MemberName}, '$[{parameter1.MemberValue}]')"; + } + public override string CharIndexNew(MethodCallExpressionModel model) + { + return string.Format("CHARINDEX ({1},{0})", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string WeekOfYear(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $"DATEPART(WEEK, {parameterNameA}) "; + } + public override string GetTableWithDataBase(string dataBaseName, string tableName) + { + return $"{dataBaseName}.dbo.{tableName}"; + } + public override string GetForXmlPath() + { + return " FOR XML PATH('')),1,len(N','),'') "; + } + public override string GetStringJoinSelector(string result, string separator) + { + if (result.ObjToString().Trim().StartsWith("DISTINCT ", StringComparison.OrdinalIgnoreCase)) + { + int index = result.IndexOf(result, StringComparison.Ordinal); // 找到去掉前缀空格后的位置 + result = result.Substring(index + 9); // 9 是 "DISTINCT " 的长度 + return $"stuff((SELECT DISTINCT cast(N'{separator}' as nvarchar(max)) + cast({result} as nvarchar(max))"; + } + else + { + return $"stuff((SELECT cast(N'{separator}' as nvarchar(max)) + cast({result} as nvarchar(max))"; + } + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + if (parameter.MemberName != null && parameter.MemberName is DateTime) + { + if (parameter2.MemberValue?.ToString() == DateType.Weekday.ToString()) + { + return string.Format(" (datepart({0},'{1}')-1) ", parameter2.MemberValue, parameter.MemberName); + } + else + { + return string.Format(" datepart({0},'{1}') ", parameter2.MemberValue, parameter.MemberName); + } + } + else + { + if (parameter2.MemberValue?.ToString() == DateType.Weekday.ToString()) + { + return string.Format(" (datepart({0},{1})-1) ", parameter2.MemberValue, parameter.MemberName); + } + else + { + return string.Format(" datepart({0},{1}) ", parameter2.MemberValue, parameter.MemberName); + } + } + } + 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 JsonField(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + //var parameter2 = model.Args[2]; + //var parameter3= model.Args[3]; + var result = GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count == 2); + if (model.Args.Count > 2) + { + result = GetJson(result, model.Args[2].MemberName, model.Args.Count == 3); + } + if (model.Args.Count > 3) + { + result = GetJson(result, model.Args[3].MemberName, model.Args.Count == 4); + } + if (model.Args.Count > 4) + { + result = GetJson(result, model.Args[4].MemberName, model.Args.Count == 5); + } + if (model.Args.Count > 5) + { + result = GetJson(result, model.Args[5].MemberName, model.Args.Count == 6); + } + return result; + } + + private string GetJson(object memberName1, object memberName2, bool isLast) + { + return $"JSON_VALUE({memberName1}, '$.'+" + memberName2 + ")"; + } + + public override string JsonListObjectAny(MethodCallExpressionModel model) + { + return $"(EXISTS (SELECT * from OPENJSON({model.Args[0].MemberName}) " + + $"WITH([value] NVARCHAR(MAX) '$.{model.Args[1].MemberValue.ToString().ToSqlFilter()}') " + + $"WHERE [value] = {model.Args[2].MemberName}))"; + } + + public override string JsonArrayAny(MethodCallExpressionModel model) + { + return string.Format("(EXISTS(SELECT * from OPENJSON({0}) WHERE [value] = {1}))" + , model.Args[0].MemberName + , model.Args[1].MemberName + ); + } + public override string TrimEnd(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $"CASE WHEN RIGHT({parameterNameA}, 1) = {parameterNameB} THEN LEFT({parameterNameA}, LEN({parameterNameA}) - 1) ELSE {parameterNameA} END"; + } + public override string TrimStart(MethodCallExpressionModel mode) + { + + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" CASE WHEN LEFT({parameterNameA}, 1) = {parameterNameB} THEN RIGHT({parameterNameA}, LEN({parameterNameA}) - 1) ELSE {parameterNameA} END "; + } + + public override string PadLeft(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + var parameterNameC = mode.Args[2].MemberName; + return $" CONCAT(REPLICATE({parameterNameC}, {parameterNameB} - LEN({parameterNameA})), {parameterNameA}) "; + } + + public override string NewUid(MethodCallExpressionModel mode) + { + return " NEWID() "; + } + + public override string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = "(" + string.Join(",", mode.Args[0].MemberValue as List) + ")"; + } + var searchWord = mode.Args[1].MemberName; + return $" CONTAINS({columns},{searchWord}) "; + } + } + + +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerFastBuilder.cs new file mode 100644 index 000000000..f4359b4dc --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerFastBuilder.cs @@ -0,0 +1,92 @@ +using Microsoft.Data.SqlClient; + +using System.Data; + +namespace SqlSugar +{ + + public class SqlServerFastBuilder : FastBuilder, IFastBuilder + { + public override bool IsActionUpdateColumns { get; set; } = true; + public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() + { + HasOffsetTime = true, + IsMerge = true + }; + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + + SqlBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = dt.TableName; + try + { + await bulkCopy.WriteToServerAsync(dt).ConfigureAwait(false); + } + catch (Exception) + { + CloseDb(); + throw; + } + CloseDb(); + return dt.Rows.Count; + } + public SqlBulkCopy GetBulkCopyInstance() + { + SqlBulkCopy copy; + if (this.Context.Ado.Transaction == null) + { + if (this.DbFastestProperties?.IsOffIdentity == true) + { + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.KeepIdentity, null); + } + else + { + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection); + } + } + else + { + if (this.DbFastestProperties?.IsOffIdentity == true) + { + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.KeepIdentity, (SqlTransaction)this.Context.Ado.Transaction); + } + 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; + } + public override Task Merge(string tableName, DataTable dt, EntityInfo entityInfo, string[] whereColumns, string[] updateColumns, List datas) + { + var sqlBuilder = this.Context.Queryable().SqlBuilder; + var insertColumns = entityInfo.Columns + .Where(it => it.IsIgnore == false) + .Where(it => it.IsIdentity == false) + .Where(it => it.OracleSequenceName == null) + .Where(it => it.InsertServerTime == false) + .Where(it => it.InsertSql == null) + .Where(it => it.IsOnlyIgnoreInsert == false); + var whereSql = string.Join(" AND ", whereColumns.Select(it => $"tgt.{sqlBuilder.GetTranslationColumnName(it)}=src.{sqlBuilder.GetTranslationColumnName(it)}")); + var updateColumnsSql = string.Join(" , ", updateColumns.Select(it => $"tgt.{sqlBuilder.GetTranslationColumnName(it)}=src.{sqlBuilder.GetTranslationColumnName(it)}")); + var insertColumnsSqlTgt = string.Join(" , ", insertColumns.Select(it => sqlBuilder.GetTranslationColumnName(it.DbColumnName))); + var insertColumnsSqlsrc = string.Join(" , ", insertColumns.Select(it => "src." + sqlBuilder.GetTranslationColumnName(it.DbColumnName))); + var sql = $@"MERGE INTO {sqlBuilder.GetTranslationColumnName(tableName)} tgt +USING {sqlBuilder.GetTranslationColumnName(dt.TableName)} src +ON ({whereSql}) +WHEN MATCHED THEN + UPDATE SET {updateColumnsSql} +WHEN NOT MATCHED THEN + INSERT ({insertColumnsSqlTgt}) + VALUES ({insertColumnsSqlsrc});"; + + return this.Context.Ado.ExecuteCommandAsync(sql); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerInsertBuilder.cs new file mode 100644 index 000000000..2787b3503 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerInsertBuilder.cs @@ -0,0 +1,82 @@ +using System.Text; + +namespace SqlSugar +{ + public class SqlServerInsertBuilder : InsertBuilder + { + public override Func ConvertInsertReturnIdFunc { get; set; } = (name, sql) => + { + return sql.Replace("select SCOPE_IDENTITY();", "").Replace(")\r\n SELECT", $")\r\n OUTPUT INSERTED.{name} as {name} \r\nSELECT"); + }; + public override bool IsNoPage { get; set; } = true; + 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))); + var result = ""; + if (isSingle) + { + string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => base.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName))); + result = string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 200; + if (this.EntityInfo.Columns.Count > 30) + { + pageSize = 50; + } + else if (this.EntityInfo.Columns.Count > 20) + { + pageSize = 100; + } + if (IsNoPage && IsReturnPkList) + { + pageSize = groupList.Count; + } + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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))))); + ++i; + } + pageIndex++; + batchInsetrSql.Append("\r\n;\r\n"); + } + result = batchInsetrSql.ToString(); + if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + result += "select SCOPE_IDENTITY();"; + } + } + + if (this.IsOffIdentity) + { + var tableName = this.GetTableNameString; + result = $"SET IDENTITY_INSERT {tableName} ON;" + result.TrimEnd(';') + $";SET IDENTITY_INSERT {tableName} OFF"; ; + } + return result; + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs new file mode 100644 index 000000000..07a2f09aa --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs @@ -0,0 +1,130 @@ +using System.Text; + +namespace SqlSugar +{ + public class SqlServerQueryBuilder : QueryBuilder + { + public override string SqlTemplate + { + get + { + return "SELECT {0}{" + UtilConstants.ReplaceKey + "} FROM {1}{2}{3}{4}"; + } + } + public override string ToSqlString() + { + var oldTake = Take; + var oldSkip = Skip; + var isDistinctPage = IsDistinct && (Take > 1 || Skip > 1); + if (isDistinctPage) + { + Take = null; + Skip = null; + } + var result = _ToSqlString(); + if (isDistinctPage) + { + if (this.OrderByValue.HasValue()) + { + Take = int.MaxValue; + result = result.Replace("DISTINCT", $" DISTINCT TOP {int.MaxValue} "); + } + Take = oldTake; + Skip = oldSkip; + result = this.Context.SqlQueryable(result).Skip(Skip ?? 0).Take(Take ?? 0).ToSql().Key; + + + } + if (IsDistinct && oldTake == 1 && oldSkip == null) + { + result = result.Replace(" TOP 1 DISTINCT", " TOP 1 "); + } + if (result.IndexOf("-- No table") > 0) + { + return "-- No table"; + } + return result; + } + public string _ToSqlString() + { + string oldOrderBy = this.OrderByValue; + string externalOrderBy = oldOrderBy; + var isIgnoreOrderBy = this.IsCount && this.PartitionByValue.IsNullOrEmpty(); + AppendFilter(); + sql = new StringBuilder(); + var oldOrderByValue = this.OrderByValue; + if (this.OrderByValue == null && (Skip != null || Take != null)) this.OrderByValue = " ORDER BY GetDate() "; + if (this.PartitionByValue.HasValue()) + { + this.OrderByValue = this.PartitionByValue + this.OrderByValue; + } + var isFirst = (Skip == 0 || Skip == null) && Take == 1 && DisableTop == false; + var isTop = (Skip == null && Take != null && DisableTop == false); + var isRowNumber = (Skip != null || Take != null) && !isFirst && !isTop; + if (!isRowNumber && oldOrderByValue == null) { this.OrderByValue = null; } + if (isFirst && oldOrderByValue == "ORDER BY GETDATE() ") { this.OrderByValue = null; } + var rowNumberString = string.Format(",ROW_NUMBER() OVER({0}) AS RowIndex ", GetOrderByString); + string groupByValue = GetGroupByString + HavingInfos; + string orderByValue = (!isRowNumber && this.OrderByValue.HasValue()) ? GetOrderByString : null; + if (isIgnoreOrderBy) { orderByValue = null; } + sql.AppendFormat(SqlTemplate, GetSelect(isFirst, isTop), base.GetTableNameString, base.GetWhereValueString, groupByValue, orderByValue); + sql.Replace(UtilConstants.ReplaceKey, isRowNumber ? (isIgnoreOrderBy ? null : rowNumberString) : null); + if (isIgnoreOrderBy) { this.OrderByValue = oldOrderBy; return sql.ToString(); } + var result = (isFirst || isTop) ? sql.ToString() : ToPageSql(sql.ToString(), this.Take, this.Skip); + if (ExternalPageIndex > 0) + { + if (externalOrderBy.IsNullOrEmpty()) + { + externalOrderBy = " ORDER BY GetDate() "; + } + result = string.Format("SELECT *,ROW_NUMBER() OVER({0}) AS RowIndex2 FROM ({1}) ExternalTable ", GetExternalOrderBy(externalOrderBy), result); + result = ToPageSql2(result, ExternalPageIndex, ExternalPageSize, true); + } + this.OrderByValue = oldOrderBy; + if (!string.IsNullOrEmpty(this.Offset)) + { + if (this.OrderByValue.IsNullOrEmpty()) + { + result += " ORDER BY GETDATE() "; + if (this.OldSql.HasValue()) + this.OldSql += " ORDER BY GETDATE() "; + } + else + { + if (this.OldSql.HasValue()) + this.OldSql += (" " + this.GetOrderByString); + } + result += this.Offset; + + if (this.OldSql.HasValue()) + this.OldSql += this.Offset; + } + result = GetSqlQuerySql(result); + if (isFirst && IsDistinct) + { + result = result.Replace("TOP 1 DISTINCT", "TOP 1 "); + } + if (this.GroupParameters?.Count > 0 && this.GroupByIsReplace) + { + result = result.Replace(this.GroupBySqlOld, this.GroupBySql); + } + return result; + } + + private string GetSelect(bool isFirst, bool isTop) + { + if (isFirst) + { + return (" TOP 1 " + GetSelectValue); + } + else if (isTop) + { + return ($" TOP {this.Take} " + GetSelectValue); + } + else + { + return GetSelectValue; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerUpdateBuilder.cs new file mode 100644 index 000000000..01bdaeb98 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlBuilder/SqlServerUpdateBuilder.cs @@ -0,0 +1,118 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SqlServerUpdateBuilder : UpdateBuilder + { + protected override string TomultipleSqlString(List> groupList) + { + Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List need Primary key"); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + StringBuilder batchUpdateSql = new StringBuilder(); + while (pageCount >= pageIndex) + { + StringBuilder updateTable = new StringBuilder(); + string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue?.Any() == true) + { + return setValue.First().Value; + } + } + var result = string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName)); + return result; + })); + batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString); + int i = 0; + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) + { + updateTable.Append(SqlTemplateBatchUnion); + } + updateTable.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(base.SqlTemplateBatchSelect, base.GetDbColumn(it, GetValue(it)), Builder.GetTranslationColumnName(it.DbColumnName))))); + ++i; + } + pageIndex++; + updateTable.Append("\r\n"); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += Regex.Replace(item, "\\" + this.Builder.SqlTranslationLeft, "S." + this.Builder.SqlTranslationLeft); + } + } + if (PrimaryKeys.HasValue()) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(item)); + } + } + batchUpdateSql.AppendFormat(SqlTemplateJoin, updateTable, whereString); + } + batchUpdateSql = GetBatchUpdateSql(batchUpdateSql); + return batchUpdateSql.ToString(); + } + + private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql) + { + if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null) + { + var result = batchUpdateSql.ToString(); + foreach (var item in ReSetValueBySqlExpList) + { + var dbColumnName = item.Value.DbColumnName; + if (item.Value.Type == ReSetValueBySqlExpListModelType.List) + { + result = result.Replace($"T.{dbColumnName}", $" S.{dbColumnName}{item.Value.Sql}T.{dbColumnName}"); + } + else + { + result = result.Replace($"T.{dbColumnName}", item.Value.Sql.Replace(dbColumnName, "S." + dbColumnName)); + } + batchUpdateSql = new StringBuilder(result); + } + } + + return batchUpdateSql; + } + + private object GetValue(DbColumnInfo it) + { + if (it.SqlParameterDbType?.Equals(System.Data.DbType.AnsiString) == true) + { + var value = FormatValue(it.Value); + if (value is string && value.ObjToString().StartsWith("N'")) + { + return value.ObjToString().TrimStart('N'); + } + else + { + return value; + } + } + else + { + return FormatValue(it.Value); + } + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlServerProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlServerProvider.cs new file mode 100644 index 000000000..ae8ea03ae --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/SqlServer/SqlServerProvider.cs @@ -0,0 +1,234 @@ +using Microsoft.Data.SqlClient; + +using System.Data; +using System.Data.Common; +using System.Xml.Linq; + +namespace SqlSugar +{ + public class SqlServerProvider : AdoProvider + { + + public SqlServerProvider() + { + this.IsOpenAsync = true; + } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + base._DbConnection = new SqlConnection(base.Context.CurrentConnectionConfig.ConnectionString); + } + catch (Exception ex) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + /// + /// Only SqlServer + /// + /// + public override void BeginTran(string transactionName) + { + CheckConnection(); + base.Transaction = ((SqlConnection)this.Connection).BeginTransaction(transactionName); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + CheckConnection(); + base.Transaction = ((SqlConnection)this.Connection).BeginTransaction(iso, transactionName); + } + public override IDataAdapter GetAdapter() + { + return new SqlDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + SqlCommand sqlCommand = new SqlCommand(sql, (SqlConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (SqlTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + SqlParameter[] ipars = GetSqlParameter(parameters); + sqlCommand.Parameters.AddRange(ipars); + } + CheckConnection(); + return sqlCommand; + } + public override async Task GetCommandAsync(string sql, SugarParameter[] parameters) + { + SqlCommand sqlCommand = new SqlCommand(sql, (SqlConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (SqlTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + SqlParameter[] ipars = GetSqlParameter(parameters); + sqlCommand.Parameters.AddRange(ipars); + } + await CheckConnectionAsync().ConfigureAwait(false); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((SqlDataAdapter)dataAdapter).SelectCommand = (SqlCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + SqlParameter[] result = new SqlParameter[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new SqlParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + //sqlParameter.UdtTypeName = parameter.UdtTypeName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + ++index; + } + return result; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public SqlParameter[] GetSqlParameter(params SugarParameter[] parameters) + { + var isVarchar = this.Context.IsVarchar(); + if (parameters == null || parameters.Length == 0) return null; + SqlParameter[] result = new SqlParameter[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new SqlParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + if (!string.IsNullOrEmpty(parameter.UdtTypeName)) + { + sqlParameter.UdtTypeName = parameter.UdtTypeName; + } + //sqlParameter.UdtTypeName = parameter.UdtTypeName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = GetDbType(parameter); + var isTime = parameter.DbType == System.Data.DbType.Time; + if (isTime) + { + sqlParameter.SqlDbType = SqlDbType.Time; + if (sqlParameter.Value != DBNull.Value) + { + sqlParameter.Value = DateTime.Parse(parameter.Value?.ToString()).TimeOfDay; + } + } + else if (parameter.Value != null && parameter.Value is XElement) + { + sqlParameter.SqlDbType = SqlDbType.Xml; + sqlParameter.Value = (parameter.Value as XElement).ToString(); + } + if (sqlParameter.Value != null && sqlParameter.Value != DBNull.Value && sqlParameter.DbType == System.Data.DbType.DateTime) + { + var date = Convert.ToDateTime(sqlParameter.Value); + if (date == DateTime.MinValue) + { + sqlParameter.Value = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + } + } + if (parameter.Direction == 0) + { + parameter.Direction = ParameterDirection.Input; + } + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (parameter.TypeName.HasValue()) + { + sqlParameter.TypeName = parameter.TypeName; + sqlParameter.SqlDbType = SqlDbType.Structured; + sqlParameter.DbType = System.Data.DbType.Object; + } + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + if (parameter.CustomDbType != null && parameter.CustomDbType is SqlDbType) + { + sqlParameter.SqlDbType = ((SqlDbType)parameter.CustomDbType); + } + if (sqlParameter.Direction == ParameterDirection.Output && parameter.Scale > 0) + { + sqlParameter.Scale = parameter.Scale; + } + ++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/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/CodeFirst/SqliteCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/CodeFirst/SqliteCodeFirst.cs new file mode 100644 index 000000000..84192bbb3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/CodeFirst/SqliteCodeFirst.cs @@ -0,0 +1,178 @@ +namespace SqlSugar +{ + public class SqliteCodeFirst : CodeFirstProvider + { + public override void ExistLogic(EntityInfo entityInfo) + { + if (entityInfo.Columns.HasValue() && entityInfo.IsDisabledUpdateAll == false) + { + if (entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1) + { + AddColumn(entityInfo); + return; + } + + var tableName = GetTableName(entityInfo); + var dbColumns = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName, false); + ConvertColumns(dbColumns); + var entityColumns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + var dropColumns = dbColumns + .Where(dc => !entityColumns.Any(ec => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(dc => !entityColumns.Any(ec => dc.DbColumnName.Equals(ec.DbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .ToList(); + var addColumns = entityColumns + .Where(ec => ec.OldDbColumnName.IsNullOrEmpty() || !dbColumns.Any(dc => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(ec => !dbColumns.Any(dc => ec.DbColumnName.Equals(dc.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + //var alterColumns = entityColumns + // .Where(ec => !dbColumns.Any(dc => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + // .Where(ec => + // dbColumns.Any(dc => dc.DbColumnName.Equals(ec.DbColumnName) + // && ((!UtilMethods.GetUnderType(ec.PropertyInfo).IsEnum() && UtilMethods.GetUnderType(ec.PropertyInfo).IsIn(UtilConstants.StringType)) || + + // IsSamgeType(ec, dc)))).ToList(); + var renameColumns = entityColumns + .Where(it => !string.IsNullOrEmpty(it.OldDbColumnName)) + .Where(entityColumn => dbColumns.Any(dbColumn => entityColumn.OldDbColumnName.Equals(dbColumn.DbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .ToList(); + + + var isChange = false; + foreach (var item in addColumns) + { + this.Context.DbMaintenance.AddColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + isChange = true; + } + foreach (var item in dropColumns) + { + //only support .net core + if (this.Context.CurrentConnectionConfig?.MoreSettings?.SqliteCodeFirstEnableDropColumn == true) + { + this.Context.DbMaintenance.DropColumn(tableName, item.DbColumnName); + isChange = true; + } + } + //foreach (var item in alterColumns) + //{ + // //this.Context.DbMaintenance.AddColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + // //isChange = true; + //} + foreach (var item in renameColumns) + { + throw new NotSupportedException("rename Column"); + } + + foreach (var item in entityColumns) + { + var dbColumn = dbColumns.FirstOrDefault(dc => dc.DbColumnName.Equals(item.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (dbColumn == null) continue; + bool pkDiff, idEntityDiff; + KeyAction(item, dbColumn, out pkDiff, out idEntityDiff); + if (dbColumn != null && pkDiff && !idEntityDiff) + { + var isAdd = item.IsPrimarykey; + if (isAdd) + { + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + else + { + this.Context.DbMaintenance.DropConstraint(tableName, string.Format("PK_{0}_{1}", tableName, item.DbColumnName)); + } + } + else if (pkDiff || idEntityDiff) + { + ChangeKey(entityInfo, tableName, item); + } + } + if (isChange && base.IsBackupTable) + { + this.Context.DbMaintenance.BackupTable(tableName, tableName + DateTime.Now.ToString("yyyyMMddHHmmss"), MaxBackupDataRows); + } + } + } + + private void AddColumn(EntityInfo entityInfo) + { + var tableName2 = GetTableName(entityInfo); + var dbColumns2 = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName2, false); + var entityColumns2 = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + ConvertColumns(dbColumns2); + var addColumns2 = entityColumns2 + .Where(ec => ec.OldDbColumnName.IsNullOrEmpty() || !dbColumns2.Any(dc => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(ec => !dbColumns2.Any(dc => ec.DbColumnName.Equals(dc.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + foreach (var item in addColumns2) + { + if (item.IsPrimarykey || item.IsIdentity) + { + Check.ExceptionEasy("Multiple primary keys cannot be modified", "多主键不能修改"); + } + this.Context.DbMaintenance.AddColumn(tableName2, EntityColumnToDbColumn(entityInfo, tableName2, item)); + } + } + + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + string backupName = tableName + DateTime.Now.ToString("yyyyMMddHHmmss"); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).Where(it => it.IsIgnore == false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + } + } + this.Context.DbMaintenance.CreateTable(tableName, columns, true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + CreateTableFieldSort = item.CreateTableFieldSort + }; + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName, null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbBind/SqliteDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbBind/SqliteDbBind.cs new file mode 100644 index 000000000..79393d422 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbBind/SqliteDbBind.cs @@ -0,0 +1,109 @@ +namespace SqlSugar +{ + public class SqliteDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + { + return "blob"; + } + if (csharpTypeName == "Int32") + csharpTypeName = "int"; + if (csharpTypeName == "Int16") + csharpTypeName = "short"; + if (csharpTypeName == "Int64") + csharpTypeName = "long"; + if (csharpTypeName == "Boolean") + csharpTypeName = "bool"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)); + return mappings.Any() ? mappings.First().Key : "varchar"; + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>() + { + + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("int32",CSharpDataType.@int), + new KeyValuePair("integer32",CSharpDataType.@int), + new KeyValuePair("number",CSharpDataType.@int), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("varchar2",CSharpDataType.@string), + new KeyValuePair("nvarchar",CSharpDataType.@string), + new KeyValuePair("nvarchar2",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("ntext",CSharpDataType.@string), + new KeyValuePair("blob_text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("nchar",CSharpDataType.@string), + new KeyValuePair("num",CSharpDataType.@string), + new KeyValuePair("currency",CSharpDataType.@string), + new KeyValuePair("datetext",CSharpDataType.@string), + new KeyValuePair("word",CSharpDataType.@string), + new KeyValuePair("graphic",CSharpDataType.@string), + + new KeyValuePair("tinyint",CSharpDataType.@byte), + new KeyValuePair("unsignedinteger8",CSharpDataType.@byte), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("int16",CSharpDataType.@short), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("int64",CSharpDataType.@long), + new KeyValuePair("long",CSharpDataType.@long), + new KeyValuePair("integer64",CSharpDataType.@long), + new KeyValuePair("bit",CSharpDataType.@bool), + new KeyValuePair("bool",CSharpDataType.@bool), + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("real",CSharpDataType.@double), + new KeyValuePair("double",CSharpDataType.@double), + new KeyValuePair("float",CSharpDataType.@float), + new KeyValuePair("float",CSharpDataType.Single), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("dec",CSharpDataType.@decimal), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("smallmoney",CSharpDataType.@decimal), + + new KeyValuePair("datetime",CSharpDataType.DateTime), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + + new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("clob",CSharpDataType.byteArray), + new KeyValuePair("raw",CSharpDataType.byteArray), + new KeyValuePair("oleobject",CSharpDataType.byteArray), + new KeyValuePair("binary",CSharpDataType.byteArray), + new KeyValuePair("photo",CSharpDataType.byteArray), + new KeyValuePair("picture",CSharpDataType.byteArray), + + new KeyValuePair("uniqueidentifier",CSharpDataType.Guid), + new KeyValuePair("varchar",CSharpDataType.Guid), + new KeyValuePair("guid",CSharpDataType.Guid) + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbFirst/SqliteDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbFirst/SqliteDbFirst.cs new file mode 100644 index 000000000..528a8c111 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbFirst/SqliteDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar +{ + public class SqliteDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs new file mode 100644 index 000000000..5acf1377e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs @@ -0,0 +1,610 @@ +using Microsoft.Data.Sqlite; + +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public class SqliteDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string GetTableInfoListSql + { + get + { + return @"select Name from sqlite_master where type='table' and name<>'sqlite_sequence' order by name;"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select Name from sqlite_master where type='view' order by name;"; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + throw new NotSupportedException(); + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD COLUMN {1} {2}{3}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + // return "ALTER TABLE {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + throw new NotSupportedException(); + } + } + protected override string BackupDataBaseSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE IF NOT EXISTS {0}(\r\n{1} $PrimaryKey )"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "DELETE FROM {0}"; + } + } + protected override string BackupTableSql + { + get + { + return " CREATE TABLE {0} AS SELECT * FROM {1} limit 0,{2}"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP {1}"; + } + } + protected override string DropConstraintSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string RenameColumnSql + { + get + { + throw new NotSupportedException(); + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select Name from sqlite_master limit 0,1"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "AUTOINCREMENT"; + } + } + + protected override string AddColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string AddTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string DeleteTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string RenameTableSql + { + get + { + return "alter table {0} rename to {1}"; + } + } + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0}({1})"; + } + } + + protected override string IsAnyIndexSql + { + get + { + return "SELECT count(*) FROM sqlite_master WHERE name = '{0}'"; + } + } + + protected override string AddDefaultValueSql => throw new NotSupportedException(" Sqlite no support default value"); + #endregion + + #region Methods + public override bool UpdateColumn(string tableName, DbColumnInfo column) + { + var isTran = this.Context.Ado.IsNoTran(); + try + { + if (column.IsPrimarykey) + { + Check.ExceptionEasy("Sqlite no support alter column primary key", "Sqlite不支持修改主键"); + } + + if (isTran) + // Start a transaction + this.Context.Ado.BeginTran(); + + tableName = tableName ?? column.TableName; + var oldColumn = column.DbColumnName; + var tempColumn = "Column" + SnowFlakeSingle.Instance.NextId(); + + // Step 1: Add a new column + column.DbColumnName = tempColumn; + column.DefaultValue = null; + this.AddColumn(tableName, column); + + // Step 2: Update values from old column to new column + this.Context.Ado.ExecuteCommand($"UPDATE {SqlBuilder.GetTranslationColumnName(tableName)} SET {SqlBuilder.GetTranslationColumnName(column.DbColumnName)}={SqlBuilder.GetTranslationColumnName(oldColumn)}"); + + // Step 3: Drop the old column + this.DropColumn(tableName, oldColumn); + + // Step 4: Rename the new column to the old column name + column.DbColumnName = oldColumn; + this.AddColumn(tableName, column); + + // Step 5: Update values from temporary column to the new column + this.Context.Ado.ExecuteCommand($"UPDATE {SqlBuilder.GetTranslationColumnName(tableName)} SET {SqlBuilder.GetTranslationColumnName(column.DbColumnName)}={SqlBuilder.GetTranslationColumnName(tempColumn)}"); + + //Step 6: Drop the temporary column + this.DropColumn(tableName, tempColumn); + + if (isTran) + // Commit the transaction + this.Context.Ado.CommitTran(); + + return true; + } + catch (Exception) + { + if (isTran) + // Handle exceptions, log, or rollback the transaction if necessary + this.Context.Ado.RollbackTran(); + // Log the exception or throw it again based on your requirements + throw; + } + } + public override List GetDbTypes() + { + return this.Context.Ado.SqlQuery(@"SELECT 'TEXT' AS Data_Type +UNION +SELECT 'INTEGER' +UNION +SELECT 'REAL' +UNION +SELECT 'BLOB' +UNION SELECT 'bigint' + UNION SELECT 'binary' + UNION SELECT 'bit' + UNION SELECT 'char' + UNION SELECT 'date' + UNION SELECT 'datetime' + UNION SELECT 'datetime2' + UNION SELECT 'datetimeoffset' + UNION SELECT 'decimal' + UNION SELECT 'float' + UNION SELECT 'image' + UNION SELECT 'int' + UNION SELECT 'money' + UNION SELECT 'nchar' + UNION SELECT 'ntext' + UNION SELECT 'numeric' + UNION SELECT 'nvarchar' + UNION SELECT 'smalldatetime' + UNION SELECT 'smallint' + UNION SELECT 'text' + UNION SELECT 'time' + UNION SELECT 'timestamp' + UNION SELECT 'tinyint' + UNION SELECT 'uniqueidentifier' + UNION SELECT 'varbinary' + UNION SELECT 'varchar' + UNION SELECT 'xml' "); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT name +FROM sqlite_master +WHERE type = 'trigger' +AND sql LIKE '%" + tableName + "%'"); + } + public override List GetFuncList() + { + return new List(); + } + public override List GetIndexList(string tableName) + { + var sql = $"PRAGMA index_list('{tableName}');"; + return this.Context.Ado.SqlQuery(sql); + } + public override void AddDefaultValue(EntityInfo entityInfo) + { + //sqlite no support AddDefaultValue + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + Console.WriteLine("sqlite no support AddDefaultValue"); + return true; + } + public override bool TruncateTable(string tableName) + { + base.TruncateTable(tableName);//delete data + try + { + //clear sqlite identity + return this.Context.Ado.ExecuteCommand($"UPDATE sqlite_sequence SET seq = 0 WHERE name = '{tableName}'") > 0; + } + catch + { + //if no identity sqlite_sequence + return true; + } + } + /// + ///by current connection string + /// + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + var connString = this.Context.CurrentConnectionConfig.ConnectionString; + var path = Regex.Match(connString, @"[a-z,A-Z]\:\\.+\\").Value; + if (path.IsNullOrEmpty()) + { + path = Regex.Match(connString, @"\/.+\/").Value; + } + if (path.IsNullOrEmpty()) + { + path = Regex.Match(connString, @"[a-z,A-Z]\:\\").Value; + } + if (!FileHelper.IsExistDirectory(path)) + { + FileHelper.CreateDirectory(path); + } + this.Context.Ado.Connection.Open(); + this.Context.Ado.Connection.Close(); + return true; + } + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + string cacheKey = "DbMaintenanceProvider.GetColumnInfosByTableName." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower(); + cacheKey = GetCacheKey(cacheKey); + if (isCache) + { + return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate>(cacheKey, () => + { + return GetColumnInfosByTableName(tableName); + + }); + } + else + { + return GetColumnInfosByTableName(tableName); + } + } + + private List GetColumnInfosByTableName(string tableName) + { + //var columns = GetColumnsByTableName2(tableName); + string sql = "PRAGMA table_info(" + SqlBuilder.GetTranslationColumnName(tableName) + ")"; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var tableSript = this.Context.Ado.GetString($"SELECT sql FROM sqlite_master WHERE name='{tableName}' AND type='table'"); + using (DbDataReader dataReader = (SqliteDataReader)this.Context.Ado.GetDataReader(sql)) + { + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + List result = new List(); + while (dataReader.Read()) + { + var type = dataReader.GetValue(2).ObjToString(); + var length = 0; + var decimalDigits = 0; + if (type.Contains('(')) + { + if (type.Contains(',')) + { + var digit = type.Split('(').Last().TrimEnd(')'); + decimalDigits = digit.Split(',').Last().ObjToInt(); + length = digit.Split(',').First().ObjToInt(); + } + else + { + length = type.Split('(').Last().TrimEnd(')').ObjToInt(); + } + type = type.Split('(').First(); + } + //bool isIdentity = columns.FirstOrDefault(it => it.DbColumnName.Equals(dataReader.GetString(1),StringComparison.CurrentCultureIgnoreCase)).IsIdentity; + DbColumnInfo column = new DbColumnInfo() + { + TableName = this.SqlBuilder.GetNoTranslationColumnName(tableName + ""), + DataType = type, + IsNullable = !dataReader.GetBoolean(3), + IsIdentity = tableSript.Contains("AUTOINCREMENT") && dataReader.GetBoolean(5).ObjToBool(), + ColumnDescription = null, + DbColumnName = dataReader.GetString(1), + DefaultValue = dataReader.GetValue(4).ObjToString(), + IsPrimarykey = dataReader.GetBoolean(5).ObjToBool(), + Length = length, + DecimalDigits = decimalDigits, + Scale = decimalDigits + }; + result.Add(column); + } + return result; + } + } + private List GetColumnsByTableName2(string tableName) + { + tableName = SqlBuilder.GetTranslationTableName(tableName); + string sql = "select * from " + tableName + " limit 0,1"; + var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + using (DbDataReader reader = (SqliteDataReader)this.Context.Ado.GetDataReader(sql)) + { + this.Context.Ado.IsEnableLogEvent = oldIsEnableLog; + List result = new List(); + var schemaTable = reader.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + { + DbColumnInfo column = new DbColumnInfo() + { + TableName = tableName, + IsIdentity = (bool)row["IsAutoIncrement"], + DbColumnName = row["ColumnName"].ToString(), + }; + result.Add(column); + } + return result; + } + } + public override bool AddRemark(EntityInfo entity) + { + return true; + } + + + public override bool BackupTable(string oldTableName, string newTableName, int maxBackupDataRows = int.MaxValue) + { + oldTableName = this.SqlBuilder.GetTranslationTableName(oldTableName); + newTableName = this.SqlBuilder.GetTranslationTableName(newTableName); + string sql = string.Format(this.BackupTableSql, newTableName, oldTableName, maxBackupDataRows); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + //if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase)) + //{ + // item.Length = 20; + //} + if (item.IsIdentity && !item.IsPrimarykey) + { + Check.Exception(true, "Identity only primary key"); + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + + if (!isCreatePrimaryKey || columns.Count(it => it.IsPrimarykey) > 1) + { + sql = sql.Replace("PRIMARY KEY AUTOINCREMENT", "").Replace("PRIMARY KEY", ""); + } + + if (columns.Count(it => it.IsPrimarykey) > 1 && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(",\r\n Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName)))); + primaryKeyInfo = primaryKeyInfo.Replace('`', '\"'); + } + + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + + this.Context.Ado.ExecuteCommand(sql); + return true; + } + 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 = item.DbColumnName; + string dataType = item.DataType; + if (dataType == "varchar" && item.Length == 0) + { + item.Length = 1; + } + string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = item.IsPrimarykey ? this.CreateTablePirmaryKey : null; + string identity = item.IsIdentity ? this.CreateTableIdentity : null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName), dataType, dataSize, nullType, primaryKey, identity); + if (item.DefaultValue.HasValue() && this.Context.CurrentConnectionConfig?.MoreSettings?.SqliteCodeFirstEnableDefaultValue == true) + { + var value = item.DefaultValue; + if (!value.Contains('(') && !value.EqualCase("CURRENT_TIMESTAMP") && !value.StartsWith('\'')) + { + value = value.ToSqlValue(); + } + addItem = $"{addItem} DEFAULT {value}"; + } + if (item.ColumnDescription.HasValue() && this.Context.CurrentConnectionConfig?.MoreSettings?.SqliteCodeFirstEnableDescription == true) + { + addItem = $"{addItem} /*{item.ColumnDescription.Replace("\r", "").Replace("\n", "")}*/ "; + } + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",\r\n", columnArray)); + tableString = tableString.Replace('`', '\"'); + return tableString; + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("MySql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + this.Context.Ado.ExecuteCommand($"PRAGMA main.page_size=1024; PRAGMA main.locking_mode=EXCLUSIVE; PRAGMA main.cache_size=5000; PRAGMA main.synchronous=NORMAL; PRAGMA main.journal_mode=WAL; VACUUM INTO '{fullFileName.ToSqlFilter()}'"); + return false; + } + //private List GetListOrCache(string cacheKey, string sql) + //{ + // return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, + // () => + // { + // var isEnableLogEvent = this.Context.Ado.IsEnableLogEvent; + // this.Context.Ado.IsEnableLogEvent = false; + // var reval = this.Context.Ado.SqlQuery(sql); + // this.Context.Ado.IsEnableLogEvent = isEnableLogEvent; + // return reval; + // }); + //} + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/Queryable/SqliteQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/Queryable/SqliteQueryable.cs new file mode 100644 index 000000000..b1c052800 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/Queryable/SqliteQueryable.cs @@ -0,0 +1,60 @@ +namespace SqlSugar +{ + public class SqliteQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + this.GroupBy(groupFileds); + return this; + } + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } + public class SqliteQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteBuilder.cs new file mode 100644 index 000000000..95bb0def9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteBuilder.cs @@ -0,0 +1,39 @@ +namespace SqlSugar +{ + public class SqliteBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft { get { return "`"; } } + public override string SqlTranslationRight { get { return "`"; } } + public override string SqlDateNow + { + get + { + return " DATETIME('now', 'localtime') "; + } + } + public override string FullSqlDateNow + { + get + { + return "select DATETIME('now', 'localtime') "; + } + } + public override string RemoveParentheses(string sql) + { + if (sql.StartsWith('(') && sql.EndsWith(')') && sql.Contains("limit", StringComparison.CurrentCultureIgnoreCase)) + { + sql = $" select * from {sql} sqlite_temp_table "; + } + if (sql.StartsWith('(') && sql.EndsWith(')')) + { + sql = sql.Substring(1, sql.Length - 2); + } + + return sql; + } + public override string RemoveN(string sql) + { + return sql?.Replace("N", ""); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteDeleteBuilder.cs new file mode 100644 index 000000000..9c70f83af --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar +{ + public class SqliteDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteExpressionContext.cs new file mode 100644 index 000000000..8e8cb74a0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteExpressionContext.cs @@ -0,0 +1,347 @@ +namespace SqlSugar +{ + public class SqliteExpressionContext : ExpressionContext, ILambdaExpressions + { + public override ExpressionContextCase Case { get; set; } = new ExpressionContextCase() + { + IsDateString = true, + }; + public SqlSugarProvider Context { get; set; } + public SqliteExpressionContext() + { + base.DbMehtods = new SqliteMethod(); + } + public override string SqlTranslationLeft { get { return "`"; } } + public override string SqlTranslationRight { get { return "`"; } } + } + public class SqliteMethod : DefaultDbMethod, IDbMethods + { + public override string UNIX_TIMESTAMP(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + return $" CAST(STRFTIME('%s', {parameterNameA}) AS INTEGER) "; + } + public override string WeekOfYear(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $"STRFTIME('%W', {parameterNameA})+1 "; + } + public override string Equals(MethodCallExpressionModel model) + { + var result = base.Equals(model); + if (model.Args.Count == 3 && result.Trim().Last() == ')') + { + result = (" " + result.Trim().TrimEnd(')') + " COLLATE NOCASE ) "); + } + return result; + } + public override string JsonIndex(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"json_extract({parameter.MemberName}, '$[{parameter1.MemberValue}]')"; + } + public override string JsonField(MethodCallExpressionModel model) + { + var hasPrefix = model.Args[1].MemberValue is string v ? v[0] == '$' : false; + model.Parameters.RemoveAll(item => item.ParameterName == model.Args[1].MemberName + ""); + return string.Format("json_extract({0},'{1}{2}')", + model.Args[0].MemberName, + hasPrefix ? string.Empty : string.Intern("$."), + model.Args[1].MemberValue); + } + public override string GetStringJoinSelector(string result, string separator) + { + return $"group_concat({result},'{separator}') "; + } + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString())); + var begin = model.Args[1].MemberName; + var end = model.Args[2].MemberName; + switch (parameter) + { + case DateType.Year: + return $" ( strftime('%Y',{end}) - strftime('%Y',{begin}) )"; + case DateType.Month: + return $" ( (strftime('%m',{end}) - strftime('%m',{begin}))+(strftime('%Y',{end}) - strftime('%Y',{begin}))*12 )"; + case DateType.Day: + return $" (julianday( strftime('%Y-%m-%d',datetime({end})) )-julianday(strftime('%Y-%m-%d',datetime({begin})))) "; + case DateType.Hour: + return $" ((julianday( strftime('%Y-%m-%d %H:%M',datetime({end})) )- julianday(strftime('%Y-%m-%d %H:%M',datetime({begin}))))*24 )"; + case DateType.Minute: + return $" ((julianday( strftime('%Y-%m-%d %H:%M',datetime({end})) )- julianday(strftime('%Y-%m-%d %H:%M',datetime({begin}))))*24*60 )"; + case DateType.Second: + return $" ((julianday( strftime('%Y-%m-%d %H:%M:%S',datetime({end})) )- julianday(strftime('%Y-%m-%d %H:%M:%S',datetime({begin}))))*24*60*60 )"; + case DateType.Millisecond: + break; + default: + break; + } + throw new Exception(parameter + " datediff no support"); + } + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("LENGTH({0})", parameter.MemberName); + } + + public override string Substring(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format("SUBSTR({0},1 + {1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.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 ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INTEGER)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INTEGER)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS TEXT)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS TEXT)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS SIGNED)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" DATETIME({0})", parameter.MemberName); + } + + public override string ToDateShort(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" strftime('%Y-%m-%d', {0})", parameter.MemberName); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + if (parameter2.MemberValue.ObjToInt() < 0) + { + return string.Format(" DATE(DATETIME({0}), '-{1} days')", parameter.MemberName, Math.Abs(parameter2.MemberValue.ObjToInt())); + } + else + { + return string.Format(" DATE(DATETIME({0}), '+{1} days')", parameter.MemberName, parameter2.MemberValue); + } + } + + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0].MemberName; + var parameter2 = model.Args[1].MemberValue; + var parameter3 = model.Args[2].MemberValue; + if (parameter2.ObjToInt() < 0) + { + return string.Format(" DATETIME(DATETIME({0}), '-{1} {2}s')", parameter, Math.Abs(parameter2.ObjToInt()), parameter3); + } + else + { + return string.Format(" DATETIME(DATETIME({0}), '+{1} {2}s')", parameter, parameter2, parameter3); + } + } + + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var typeName = model.Args[1].MemberValue.ToString(); + var parameter2 = typeName; + var type = (DateType)Enum.Parse(typeof(DateType), parameter2, false); + switch (type) + { + case DateType.Year: + parameter2 = "%Y"; + break; + case DateType.Month: + parameter2 = "%m"; + break; + case DateType.Day: + parameter2 = "%d"; + return string.Format(" CAST(STRFTIME('{1}', DATETIME(DATETIME(strftime('%Y-%m-%d', {0})), 'LOCALTIME')) AS INTEGER)", parameter.MemberName, parameter2); + case DateType.Hour: + parameter2 = "%H"; + break; + case DateType.Second: + parameter2 = "%S"; + break; + case DateType.Minute: + parameter2 = "%M"; + break; + case DateType.Weekday: + return $" cast (strftime('%w', {parameter.MemberName}) as integer) "; + case DateType.Millisecond: + default: + Check.ThrowNotSupportedException(typeName); + break; + } + return string.Format(" CAST(STRFTIME('{1}', DATETIME({0}) ) AS INTEGER)", parameter.MemberName, parameter2); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0].MemberName; + var parameter2 = model.Args[1].MemberName; + int time = 1; + return string.Format(" strftime('%Y-%m-%d', {0})= strftime('%Y-%m-%d', {1}) ", parameter, parameter2, time); + } + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0].MemberName; + var parameter2 = model.Args[1].MemberName; + var parameter3 = model.Args[2].MemberValue; + var type = (DateType)Enum.Parse(typeof(DateType), parameter3.ObjToString(), false); + int time = 1; + switch (type) + { + case DateType.Year: + time = time * 1 / 365; + break; + case DateType.Month: + time = time * 1 / 30; + break; + case DateType.Day: + break; + case DateType.Hour: + time = time * 24; + break; + case DateType.Second: + time = time * 24 * 60 * 60; + break; + case DateType.Minute: + time = time * 24 * 60; + break; + case DateType.Millisecond: + time = time * 24 * 60 * 60 * 1000; + break; + } + return string.Format(" Cast((JulianDay({0}) - JulianDay({1})) *{2} As INTEGER)", parameter, parameter2, time); + } + + public override string MergeString(params string[] strings) + { + return string.Join("||", strings).Replace("+", ""); + } + + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("IFNULL({0},{1})", parameter.MemberName, parameter1.MemberName); + } + + public override string GetDate() + { + return "DATETIME('now', 'localtime')"; + } + + public override string GetRandom() + { + return "RANDOM()"; + } + + public override string CharIndex(MethodCallExpressionModel model) + { + var parameterNameA = model.Args[0].MemberName; + var parameterNameB = model.Args[1].MemberName; + return $" INSTR(LOWER({parameterNameA}), LOWER({parameterNameB})) "; + } + + public override string TrimEnd(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" CASE WHEN SUBSTR({parameterNameA}, -1) = {parameterNameB} THEN SUBSTR({parameterNameA}, 1, LENGTH({parameterNameA}) - 1) ELSE {parameterNameA} END "; + } + public override string TrimStart(MethodCallExpressionModel mode) + { + + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" CASE WHEN SUBSTR({parameterNameA}, 1, 1) ={parameterNameB} THEN SUBSTR({parameterNameA}, 2) ELSE {parameterNameA} END "; + } + + public override string PadLeft(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + var parameterNameC = mode.Args[2].MemberName; + var value = new string[mode.Args[1].MemberValue.ObjToInt()].Select(it => parameterNameC); + return $"substr({string.Join("||", value)} || {parameterNameA}, {parameterNameB}*-1) "; + } + + public override string Left(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" SUBSTR({parameterNameA}, 1, {parameterNameB}) "; + } + public override string Right(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + var parameterNameB = mode.Args[1].MemberName; + return $" SUBSTR({parameterNameA}, -2, {parameterNameB}) "; + } + + public override string NewUid(MethodCallExpressionModel mode) + { + return " substr(upper(hex(randomblob(4))), 1, 8) || '-' ||\r\n substr(upper(hex(randomblob(2))), 1, 4) || '-' ||\r\n '4' || substr(upper(hex(randomblob(2))), 2, 3) || '-' ||\r\n substr('89ab', 1 + (abs(random()) % 4), 1) || substr(upper(hex(randomblob(2))), 2, 3) || '-' ||\r\n substr(upper(hex(randomblob(6))), 1, 12) "; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs new file mode 100644 index 000000000..1ef722003 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs @@ -0,0 +1,212 @@ +using Microsoft.Data.Sqlite; + +using System.Data; + +namespace SqlSugar +{ + public class SqliteFastBuilder : IFastBuilder + { + public EntityInfo FastEntityInfo { get; set; } + private EntityInfo entityInfo; + private bool IsUpdate = false; + public string CharacterSet { get; set; } + private DataTable UpdateDataTable { get; set; } + public bool IsActionUpdateColumns { get; set; } + public DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() { IsNoCopyDataTable = true }; + public SqliteFastBuilder(EntityInfo entityInfo) + { + this.entityInfo = entityInfo; + } + + public SqlSugarProvider Context { get; set; } + + public void CloseDb() + { + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) + { + this.Context.Close(); + } + } + + public async Task CreateTempAsync(DataTable dt) where T : class, new() + { + await Task.Delay(0).ConfigureAwait(false); + IsUpdate = true; + } + + + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + if (dt.Rows.Count == 0 || IsUpdate) + { + this.UpdateDataTable = dt; + return 0; + } + foreach (var item in this.entityInfo.Columns) + { + if (item.IsIdentity && dt.Columns.Contains(item.DbColumnName)) + { + dt.Columns.Remove(item.DbColumnName); + } + } + var dictionary = this.Context.Utilities.DataTableToDictionaryList(dt.Rows.Cast().Take(1).CopyToDataTable()); + int result = 0; + var cn = this.Context.Ado.Connection as SqliteConnection; + Open(cn); + if (this.Context.Ado.Transaction == null) + { + using (var transaction = cn.BeginTransaction()) + { + result = await _BulkCopy(dt, dictionary, result, cn).ConfigureAwait(false); + transaction.Commit(); + } + } + else + { + result = await _BulkCopy(dt, dictionary, result, cn).ConfigureAwait(false); + } + return result; + } + + private async Task _BulkCopy(DataTable dt, List> dictionary, int i, SqliteConnection cn) + { + using (var cmd = cn.CreateCommand()) + { + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) + { + foreach (DataRow item in dt.Rows) + { + cmd.CommandText = this.Context.Insertable(UtilMethods.DataRowToDictionary(item)).AS(dt.TableName).ToSqlString().Replace(";SELECT LAST_INSERT_ROWID();", ""); + i += await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); + } + } + else + { + cmd.CommandText = this.Context.Insertable(dictionary.First()).AS(dt.TableName).ToSql().Key.Replace(";SELECT LAST_INSERT_ROWID();", ""); + foreach (DataRow dataRow in dt.Rows) + { + foreach (DataColumn item in dt.Columns) + { + if (IsBoolTrue(dataRow, item)) + { + cmd.Parameters.AddWithValue("@" + item.ColumnName, true); + } + else if (IsBoolFalse(dataRow, item)) + { + cmd.Parameters.AddWithValue("@" + item.ColumnName, false); + } + else + { + cmd.Parameters.AddWithValue("@" + item.ColumnName, dataRow[item.ColumnName]); + } + } + i += await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); + cmd.Parameters.Clear(); + } + } + } + return i; + } + private async Task _BulkUpdate(DataTable dt, List> dictionary, int i, string[] whereColums, string[] updateColums, SqliteConnection cn) + { + using (var cmd = cn.CreateCommand()) + { + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) + { + foreach (DataRow item in dt.Rows) + { + cmd.CommandText = this.Context.Updateable(UtilMethods.DataRowToDictionary(item)) + .WhereColumns(whereColums) + .UpdateColumns(updateColums) + .AS(dt.TableName).ToSqlString(); + i += await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); + } + } + else + { + cmd.CommandText = this.Context.Updateable(dictionary.First()) + .WhereColumns(whereColums) + .UpdateColumns(updateColums) + .AS(dt.TableName).ToSql().Key; + + foreach (DataRow dataRow in dt.Rows) + { + foreach (DataColumn item in dt.Columns) + { + if (IsBoolTrue(dataRow, item)) + { + cmd.Parameters.AddWithValue("@" + item.ColumnName, true); + } + else if (IsBoolFalse(dataRow, item)) + { + cmd.Parameters.AddWithValue("@" + item.ColumnName, false); + } + else + { + cmd.Parameters.AddWithValue("@" + item.ColumnName, dataRow[item.ColumnName]); + } + } + i += await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); + cmd.Parameters.Clear(); + } + } + } + return i; + } + + private static bool IsBoolFalse(DataRow dataRow, DataColumn item) + { + return dataRow[item.ColumnName] != null && dataRow[item.ColumnName] is string && dataRow[item.ColumnName].ToString() == ("isSqliteCore_False"); + } + + private static bool IsBoolTrue(DataRow dataRow, DataColumn item) + { + return dataRow[item.ColumnName] != null && dataRow[item.ColumnName] is string && dataRow[item.ColumnName].ToString() == ("isSqliteCore_True"); + } + + private static void Open(SqliteConnection cn) + { + if (cn.State != ConnectionState.Open) + cn.Open(); + } + + public async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var dt = UpdateDataTable; + if (dt.Rows.Count == 0) + { + return 0; + } + var dictionary = this.Context.Utilities.DataTableToDictionaryList(dt.Rows.Cast().Take(1).CopyToDataTable()); + int result = 0; + var cn = this.Context.Ado.Connection as SqliteConnection; + Open(cn); + if (this.Context.Ado.Transaction == null) + { + using (var transaction = cn.BeginTransaction()) + { + result = await _BulkUpdate(dt, dictionary, result, whereColumns, updateColumns, cn).ConfigureAwait(false); + transaction.Commit(); + } + } + else + { + result = await _BulkUpdate(dt, dictionary, result, whereColumns, updateColumns, cn).ConfigureAwait(false); + } + return result; + } + + public async Task Merge(string tableName, DataTable dt, EntityInfo entityInfo, string[] whereColumns, string[] updateColumns, List datas) where T : class, new() + { + var result = 0; + await Context.Utilities.PageEachAsync(datas, 2000, async pageItems => + { + var x = await Context.Storageable(pageItems).As(tableName).WhereColumns(whereColumns).ToStorageAsync().ConfigureAwait(false); + result += await x.BulkCopyAsync().ConfigureAwait(false); + result += await x.BulkUpdateAsync(updateColumns).ConfigureAwait(false); + return result; + }).ConfigureAwait(false); + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteInsertBuilder.cs new file mode 100644 index 000000000..495819d60 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteInsertBuilder.cs @@ -0,0 +1,162 @@ +using System.Text; + +namespace SqlSugar +{ + public class SqliteInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;SELECT LAST_INSERT_ROWID();"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + + public override string SqlTemplateBatch + { + get + { + return "INSERT INTO {0} ({1})"; + } + } + 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))); + ActionMinDate(); + return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + batchInsetrSql.Append("INSERT INTO " + GetTableNameString + " "); + batchInsetrSql.Append('('); + batchInsetrSql.Append(columnsString); + batchInsetrSql.Append(") VALUES"); + string insertColumns = ""; + int i = 0; + foreach (var item in groupList) + { + batchInsetrSql.Append('('); + insertColumns = string.Join(",", item.Select(it => base.GetDbColumn(it, FormatValue(i, it.DbColumnName, it.Value)))); + batchInsetrSql.Append(insertColumns); + if (groupList.Last() == item) + { + batchInsetrSql.Append(") "); + } + else + { + batchInsetrSql.Append("), "); + } + i++; + } + + batchInsetrSql.AppendLine(";SELECT LAST_INSERT_ROWID();"); + var result = batchInsetrSql.ToString(); + return result; + } + } + public object FormatValue(int i, string name, object value) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.DateType) + { + 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.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + return value.ToSqlValue(); + } + else + { + return Convert.ToInt64(value); + } + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return GetDateTimeOffsetString(value); + } + else if (type == UtilConstants.ByteArrayType) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + this.Parameters.Add(new SugarParameter(parameterName, value)); + return parameterName; + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + 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.fffffff") + "'"; + } + + 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/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteQueryBuilder.cs new file mode 100644 index 000000000..8174f1929 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteQueryBuilder.cs @@ -0,0 +1,105 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar +{ + public partial class SqliteQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 0,10 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {5},{6}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY DATETIME('now') "; + } + } + + #endregion + + #region Common Methods + public override bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS \`\w+\.\w+\`") || Regex.IsMatch(sql, @"AS \`\w+\.\w+\.\w+\`"); + } + public override string ToSqlString() + { + base.AppendFilter(); + string result = null; + string oldOrderBy = this.OrderByValue; + 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 (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 = oldOrderBy; + result = GetSqlQuerySql(result); + if (result.IndexOf("-- No table") > 0) + { + return "-- No table"; + } + return result; + } + + #endregion + + #region Get SQL Partial + public override string GetSelectValue + { + get + { + string reval = string.Empty; + if (this.SelectValue == null || this.SelectValue is string) + { + reval = GetSelectValueByString(); + } + else + { + reval = GetSelectValueByExpression(); + } + if (this.SelectType == ResolveExpressType.SelectMultiple) + { + this.SelectCacheKey = this.SelectCacheKey + string.Join("-", this.JoinQueryInfos.Select(it => it.TableName)); + } + if (IsDistinct) + { + reval = " DISTINCT " + reval; + } + if (this.SubToListParameters != null && this.SubToListParameters.Count != 0) + { + reval = SubToListMethod(reval); + } + return reval; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteUpdateBuilder.cs new file mode 100644 index 000000000..3f22ec02d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqlBuilder/SqliteUpdateBuilder.cs @@ -0,0 +1,126 @@ +using System.Text; + +namespace SqlSugar +{ + public class SqliteUpdateBuilder : UpdateBuilder + { + public override string ReSetValueBySqlExpListType { get; set; } = "sqlite"; + protected override string TomultipleSqlString(List> groupList) + { + StringBuilder sb = new StringBuilder(); + int i = 0; + sb.AppendLine(string.Join("\r\n", groupList.Select(t => + { + var updateTable = string.Format("UPDATE {0} SET", base.GetTableNameStringNoWith); + var setValues = string.Join(",", t.Where(s => !s.IsPrimarykey).Where(s => OldPrimaryKeys?.Contains(s.DbColumnName) != true).Select(m => GetOracleUpdateColums(i, m, false)).ToArray()); + var pkList = t.Where(s => s.IsPrimarykey).ToList(); + if (this.IsWhereColumns && this.PrimaryKeys?.Count > 0) + { + var whereColumns = pkList.Where(it => this.PrimaryKeys?.Any(p => p.EqualCase(it.PropertyName) || p.EqualCase(it.DbColumnName)) == true).ToList(); + if (whereColumns.Count != 0) + { + pkList = whereColumns; + } + } + 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 string GetOracleUpdateColums(int i, DbColumnInfo m, bool iswhere) + { + var result = string.Format("\"{0}\"={1}", m.DbColumnName.ToUpper(), base.GetDbColumn(m, FormatValue(i, m.DbColumnName, m.Value, iswhere))); + if (iswhere && m.Value == null) + { + result = result.Replace("=NULL", " is NULL "); + } + return result; + } + + 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.DateTimeOffsetType) + { + return GetDateTimeOffsetString(value); + } + 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 (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + 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.fffffff") + "'"; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqliteProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqliteProvider.cs new file mode 100644 index 000000000..c36e7a8ab --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Realization/Sqlite/SqliteProvider.cs @@ -0,0 +1,137 @@ +using Microsoft.Data.Sqlite; + +using System.Data; +using System.Data.Common; +namespace SqlSugar +{ + public partial class SqliteProvider : AdoProvider + { + public SqliteProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var SQLiteConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + if (SQLiteConnectionString?.Contains('=') == false) + { + Check.ExceptionEasy("ConnString format error . Correct format DataSource=...", "字符串格式错误,应该是DataSource=..."); + } + base._DbConnection = new SqliteConnection(SQLiteConnectionString); + } + catch (Exception ex) + { + if (ex.InnerException != null) + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message + "\r\n" + ex.InnerException.Message); + } + else + { + Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message); + } + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public override void BeginTran(string transactionName) + { + base.BeginTran(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + base.BeginTran(iso); + } + public override IDataAdapter GetAdapter() + { + return new SqliteDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + SqliteCommand sqlCommand = new SqliteCommand(sql, (SqliteConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (SqliteTransaction)this.Transaction; + } + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((SqliteParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((SqliteDataAdapter)dataAdapter).SelectCommand = (SqliteCommand)command; + } + /// + /// if SQLite return SQLiteParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + SqliteParameter[] result = new SqliteParameter[parameters.Length]; + int index = 0; + var isVarchar = this.Context.IsVarchar(); + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + if (parameter.Value.GetType() == UtilConstants.GuidType) + { + parameter.Value = parameter.Value.ToString(); + } + var sqlParameter = new SqliteParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + if (sqlParameter.DbType == System.Data.DbType.Guid) + { + sqlParameter.DbType = System.Data.DbType.String; + if (sqlParameter.Value != DBNull.Value) + { + sqlParameter.Value = sqlParameter.Value.ObjToString(); + } + } + if (isVarchar && sqlParameter.DbType == System.Data.DbType.String) + { + sqlParameter.DbType = System.Data.DbType.AnsiString; + } + else if (parameter.DbType == System.Data.DbType.DateTimeOffset) + { + if (sqlParameter.Value != DBNull.Value) + sqlParameter.Value = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)sqlParameter.Value); + sqlParameter.DbType = System.Data.DbType.DateTime; + } + ++index; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SimpleClient.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SimpleClient.cs new file mode 100644 index 000000000..48095cd1e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SimpleClient.cs @@ -0,0 +1,758 @@ +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + + public partial class SimpleClient : ISugarRepository, ISimpleClient where T : class, new() + { + #region Interface + public virtual ISqlSugarClient Context { get; set; } + + public virtual ITenant AsTenant() + { + var result = this.Context as ITenant; + if (result == null && this.Context is SqlSugarProvider) + { + result = (this.Context as SqlSugarProvider).Root as ITenant; + } + else if (result == null && this.Context is SqlSugarScopeProvider) + { + result = (this.Context as SqlSugarScopeProvider).conn.Root as ITenant; + } + return result; + } + public virtual ISqlSugarClient AsSugarClient() + { + return this.Context; + } + + public SimpleClient() + { + + } + public SimpleClient(ISqlSugarClient context) + { + this.Context = context; + } + public SimpleClient Change() where ChangeType : class, new() + { + return this.Context.GetSimpleClient(); + } + public SimpleClient CopyNew() + { + SimpleClient sm = new SimpleClient(); + sm.Context = this.Context.CopyNew(); + return sm; + } + public virtual RepositoryType CopyNew() where RepositoryType : ISugarRepository + { + Type type = typeof(RepositoryType); + var isAnyParamter = type.GetConstructors().Any(z => z.GetParameters().Length != 0); + object o = null; + if (isAnyParamter) + { + object[] pars = type.GetConstructors().First().GetParameters() + .Select(it => (object)null).ToArray(); + o = Activator.CreateInstance(type, pars); + } + else + { + o = Activator.CreateInstance(type); + } + var result = (RepositoryType)o; + if (result.Context != null) + { + result.Context = result.Context.CopyNew(); + } + else + { + result.Context = this.Context.CopyNew(); + } + return result; + } + public virtual RepositoryType CopyNew(IServiceProvider serviceProvider) where RepositoryType : ISugarRepository + { + var instance = handleDependencies(typeof(RepositoryType), serviceProvider, true); + return (RepositoryType)instance; + } + + private object handleDependencies(Type type, IServiceProvider serviceProvider, bool needNewCopy = false) + { + ConstructorInfo constructorInfo = null; + var newInstanceType = type; + if (type.IsInterface && IsAssignableToBaseRepository(type)) + { + var dependencyInstanceType = serviceProvider.GetService(type)?.GetType(); + newInstanceType = dependencyInstanceType; + constructorInfo = dependencyInstanceType.GetConstructors().FirstOrDefault(); + } + else + { + constructorInfo = type.GetConstructors().FirstOrDefault(); + } + var parameters = constructorInfo?.GetParameters(); + if (parameters == null || parameters.Length == 0) + { + object dependencyInstance = serviceProvider.GetService(type); + if (dependencyInstance is ISugarRepository sugarRepository) + { + return setContext(sugarRepository, needNewCopy); + } + else + { + return dependencyInstance; + } + } + + var conParas = new List(); + foreach (var parameter in parameters) + { + Type dependencyType = parameter.ParameterType; + conParas.Add(handleDependencies(dependencyType, serviceProvider)); + } + + object instance = null; + if (conParas?.Count > 0) + { + instance = Activator.CreateInstance(newInstanceType, conParas.ToArray()); + } + else + { + instance = Activator.CreateInstance(newInstanceType); + } + return instance; + } + private ISugarRepository setContext(ISugarRepository sugarRepository, bool needNewCopy) + { + if (sugarRepository.Context != null) + { + if (needNewCopy) + { + sugarRepository.Context = sugarRepository.Context.CopyNew(); + } + } + else + { + if (needNewCopy) + { + sugarRepository.Context = this.Context.CopyNew(); + } + else + { + sugarRepository.Context = this.Context; + } + } + return sugarRepository; + } + private bool IsAssignableToBaseRepository(Type type) + { + var baseInterfaces = type.GetInterfaces(); + foreach (Type interfaceType in baseInterfaces) + { + if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(ISimpleClient<>)) + { + Type genericArgument = interfaceType.GetGenericArguments()[0]; + Type baseRepositoryGenericType = typeof(ISimpleClient<>).MakeGenericType(genericArgument); + + if (baseRepositoryGenericType.IsAssignableFrom(type)) + { + return true; + } + } + } + return false; + } + public virtual RepositoryType ChangeRepository() where RepositoryType : ISugarRepository + { + Type type = typeof(RepositoryType); + var isAnyParamter = type.GetConstructors().Any(z => z.GetParameters().Length != 0); + object o = null; + if (isAnyParamter) + { + o = Activator.CreateInstance(type, new string[] { null }); + } + else + { + o = Activator.CreateInstance(type); + } + var result = (RepositoryType)o; + if (result.Context == null) + { + result.Context = this.Context; + } + return result; + } + public virtual RepositoryType ChangeRepository(IServiceProvider serviceProvider) where RepositoryType : ISugarRepository + { + var instance = handleDependencies(typeof(RepositoryType), serviceProvider, false); + return (RepositoryType)instance; + } + public virtual ISugarQueryable AsQueryable() + { + return Context.Queryable(); + } + public virtual IInsertable AsInsertable(T insertObj) + { + return Context.Insertable(insertObj); + } + public virtual IInsertable AsInsertable(T[] insertObjs) + { + return Context.Insertable(insertObjs); + } + public virtual IInsertable AsInsertable(List insertObjs) + { + return Context.Insertable(insertObjs); + } + public virtual IUpdateable AsUpdateable(T updateObj) + { + return Context.Updateable(updateObj); + } + public virtual IUpdateable AsUpdateable(T[] updateObjs) + { + return Context.Updateable(updateObjs); + } + public virtual IUpdateable AsUpdateable(List updateObjs) + { + return Context.Updateable(updateObjs); + } + public virtual IUpdateable AsUpdateable() + { + return Context.Updateable(); + } + public virtual IDeleteable AsDeleteable() + { + return Context.Deleteable(); + } + #endregion + + #region Method + public virtual T GetById(dynamic id) + { + return Context.Queryable().InSingle(id); + } + public virtual List GetList() + { + return Context.Queryable().ToList(); + } + + public virtual List GetList(Expression> whereExpression) + { + return Context.Queryable().Where(whereExpression).ToList(); + } + public virtual T GetSingle(Expression> whereExpression) + { + return Context.Queryable().Single(whereExpression); + } + public virtual T GetFirst(Expression> whereExpression) + { + return Context.Queryable().First(whereExpression); + } + public virtual List GetPageList(Expression> whereExpression, PageModel page) + { + int count = 0; + var result = Context.Queryable().Where(whereExpression).ToPageList(page.PageIndex, page.PageSize, ref count); + page.TotalCount = count; + return result; + } + public virtual List GetPageList(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + int count = 0; + var result = Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToPageList(page.PageIndex, page.PageSize, ref count); + page.TotalCount = count; + return result; + } + public virtual List GetPageList(List conditionalList, PageModel page) + { + int count = 0; + var result = Context.Queryable().Where(conditionalList).ToPageList(page.PageIndex, page.PageSize, ref count); + page.TotalCount = count; + return result; + } + public virtual List GetPageList(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + int count = 0; + var result = Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).ToPageList(page.PageIndex, page.PageSize, ref count); + page.TotalCount = count; + return result; + } + public virtual bool IsAny(Expression> whereExpression) + { + return Context.Queryable().Where(whereExpression).Any(); + } + public virtual int Count(Expression> whereExpression) + { + + return Context.Queryable().Where(whereExpression).Count(); + } + + public virtual bool Insert(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteCommand() > 0; + } + + public virtual bool InsertOrUpdate(T data) + { + return this.Context.Storageable(data).ExecuteCommand() > 0; + } + public virtual bool InsertOrUpdate(List datas) + { + return this.Context.Storageable(datas).ExecuteCommand() > 0; + } + + public virtual int InsertReturnIdentity(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnIdentity(); + } + public virtual long InsertReturnBigIdentity(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnBigIdentity(); + } + public virtual long InsertReturnSnowflakeId(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnSnowflakeId(); + } + public virtual List InsertReturnSnowflakeId(List insertObjs) + { + return this.Context.Insertable(insertObjs).ExecuteReturnSnowflakeIdList(); + } + public virtual Task InsertReturnSnowflakeIdAsync(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnSnowflakeIdAsync(); + } + public virtual Task> InsertReturnSnowflakeIdAsync(List insertObjs) + { + return this.Context.Insertable(insertObjs).ExecuteReturnSnowflakeIdListAsync(); + } + + public virtual T InsertReturnEntity(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnEntity(); + } + + public virtual bool InsertRange(T[] insertObjs) + { + return this.Context.Insertable(insertObjs).ExecuteCommand() > 0; + } + public virtual bool InsertRange(List insertObjs) + { + return this.Context.Insertable(insertObjs).ExecuteCommand() > 0; + } + public virtual bool Update(T updateObj) + { + return this.Context.Updateable(updateObj).ExecuteCommand() > 0; + } + public virtual bool UpdateRange(T[] updateObjs) + { + return this.Context.Updateable(updateObjs).ExecuteCommand() > 0; + } + public virtual bool UpdateRange(List updateObjs) + { + return this.Context.Updateable(updateObjs).ExecuteCommand() > 0; + } + public virtual bool Update(Expression> columns, Expression> whereExpression) + { + return this.Context.Updateable().SetColumns(columns).Where(whereExpression).ExecuteCommand() > 0; + } + public virtual bool UpdateSetColumnsTrue(Expression> columns, Expression> whereExpression) + { + return this.Context.Updateable().SetColumns(columns, true).Where(whereExpression).ExecuteCommand() > 0; + } + public virtual bool Delete(T deleteObj) + { + return this.Context.Deleteable().Where(deleteObj).ExecuteCommand() > 0; + } + public virtual bool Delete(List deleteObjs) + { + return this.Context.Deleteable().Where(deleteObjs).ExecuteCommand() > 0; + } + public virtual bool Delete(Expression> whereExpression) + { + return this.Context.Deleteable().Where(whereExpression).ExecuteCommand() > 0; + } + public virtual bool DeleteById(dynamic id) + { + return this.Context.Deleteable().In(id).ExecuteCommand() > 0; + } + public virtual bool DeleteByIds(dynamic[] ids) + { + return this.Context.Deleteable().In(ids).ExecuteCommand() > 0; + } + #endregion + + #region Async Method + public virtual Task GetByIdAsync(dynamic id) + { + return Context.Queryable().InSingleAsync(id); + } + public virtual Task> GetListAsync() + { + return Context.Queryable().ToListAsync(); + } + + public virtual Task> GetListAsync(Expression> whereExpression) + { + return Context.Queryable().Where(whereExpression).ToListAsync(); + } + public virtual Task GetSingleAsync(Expression> whereExpression) + { + return Context.Queryable().SingleAsync(whereExpression); + } + public virtual Task GetFirstAsync(Expression> whereExpression) + { + return Context.Queryable().FirstAsync(whereExpression); + } + public virtual async Task> GetPageListAsync(Expression> whereExpression, PageModel page) + { + RefAsync count = 0; + var result = await Context.Queryable().Where(whereExpression).ToPageListAsync(page.PageIndex, page.PageSize, count).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual async Task> GetPageListAsync(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + RefAsync count = 0; + var result = await Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToPageListAsync(page.PageIndex, page.PageSize, count).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual async Task> GetPageListAsync(List conditionalList, PageModel page) + { + RefAsync count = 0; + var result = await Context.Queryable().Where(conditionalList).ToPageListAsync(page.PageIndex, page.PageSize, count).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual async Task> GetPageListAsync(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + RefAsync count = 0; + var result = await Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).ToPageListAsync(page.PageIndex, page.PageSize, count).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual Task IsAnyAsync(Expression> whereExpression) + { + return Context.Queryable().Where(whereExpression).AnyAsync(); + } + public virtual Task CountAsync(Expression> whereExpression) + { + + return Context.Queryable().Where(whereExpression).CountAsync(); + } + + public virtual async Task InsertOrUpdateAsync(T data) + { + return await Context.Storageable(data).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task InsertOrUpdateAsync(List datas) + { + return await Context.Storageable(datas).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task InsertAsync(T insertObj) + { + return await Context.Insertable(insertObj).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual Task InsertReturnIdentityAsync(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnIdentityAsync(); + } + public virtual Task InsertReturnBigIdentityAsync(T insertObj) + { + return this.Context.Insertable(insertObj).ExecuteReturnBigIdentityAsync(); + } + public virtual async Task InsertReturnEntityAsync(T insertObj) + { + return await Context.Insertable(insertObj).ExecuteReturnEntityAsync().ConfigureAwait(false); + } + public virtual async Task InsertRangeAsync(T[] insertObjs) + { + return await Context.Insertable(insertObjs).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task InsertRangeAsync(List insertObjs) + { + return await Context.Insertable(insertObjs).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task UpdateAsync(T updateObj) + { + return await Context.Updateable(updateObj).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task UpdateRangeAsync(T[] updateObjs) + { + return await Context.Updateable(updateObjs).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task UpdateRangeAsync(List updateObjs) + { + return await Context.Updateable(updateObjs).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task UpdateAsync(Expression> columns, Expression> whereExpression) + { + return await Context.Updateable().SetColumns(columns).Where(whereExpression).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task UpdateSetColumnsTrueAsync(Expression> columns, Expression> whereExpression) + { + return await Context.Updateable().SetColumns(columns, true).Where(whereExpression).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task DeleteAsync(T deleteObj) + { + return await Context.Deleteable().Where(deleteObj).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task DeleteAsync(List deleteObjs) + { + return await Context.Deleteable().Where(deleteObjs).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task DeleteAsync(Expression> whereExpression) + { + return await Context.Deleteable().Where(whereExpression).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + public virtual async Task DeleteByIdAsync(dynamic id) + { + return await this.Context.Deleteable().In(id).ExecuteCommandAsync() > 0; + } + public virtual async Task DeleteByIdsAsync(dynamic[] ids) + { + return await Context.Deleteable().In(ids).ExecuteCommandAsync().ConfigureAwait(false) > 0; + } + #endregion + + #region Async Method CancellationToken + public virtual Task InsertReturnSnowflakeIdAsync(T insertObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return this.Context.Insertable(insertObj).ExecuteReturnSnowflakeIdAsync(cancellationToken); + } + public virtual Task> InsertReturnSnowflakeIdAsync(List insertObjs, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return this.Context.Insertable(insertObjs).ExecuteReturnSnowflakeIdListAsync(cancellationToken); + } + + public virtual Task GetByIdAsync(dynamic id, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().InSingleAsync(id); + } + public virtual Task> GetListAsync(CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().ToListAsync(cancellationToken); + } + + public virtual Task> GetListAsync(Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().Where(whereExpression).ToListAsync(cancellationToken); + } + public virtual Task GetSingleAsync(Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().SingleAsync(whereExpression); + } + public virtual Task GetFirstAsync(Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().FirstAsync(whereExpression, cancellationToken); + } + public virtual async Task> GetPageListAsync(Expression> whereExpression, PageModel page, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + RefAsync count = 0; + var result = await Context.Queryable().Where(whereExpression).ToPageListAsync(page.PageIndex, page.PageSize, count, cancellationToken).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual async Task> GetPageListAsync(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc, CancellationToken cancellationToken = default) + { + this.Context.Ado.CancellationToken = cancellationToken; + RefAsync count = 0; + var result = await Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToPageListAsync(page.PageIndex, page.PageSize, count, cancellationToken).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual async Task> GetPageListAsync(List conditionalList, PageModel page, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + RefAsync count = 0; + var result = await Context.Queryable().Where(conditionalList).ToPageListAsync(page.PageIndex, page.PageSize, count, cancellationToken).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual async Task> GetPageListAsync(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc, CancellationToken cancellationToken = default) + { + this.Context.Ado.CancellationToken = cancellationToken; + RefAsync count = 0; + var result = await Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).ToPageListAsync(page.PageIndex, page.PageSize, count, cancellationToken).ConfigureAwait(false); + page.TotalCount = count; + return result; + } + public virtual Task IsAnyAsync(Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().Where(whereExpression).AnyAsync(); + } + public virtual Task CountAsync(Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return Context.Queryable().Where(whereExpression).CountAsync(cancellationToken); + } + + public virtual async Task InsertOrUpdateAsync(T data, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Storageable(data).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task InsertOrUpdateAsync(List datas, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Storageable(datas).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task InsertAsync(T insertObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Insertable(insertObj).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual Task InsertReturnIdentityAsync(T insertObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return this.Context.Insertable(insertObj).ExecuteReturnIdentityAsync(cancellationToken); + } + public virtual Task InsertReturnBigIdentityAsync(T insertObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return this.Context.Insertable(insertObj).ExecuteReturnBigIdentityAsync(cancellationToken); + } + public virtual async Task InsertReturnEntityAsync(T insertObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Insertable(insertObj).ExecuteReturnEntityAsync().ConfigureAwait(false); + } + public virtual async Task InsertRangeAsync(T[] insertObjs, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Insertable(insertObjs).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task InsertRangeAsync(List insertObjs, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Insertable(insertObjs).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task UpdateAsync(T updateObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Updateable(updateObj).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task UpdateRangeAsync(T[] updateObjs, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Updateable(updateObjs).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task UpdateRangeAsync(List updateObjs, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Updateable(updateObjs).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task UpdateAsync(Expression> columns, Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Updateable().SetColumns(columns).Where(whereExpression).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task UpdateSetColumnsTrueAsync(Expression> columns, Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Updateable().SetColumns(columns, true).Where(whereExpression).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task DeleteAsync(T deleteObj, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Deleteable().Where(deleteObj).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task DeleteAsync(List deleteObjs, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Deleteable().Where(deleteObjs).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task DeleteAsync(Expression> whereExpression, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Deleteable().Where(whereExpression).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + public virtual async Task DeleteByIdAsync(dynamic id, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await this.Context.Deleteable().In(id).ExecuteCommandAsync() > 0; + } + public virtual async Task DeleteByIdsAsync(dynamic[] ids, CancellationToken cancellationToken) + { + this.Context.Ado.CancellationToken = cancellationToken; + return await Context.Deleteable().In(ids).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false) > 0; + } + + public int Count(List conditionalModels) + { + return Context.Queryable().Where(conditionalModels).Count(); + } + + public bool Delete(List conditionalModels) + { + return Context.Deleteable().Where(conditionalModels).ExecuteCommandHasChange(); + } + + public List GetList(Expression> whereExpression, List orderByModels) + { + return Context.Queryable().Where(whereExpression).OrderBy(orderByModels).ToList(); + } + + public List GetList(List conditionalList) + { + return Context.Queryable().Where(conditionalList).ToList(); + } + + public List GetList(List conditionalList, List orderByModels) + { + return Context.Queryable().Where(conditionalList).OrderBy(orderByModels).ToList(); + } + + public List GetPageList(Expression> whereExpression, PageModel page, List orderByModels) + { + var total = 0; + var list = Context.Queryable().Where(whereExpression).OrderBy(orderByModels).ToPageList(page.PageIndex, page.PageSize, ref total); + page.TotalCount = total; + return list; + } + + public List GetPageList(List conditionalList, PageModel page, List orderByModels) + { + var total = 0; + var list = Context.Queryable().Where(conditionalList).OrderBy(orderByModels).ToPageList(page.PageIndex, page.PageSize, ref total); + page.TotalCount = total; + return list; + } + + public T GetSingle(List conditionalModels) + { + return Context.Queryable().Where(conditionalModels).Single(); + } + + public T GetFirst(List conditionalModels) + { + return Context.Queryable().Where(conditionalModels).First(); + } + + public bool IsAny(List conditionalModels) + { + return Context.Queryable().Where(conditionalModels).Any(); + } + + public T GetFirst(Expression> whereExpression, List orderByModels) + { + return Context.Queryable().Where(whereExpression).OrderBy(orderByModels).First(); + } + + public T GetFirst(List conditionalModels, List orderByModels) + { + return Context.Queryable().Where(conditionalModels).OrderBy(orderByModels).First(); + } + + #endregion + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableAttribute.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableAttribute.cs new file mode 100644 index 000000000..aee95d6f3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableAttribute.cs @@ -0,0 +1,42 @@ +namespace SqlSugar +{ + [AttributeUsage(AttributeTargets.Class, Inherited = true)] + public class SplitTableAttribute : Attribute + { + public SplitType SplitType { get; set; } + public Type CustomSplitTableService { get; set; } + public SplitTableAttribute(SplitType splitType) + { + this.SplitType = splitType; + } + public SplitTableAttribute(SplitType splitType, Type customSplitTableService) + { + this.SplitType = splitType; + if (!customSplitTableService.GetInterfaces().Any(it => it == typeof(ISplitTableService))) + { + Check.ExceptionEasy("customSplitTableService in SplitTableAttribute(SplitType splitType,Type customSplitTableService) must be inherited ISplitTableService", " SplitTableAttribute(SplitType splitType,Type customSplitTableService) 中的 customSplitTableService 必须继承 ISplitTableService"); + } + this.CustomSplitTableService = customSplitTableService; + } + } + + [AttributeUsage(AttributeTargets.Property, Inherited = true)] + public class SplitFieldAttribute : Attribute + { + + public SplitFieldAttribute() + { + + } + } + + [AttributeUsage(AttributeTargets.Property, Inherited = true)] + public class TimeDbSplitFieldAttribute : Attribute + { + public DateType? DateType { get; set; } + public TimeDbSplitFieldAttribute(DateType type) + { + DateType = type; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableContext.cs new file mode 100644 index 000000000..d12303c52 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableContext.cs @@ -0,0 +1,108 @@ +using System.Reflection; + +namespace SqlSugar +{ + public class SplitTableContextResult + { + public List Items { get; set; } + public SplitTableContext Helper { get; set; } + + public string GetTableName() + { + return GetTableNames().First(); + } + public string[] GetTableNames() + { + List result = new List(); + var attribute = typeof(T).GetCustomAttribute() as SplitTableAttribute; + Check.Exception(attribute == null, $" {typeof(T).Name} need SplitTableAttribute"); + foreach (var item in Items) + { + result.Add(Helper.GetTableName(Helper.GetValue(attribute.SplitType, item))); + } + return result.Distinct().ToArray(); + } + public string[] GetTableNames(SplitType splitType) + { + List result = new List(); + foreach (var item in Items) + { + result.Add(Helper.GetTableName(Helper.GetValue(splitType, item))); + } + return result.ToArray(); + } + } + public class SplitTableContext + { + internal SqlSugarProvider Context { get; set; } + internal EntityInfo EntityInfo { get; set; } + internal ISplitTableService Service { get; set; } + private SplitTableContext() { } + internal SplitTableContext(SqlSugarProvider context) + { + this.Context = context; + if (this.Context.CurrentConnectionConfig.ConfigureExternalServices?.SplitTableService != null) + { + Service = this.Context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService; + } + else + { + Service = new DateSplitTableService(); + } + } + public List GetTables() + { + if (StaticConfig.SplitTableGetTablesFunc != null) + { + return GetCustomGetTables(); + } + var oldIsEnableLogEvent = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + List tableInfos = ((DbMaintenanceProvider)this.Context.DbMaintenance).GetSchemaTables(EntityInfo); + if (tableInfos == null) + { + tableInfos = this.Context.DbMaintenance.GetTableInfoList(false); + } + List result = Service.GetAllTables(this.Context, EntityInfo, tableInfos); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLogEvent; + return result; + } + + private List GetCustomGetTables() + { + var oldIsEnableLogEvent = this.Context.Ado.IsEnableLogEvent; + this.Context.Ado.IsEnableLogEvent = false; + var tables = StaticConfig.SplitTableGetTablesFunc(); + List result = Service.GetAllTables(this.Context, EntityInfo, tables.Select(it => new DbTableInfo() { Name = it.TableName }).ToList()); + this.Context.Ado.IsEnableLogEvent = oldIsEnableLogEvent; + return result.ToList(); + } + + public string GetDefaultTableName() + { + return Service.GetTableName(this.Context, EntityInfo); + } + public string GetTableName(SplitType splitType) + { + return Service.GetTableName(this.Context, EntityInfo, splitType); + } + public string GetTableName(SplitType splitType, object fieldValue) + { + return Service.GetTableName(this.Context, EntityInfo, splitType, fieldValue); + } + public string GetTableName(object fieldValue) + { + var attribute = EntityInfo.Type.GetCustomAttribute() as SplitTableAttribute; + Check.Exception(attribute == null, $" {EntityInfo.EntityName} need SplitTableAttribute"); + return Service.GetTableName(this.Context, EntityInfo, attribute.SplitType, fieldValue); + } + public object GetValue(SplitType splitType, object entityValue) + { + return Service.GetFieldValue(this.Context, EntityInfo, splitType, entityValue); + } + internal void CheckPrimaryKey() + { + Check.Exception(EntityInfo.Columns.Any(it => it.IsIdentity == true), ErrorMessage.GetThrowMessage("Split table can't IsIdentity=true", "分表禁止使用自增列")); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableExtensions.cs new file mode 100644 index 000000000..e9ff055f5 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableExtensions.cs @@ -0,0 +1,14 @@ +namespace SqlSugar.SplitTableExtensions +{ + public static class Extensions + { + public static List SplitTable(this List thisValue, Func, IEnumerable> getTableNamesFunc) + { + return thisValue; + } + public static List SplitTable(this T thisValue, Func, IEnumerable> getTableNamesFunc) + { + return new List(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableInfo.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableInfo.cs new file mode 100644 index 000000000..ab1d47ef9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTableInfo.cs @@ -0,0 +1,13 @@ +namespace SqlSugar +{ + public class SplitTableInfo + { + public string TableName { get; set; } + public DateTime Date { get; set; } + public String String { get; set; } + public decimal Decimal { get; set; } + public long Long { get; set; } + public int Int { get; set; } + public Byte[] ByteArray { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitType.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitType.cs new file mode 100644 index 000000000..1259880b4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitType.cs @@ -0,0 +1,18 @@ +namespace SqlSugar +{ + public enum SplitType + { + Day = 0, + Week = 1, + Month = 2, + Month_6 = 1000, + Season = 3, + Year = 4, + _Custom01 = 5, + _Custom02 = 6, + _Custom03 = 7, + _Custom04 = 8, + _Custom05 = 9, + _Custom06 = 10, + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTypeExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTypeExtensions.cs new file mode 100644 index 000000000..da6f758af --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SpliteTable/SplitTypeExtensions.cs @@ -0,0 +1,38 @@ +namespace SqlSugar +{ + public static class SplitTableInfoExtensions + { + public static IEnumerable InTableNames(this List tables, params string[] tableNames) + { + return tables.Where(it => tableNames.Any(y => y.Equals(it.TableName, StringComparison.OrdinalIgnoreCase))); + } + public static IEnumerable ContainsTableNames(this List tables, params string[] tableNames) + { + List result = new List(); + foreach (var item in tables) + { + if (tableNames.Any(it => item.TableName.ObjToString().Contains(it.ObjToString(), StringComparison.CurrentCultureIgnoreCase))) + { + result.Add(item); + } + } + return result; + } + public static IEnumerable ContainsTableNamesIfNullDefaultFirst(this List tables, params string[] tableNames) + { + List result = new List(); + foreach (var item in tables) + { + if (tableNames.Any(it => item.TableName.ObjToString().Contains(it.ObjToString(), StringComparison.CurrentCultureIgnoreCase))) + { + result.Add(item); + } + } + if (result.Count == 0 && tables.Count != 0) + { + result.Add(tables.First()); + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SqlSugarClient.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SqlSugarClient.cs new file mode 100644 index 000000000..7e6f90904 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SqlSugarClient.cs @@ -0,0 +1,1620 @@ +using System.Data; +using System.Dynamic; +using System.Linq.Expressions; +using System.Reflection; + +namespace SqlSugar +{ + public partial class SqlSugarClient : ISqlSugarClient, ITenant + { + #region Gobal Property + private SqlSugarProvider _Context = null; + private string _ThreadId; + private ConnectionConfig _CurrentConnectionConfig; + internal List _AllClients; + private bool _IsAllTran = false; + private bool _IsOpen = false; + private MappingTableList _MappingTables; + private MappingColumnList _MappingColumns; + private IgnoreColumnList _IgnoreColumns; + private IgnoreColumnList _IgnoreInsertColumns; + private Action _configAction; + + internal Guid? AsyncId { get; set; } + internal bool? IsSingleInstance { get; set; } + + #endregion + + #region Constructor + public SqlSugarClient(ConnectionConfig config) + { + Check.Exception(config == null, "ConnectionConfig config is null"); + InitContext(config); + } + + public SqlSugarClient(List configs) + { + Check.Exception(configs.IsNullOrEmpty(), "List configs is null or count=0"); + InitConfigs(configs); + var config = configs.First(); + InitContext(config); + _AllClients = configs.Select(it => new SugarTenant() { ConnectionConfig = it }).ToList(); ; + _AllClients.First(it => it.ConnectionConfig.ConfigId == config.ConfigId).Context = this.Context; + } + public SqlSugarClient(ConnectionConfig config, Action configAction) + { + _configAction = configAction; + Check.Exception(config == null, "ConnectionConfig config is null"); + InitContext(config); + configAction(this); + } + + public SqlSugarClient(List configs, Action configAction) + { + _configAction = configAction; + Check.Exception(configs.IsNullOrEmpty(), "List configs is null or count=0"); + InitConfigs(configs); + var config = configs.First(); + InitContext(config); + _AllClients = configs.Select(it => new SugarTenant() { ConnectionConfig = it }).ToList(); ; + _AllClients.First(it => it.ConnectionConfig.ConfigId == config.ConfigId).Context = this.Context; + configAction(this); + } + #endregion + + #region Global variable + public SugarActionType SugarActionType { get { return this.Context.SugarActionType; } set { this.Context.SugarActionType = value; } } + public SqlSugarProvider Context { get { return GetContext(); } } + public ConnectionConfig CurrentConnectionConfig { get { return _CurrentConnectionConfig; } set { _CurrentConnectionConfig = value; } } + public Guid ContextID { get { return this.Context.ContextID; } set { this.Context.ContextID = value; } } + public ConfigQuery ConfigQuery { get { return this.Context.ConfigQuery; } set { this.Context.ConfigQuery = value; } } + + public MappingTableList MappingTables { get { return _MappingTables; } set { _MappingTables = value; } } + public MappingColumnList MappingColumns { get { return _MappingColumns; } set { _MappingColumns = value; } } + public IgnoreColumnList IgnoreColumns { get { return _IgnoreColumns; } set { _IgnoreColumns = value; } } + public IgnoreColumnList IgnoreInsertColumns { get { return _IgnoreInsertColumns; } set { _IgnoreInsertColumns = value; } } + public Dictionary TempItems { get { return this.Context.TempItems; } set { this.Context.TempItems = value; } } + #endregion + + #region SimpleClient + + public T CreateContext(bool isTran = true) where T : SugarUnitOfWork, new() + { + T result = new T(); + _CreateContext(isTran, result); + var type = typeof(T); + var ps = type.GetProperties(); + var cacheKey = "SugarUnitOfWork" + typeof(T).FullName + typeof(T).GetHashCode(); + var properies = new ReflectionInoCacheService().GetOrCreate(cacheKey, + () => + ps.Where(it => + + (it.PropertyType.BaseType?.Name.StartsWith("SimpleClient`") == true) + || + it.PropertyType.Name.StartsWith("SimpleClient`") + + )); + foreach (var item in properies) + { + var value = Activator.CreateInstance(item.PropertyType); + TenantAttribute tenantAttribute = item.PropertyType.GetGenericArguments()[0].GetCustomAttribute(); + if (tenantAttribute == null) + { + value.GetType().GetProperty("Context").SetValue(value, this); + } + else + { + value.GetType().GetProperty("Context").SetValue(value, this.GetConnection(tenantAttribute.configId)); + } + item.SetValue(result, value); + } + return result; + } + public SugarUnitOfWork CreateContext(bool isTran = true) + { + SugarUnitOfWork sugarUnitOf = new SugarUnitOfWork(); + return _CreateContext(isTran, sugarUnitOf); + } + + private SugarUnitOfWork _CreateContext(bool isTran, SugarUnitOfWork sugarUnitOf) + { + sugarUnitOf.Db = this; + sugarUnitOf.Tenant = this; + sugarUnitOf.IsTran = isTran; + this.Open(); + if (isTran) + this.BeginTran(); + return sugarUnitOf; + } + public SimpleClient GetSimpleClient() where T : class, new() + { + return this.Context.GetSimpleClient(); + } + public RepositoryType GetRepository() where RepositoryType : ISugarRepository, new() + { + Type type = typeof(RepositoryType); + var isAnyParamter = type.GetConstructors().Any(z => z.GetParameters().Length != 0); + object o = null; + if (isAnyParamter) + { + o = Activator.CreateInstance(type, new string[] { null }); + } + else + { + o = Activator.CreateInstance(type); + } + var result = (RepositoryType)o; + if (result.Context == null) + { + result.Context = this.Context; + } + return result; + } + #endregion + + #region Insertable + public IInsertable> InsertableByDynamic(object insertDynamicObject) + { + return this.Context.InsertableByDynamic(insertDynamicObject); + } + public InsertMethodInfo InsertableByObject(object singleEntityObjectOrListObject) + { + return this.Context.InsertableByObject(singleEntityObjectOrListObject); + } + public IInsertable Insertable(Dictionary columnDictionary) where T : class, new() + { + return this.Context.Insertable(columnDictionary); + } + + public IInsertable Insertable(dynamic insertDynamicObject) where T : class, new() + { + if (insertDynamicObject is IList) + { + return this.Context.Insertable((insertDynamicObject as IList).ToList()); + } + return this.Context.Insertable(insertDynamicObject); + } + + public IInsertable Insertable(List insertObjs) where T : class, new() + { + return this.Context.Insertable(insertObjs); + } + + public IInsertable Insertable(T insertObj) where T : class, new() + { + Check.ExceptionEasy(typeof(T).FullName.Contains("System.Collections.Generic.List`"), " need where T: class, new() ", "需要Class,new()约束,并且类属性中不能有required修饰符"); + if (typeof(T).Name == "Object") + { + Check.ExceptionEasy("Object type use db.InsertableByObject(obj).ExecuteCommand()", "检测到T为Object类型,请使用 db.InsertableByObject(obj).ExecuteCommand(),Insertable不支持object,InsertableByObject可以(缺点:功能比较少)"); + } + return this.Context.Insertable(insertObj); + } + + public IInsertable Insertable(T[] insertObjs) where T : class, new() + { + return this.Context.Insertable(insertObjs); + } + + #endregion + + #region Queryable + + #region Nav CUD + public InsertNavTaskInit InsertNav(T data) where T : class, new() + { + return this.Context.InsertNav(data); + } + public InsertNavTaskInit InsertNav(List datas) where T : class, new() + { + return this.Context.InsertNav(datas); + } + public InsertNavTaskInit InsertNav(T data, InsertNavRootOptions rootOptions) where T : class, new() + { + return this.Context.InsertNav(data, rootOptions); + } + public InsertNavTaskInit InsertNav(List datas, InsertNavRootOptions rootOptions) where T : class, new() + { + return this.Context.InsertNav(datas, rootOptions); + } + public DeleteNavTaskInit DeleteNav(T data) where T : class, new() + { + return this.Context.DeleteNav(data); + } + public DeleteNavTaskInit DeleteNav(List datas) where T : class, new() + { + return this.Context.DeleteNav(datas); + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression) where T : class, new() + { + return this.Context.DeleteNav(whereExpression); + } + + public DeleteNavTaskInit DeleteNav(T data, DeleteNavRootOptions options) where T : class, new() + { + return this.Context.DeleteNav(data, options); + } + public DeleteNavTaskInit DeleteNav(List datas, DeleteNavRootOptions options) where T : class, new() + { + return this.Context.DeleteNav(datas, options); + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression, DeleteNavRootOptions options) where T : class, new() + { + return this.Context.DeleteNav(whereExpression, options); + } + + public UpdateNavTaskInit UpdateNav(T data) where T : class, new() + { + return this.Context.UpdateNav(data); + } + public UpdateNavTaskInit UpdateNav(List datas, UpdateNavRootOptions rootOptions) where T : class, new() + { + return this.Context.UpdateNav(datas, rootOptions); + } + public UpdateNavTaskInit UpdateNav(T data, UpdateNavRootOptions rootOptions) where T : class, new() + { + return this.Context.UpdateNav(data, rootOptions); + } + public UpdateNavTaskInit UpdateNav(List datas) where T : class, new() + { + return this.Context.UpdateNav(datas); + } + #endregion + + #region Union + public ISugarQueryable Union(List> queryables) where T : class + { + return this.Context.Union(queryables); + } + + public ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class + { + return this.Context.Union(queryables); + } + + public ISugarQueryable UnionAll(List> queryables) where T : class + { + return this.Context.UnionAll(queryables); + } + + public ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class + { + return this.Context.UnionAll(queryables); + } + #endregion + + public QueryMethodInfo QueryableByObject(Type entityType) + { + return this.Context.QueryableByObject(entityType); + } + public QueryMethodInfo QueryableByObject(Type entityType, string shortName) + { + return this.Context.QueryableByObject(entityType, shortName); + } + public ISugarQueryable MasterQueryable() + { + return this.Context.MasterQueryable(); + } + public ISugarQueryable SlaveQueryable() + { + return this.Context.SlaveQueryable(); + } + public ISugarQueryable SqlQueryable(string sql) where T : class, new() + { + return this.Context.SqlQueryable(sql); + } + public ISugarQueryable Queryable(string tableName, string shortName) + { + return this.Context.Queryable(tableName, shortName); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return this.Context.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) + where T : class, new() + where T2 : class, new() + { + return this.Context.Queryable(joinQueryable1, joinQueryable2, joinExpression).With(SqlWith.Null); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) + where T : class, new() + where T2 : class, new() + { + return this.Context.Queryable(joinQueryable1, joinQueryable2, joinType, joinExpression).With(SqlWith.Null); + } + + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, + JoinType joinType1, Expression> joinExpression1, + JoinType joinType2, Expression> joinExpression2) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + { + return this.Context.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinType1, joinExpression1, joinType2, joinExpression2).With(SqlWith.Null); + } + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, ISugarQueryable joinQueryable4, + JoinType joinType1, Expression> joinExpression1, + JoinType joinType2, Expression> joinExpression2, + JoinType joinType3, Expression> joinExpression3) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + where T4 : class, new() + { + return this.Context.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinQueryable4, joinType1, joinExpression1, joinType2, joinExpression2, joinType3, joinExpression3).With(SqlWith.Null); + } + + public ISugarQueryable Queryable() + { + return this.Context.Queryable(); + } + + public ISugarQueryable Queryable(ISugarQueryable queryable) + { + + var result = this.Context.Queryable(queryable); + var QueryBuilder = queryable.QueryBuilder; + result.QueryBuilder.IsQueryInQuery = true; + var appendIndex = result.QueryBuilder.Parameters == null ? 1 : result.QueryBuilder.Parameters.Count + 1; + result.QueryBuilder.WhereIndex = (QueryBuilder.WhereIndex + 1); + result.QueryBuilder.LambdaExpressions.ParameterIndex = (QueryBuilder.LambdaExpressions.ParameterIndex + appendIndex); + return result; + } + public ISugarQueryable Queryable(ISugarQueryable queryable, string shortName) + { + return this.Context.Queryable(queryable, shortName); + } + + public ISugarQueryable Queryable(string shortName) + { + return this.Context.Queryable(shortName); + } + + #endregion + + #region Saveable + public GridSaveProvider GridSave(List saveList) where T : class, new() + { + return this.Context.GridSave(saveList); + } + public GridSaveProvider GridSave(List oldList, List saveList) where T : class, new() + { + return this.Context.GridSave(oldList, saveList); + } + public StorageableDataTable Storageable(DataTable data) + { + return this.Context.Storageable(data); + } + public StorageableDataTable Storageable(List> dictionaryList, string tableName) + { + DataTable dt = this.Context.Utilities.DictionaryListToDataTable(dictionaryList); + dt.TableName = tableName; + return this.Context.Storageable(dt); + } + public StorageableDataTable Storageable(Dictionary dictionary, string tableName) + { + DataTable dt = this.Context.Utilities.DictionaryListToDataTable(new List>() { dictionary }); + dt.TableName = tableName; + return this.Context.Storageable(dt); + } + + public IStorageable Storageable(List dataList) where T : class, new() + { + return this.Context.Storageable(dataList); + } + public IStorageable Storageable(IList dataList) where T : class, new() + { + return this.Context.Storageable(dataList.ToList()); + } + public IStorageable Storageable(T[] dataList) where T : class, new() + { + return this.Context.Storageable(dataList?.ToList()); + } + public IStorageable Storageable(T data) where T : class, new() + { + Check.Exception(typeof(T).FullName.Contains("System.Collections.Generic.List`"), " need where T: class, new() "); + return this.Context.Storageable(new List { data }); + } + + [Obsolete("use Storageable")] + public ISaveable Saveable(List saveObjects) where T : class, new() + { + return this.Context.Saveable(saveObjects); + } + [Obsolete("use Storageable")] + public ISaveable Saveable(T saveObject) where T : class, new() + { + return this.Context.Saveable(saveObject); + } + public StorageableMethodInfo StorageableByObject(object singleEntityObjectOrListObject) + { + return this.Context.StorageableByObject(singleEntityObjectOrListObject); + } + #endregion + + #region Reportable + public IReportable Reportable(T data) + { + return this.Context.Reportable(data); + } + public IReportable Reportable(List list) + { + return this.Context.Reportable(list); + } + public IReportable Reportable(T[] array) + { + return this.Context.Reportable(array); + } + #endregion + + #region Queue + public QueueList Queues { get { return this.Context.Queues; } set { this.Context.Queues = value; } } + public void AddQueue(string sql, object parsmeters = null) + { + this.Context.AddQueue(sql, parsmeters); + } + + public void AddQueue(string sql, List parsmeters) + { + this.Context.AddQueue(sql, parsmeters); + } + + public void AddQueue(string sql, SugarParameter parsmeter) + { + this.Context.AddQueue(sql, parsmeter); + } + public int SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Tuple, List, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Tuple, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Tuple, List, List, List, List> SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Tuple, List, List, List> SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Tuple, List, List> SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Tuple, List> SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public List SaveQueues(bool isTran = true) + { + return this.Context.SaveQueues(isTran); + } + + public Task SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task, List, List>> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task, List>> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + + public Task> SaveQueuesAsync(bool isTran = true) + { + return this.Context.SaveQueuesAsync(isTran); + } + #endregion + + #region Updateable + public IUpdateable> UpdateableByDynamic(object updateDynamicObject) + { + return this.Context.UpdateableByDynamic(updateDynamicObject); + } + public UpdateMethodInfo UpdateableByObject(object singleEntityObjectOrListObject) + { + return this.Context.UpdateableByObject(singleEntityObjectOrListObject); + } + public UpdateExpressionMethodInfo UpdateableByObject(Type entityType) + { + return this.Context.UpdateableByObject(entityType); + } + public IUpdateable Updateable() where T : class, new() + { + return this.Context.Updateable(); + } + + public IUpdateable Updateable(Dictionary columnDictionary) where T : class, new() + { + return this.Context.Updateable(columnDictionary); + } + + public IUpdateable Updateable(dynamic updateDynamicObject) where T : class, new() + { + if (updateDynamicObject is IList) + { + return this.Context.Updateable((updateDynamicObject as IList).ToList()); + } + return this.Context.Updateable(updateDynamicObject); + } + + public IUpdateable Updateable(Expression> columns) where T : class, new() + { + return this.Context.Updateable(columns); + } + + public IUpdateable Updateable(Expression> columns) where T : class, new() + { + return this.Context.Updateable(columns); + } + + public IUpdateable Updateable(List UpdateObjs) where T : class, new() + { + return this.Context.Updateable(UpdateObjs); + } + + public IUpdateable Updateable(T UpdateObj) where T : class, new() + { + return this.Context.Updateable(UpdateObj); + } + + public IUpdateable Updateable(T[] UpdateObjs) where T : class, new() + { + return this.Context.Updateable(UpdateObjs); + } + + #endregion + + #region Ado + public IAdo Ado => this.Context.Ado; + + #endregion + + #region Deleteable + public DeleteMethodInfo DeleteableByObject(object singleEntityObjectOrListObject) + { + return this.Context.DeleteableByObject(singleEntityObjectOrListObject); + } + public IDeleteable Deleteable() where T : class, new() + { + return this.Context.Deleteable(); + } + + public IDeleteable Deleteable(dynamic primaryKeyValue) where T : class, new() + { + return this.Context.Deleteable(primaryKeyValue); + } + + public IDeleteable Deleteable(dynamic[] primaryKeyValues) where T : class, new() + { + return this.Context.Deleteable(primaryKeyValues); + } + + public IDeleteable Deleteable(Expression> expression) where T : class, new() + { + return this.Context.Deleteable(expression); + } + + public IDeleteable Deleteable(List pkValue) where T : class, new() + { + return this.Context.Deleteable(pkValue); + } + + public IDeleteable Deleteable(List deleteObjs) where T : class, new() + { + return this.Context.Deleteable(deleteObjs); + } + + public IDeleteable Deleteable(T deleteObj) where T : class, new() + { + return this.Context.Deleteable(deleteObj); + } + + + #endregion + + #region Fastest + public IFastest Fastest() where T : class, new() + { + return this.Context.Fastest(); + } + #endregion + + #region ThenMapper + public void ThenMapper(IEnumerable list, Action action) + { + this.Context.ThenMapper(list, action); + } + public Task ThenMapperAsync(IEnumerable list, Func action) + { + return this.Context.ThenMapperAsync(list, action); + } + #endregion + + #region More api + public string[] GetCurrentConfigIds() + { + return _AllClients.Select(it => it.ConnectionConfig.ConfigId + string.Empty).ToArray(); + } + public IContextMethods Utilities { get { return this.Context.Utilities; } set { this.Context.Utilities = value; } } + public AopProvider Aop => this.Context.Aop; + public ICodeFirst CodeFirst => this.Context.CodeFirst; + public IDbFirst DbFirst => this.Context.DbFirst; + public IDbMaintenance DbMaintenance => this.Context.DbMaintenance; + public EntityMaintenance EntityMaintenance { get { return this.Context.EntityMaintenance; } set { this.Context.EntityMaintenance = value; } } + public QueryFilterProvider QueryFilter { get { return this.Context.QueryFilter; } set { this.Context.QueryFilter = value; } } + #endregion + + #region TenantManager + public ITenant AsTenant() + { + var tenant = this as ITenant; + return tenant; + } + public SqlSugarTransaction UseTran() + { + return new SqlSugarTransaction(this); + } + public void RemoveConnection(dynamic configId) + { + var removeData = this._AllClients.FirstOrDefault(it => ((object)it.ConnectionConfig.ConfigId).ObjToString() == ((object)configId).ObjToString()); + object currentId = this.CurrentConnectionConfig.ConfigId; + if (removeData != null) + { + if (removeData.Context.Ado.IsAnyTran()) + { + Check.ExceptionEasy("RemoveConnection error has tran", $"删除失败{removeData.ConnectionConfig.ConfigId}存在未提交事务"); + } + else if (((object)removeData.ConnectionConfig.ConfigId).ObjToString() == currentId.ObjToString()) + { + Check.ExceptionEasy("Default ConfigId cannot be deleted", $"默认库不能删除{removeData.ConnectionConfig.ConfigId}"); + } + this._AllClients.Remove(removeData); + } + } + public void AddConnection(ConnectionConfig connection) + { + Check.ArgumentNullException(connection, "AddConnection.connection can't be null"); + InitTenant(); + var db = this._AllClients.FirstOrDefault(it => ((object)it.ConnectionConfig.ConfigId).ObjToString() == ((object)connection.ConfigId).ObjToString()); + if (db == null) + { + if (this._AllClients == null) + { + this._AllClients = new List(); + } + var provider = new SqlSugarProvider(connection); + if (connection.AopEvents != null) + { + provider.Ado.IsEnableLogEvent = true; + } + this._AllClients.Add(new SugarTenant() + { + ConnectionConfig = connection, + Context = provider + }); + } + } + public SqlSugarProvider GetConnectionWithAttr() + { + var attr = typeof(T).GetCustomAttribute(); + if (attr == null) + return this.GetConnection(this.CurrentConnectionConfig.ConfigId); + var configId = attr.configId; + return this.GetConnection(configId); + } + public SqlSugarProvider GetConnectionWithAttr(Type type) + { + var attr = type.GetCustomAttribute(); + if (attr == null) + return this.GetConnection(this.CurrentConnectionConfig.ConfigId); + var configId = attr.configId; + return this.GetConnection(configId); + } + public SqlSugarScopeProvider GetConnectionScopeWithAttr() + { + var attr = typeof(T).GetCustomAttribute(); + if (attr == null) + return this.GetConnectionScope(this.CurrentConnectionConfig.ConfigId); + var configId = attr.configId; + return this.GetConnectionScope(configId); + } + public SqlSugarProvider GetConnection(object configId) + { + InitTenant(); + var db = this._AllClients.FirstOrDefault(it => Convert.ToString(it.ConnectionConfig.ConfigId) == Convert.ToString(configId)); + if (db == null) + { + Check.Exception(true, "ConfigId was not found {0}", configId + ""); + } + if (db.Context == null) + { + db.Context = new SqlSugarProvider(db.ConnectionConfig); + } + var intiAop = db.Context.Aop; + if (db.Context.CurrentConnectionConfig.AopEvents == null) + { + db.Context.CurrentConnectionConfig.AopEvents = new AopEvents(); + } + if (_IsAllTran && db.Context.Ado.Transaction == null) + { + db.Context.Ado.BeginTran(); + } + db.Context.Root = this; + if (db.Context.MappingTables == null) + { + db.Context.MappingTables = new MappingTableList(); + } + return db.Context; + } + + public SqlSugarScopeProvider GetConnectionScope(object configId) + { + var conn = GetConnection(configId); + return new SqlSugarScopeProvider(conn); + } + public bool IsAnyConnection(object configId) + { + InitTenant(); + var db = this._AllClients.FirstOrDefault(it => Convert.ToString(it.ConnectionConfig.ConfigId) == Convert.ToString(configId)); + return db != null; + + } + public void ChangeDatabase(object configId) + { + configId = Convert.ToString(configId); + var isLog = _Context.Ado.IsEnableLogEvent; + Check.Exception(!_AllClients.Any(it => Convert.ToString(it.ConnectionConfig.ConfigId) == Convert.ToString(configId)), "ConfigId was not found {0}", configId + ""); + InitTenant(_AllClients.First(it => Convert.ToString(it.ConnectionConfig.ConfigId) == Convert.ToString(configId))); + if (this._IsAllTran) + this.Ado.BeginTran(); + if (this._IsOpen) + this.Open(); + _Context.Ado.IsEnableLogEvent = isLog; + if (_CurrentConnectionConfig.AopEvents == null) + _CurrentConnectionConfig.AopEvents = new AopEvents(); + } + public void ChangeDatabase(Func changeExpression) + { + var isLog = _Context.Ado.IsEnableLogEvent; + var allConfigs = _AllClients.Select(it => it.ConnectionConfig); + Check.Exception(!allConfigs.Any(changeExpression), "changeExpression was not found {0}", changeExpression.ToString()); + InitTenant(_AllClients.First(it => it.ConnectionConfig == allConfigs.First(changeExpression))); + if (this._IsAllTran) + this.Ado.BeginTran(); + if (this._IsOpen) + this.Open(); + _Context.Ado.IsEnableLogEvent = isLog; + if (_CurrentConnectionConfig.AopEvents == null) + _CurrentConnectionConfig.AopEvents = new AopEvents(); + } + public void BeginTran() + { + _IsAllTran = true; + AllClientEach(it => it.Ado.BeginTran()); + } + + public void BeginTran(IsolationLevel iso) + { + _IsAllTran = true; + AllClientEach(it => it.Ado.BeginTran(iso)); + } + + public async Task BeginTranAsync() + { + _IsAllTran = true; + await AllClientEachAsync(async it => await it.Ado.BeginTranAsync().ConfigureAwait(false)).ConfigureAwait(false); + } + + public async Task BeginTranAsync(IsolationLevel iso) + { + _IsAllTran = true; + await AllClientEachAsync(async it => await it.Ado.BeginTranAsync(iso).ConfigureAwait(false)).ConfigureAwait(false); + } + + public void CommitTran() + { + this.Context.Ado.CommitTran(); + AllClientEach(it => + { + + try + { + it.Ado.CommitTran(); + } + catch + { + SugarRetry.Execute(() => it.Ado.CommitTran(), new TimeSpan(0, 0, 5), 3); + } + + }); + _IsAllTran = false; + } + + public async Task CommitTranAsync() + { + await Context.Ado.CommitTranAsync().ConfigureAwait(false); + await AllClientEachAsync(async it => + { + + try + { + await it.Ado.CommitTranAsync().ConfigureAwait(false); + } + catch + { + SugarRetry.Execute(() => it.Ado.CommitTran(), new TimeSpan(0, 0, 5), 3); + } + + }).ConfigureAwait(false); + _IsAllTran = false; + } + public DbResult UseTran(Action action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + this.BeginTran(); + if (action != null) + action(); + this.CommitTran(); + result.Data = result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + this.RollbackTran(); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public async Task> UseTranAsync(Func action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + await BeginTranAsync().ConfigureAwait(false); + if (action != null) + await action().ConfigureAwait(false); + await CommitTranAsync().ConfigureAwait(false); + result.Data = result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + await RollbackTranAsync().ConfigureAwait(false); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public DbResult UseTran(Func action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + this.BeginTran(); + if (action != null) + result.Data = action(); + this.CommitTran(); + result.IsSuccess = true; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + this.RollbackTran(); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public async Task> UseTranAsync(Func> action, Action errorCallBack = null) + { + var result = new DbResult(); + try + { + this.BeginTran(); + T data = default(T); + if (action != null) + data = await action().ConfigureAwait(false); + this.CommitTran(); + result.IsSuccess = true; + result.Data = data; + } + catch (Exception ex) + { + result.ErrorException = ex; + result.ErrorMessage = ex.Message; + result.IsSuccess = false; + this.RollbackTran(); + if (errorCallBack != null) + { + errorCallBack(ex); + } + } + return result; + } + + public void RollbackTran() + { + this.Context.Ado.RollbackTran(); + AllClientEach(it => + { + + try + { + it.Ado.RollbackTran(); + } + catch + { + SugarRetry.Execute(() => it.Ado.RollbackTran(), new TimeSpan(0, 0, 5), 3); + } + + }); + _IsAllTran = false; + } + public async Task RollbackTranAsync() + { + await Context.Ado.RollbackTranAsync().ConfigureAwait(false); + await AllClientEachAsync(async it => + { + + try + { + await it.Ado.RollbackTranAsync().ConfigureAwait(false); + } + catch + { + SugarRetry.Execute(() => it.Ado.RollbackTran(), new TimeSpan(0, 0, 5), 3); + } + + }).ConfigureAwait(false); + _IsAllTran = false; + } + public void Close() + { + this.Context.Close(); + AllClientEach(it => it.Close()); + _IsOpen = false; + } + public void Open() + { + this.Context.Open(); + _IsOpen = true; + } + + #endregion + + #region IDispose + public void Dispose() + { + AllClientEach(it => it.Ado.RollbackTran()); + AllClientEach(it => it.Dispose()); + } + + #endregion + + #region Cache + public SugarCacheProvider DataCache + { + get { return this.Context.DataCache; } + } + #endregion + + #region Other method + public DynamicBuilder DynamicBuilder() + { + return this.Context.DynamicBuilder(); + } + public void Tracking(T data) where T : class, new() + { + this.Context.Tracking(data); + } + public void ClearTracking() + { + this.Context.ClearTracking(); + } + public void Tracking(List datas) where T : class, new() + { + this.Context.Tracking(datas); + } + public SqlSugarClient CopyNew() + { + + if (_AllClients?.Count > 1 && _configAction != null) + { + List connections = new List(); + foreach (var item in _AllClients) + { + connections.Add(UtilMethods.CopyConfig(item.ConnectionConfig)); + } + var newDb = new SqlSugarClient(connections, _configAction); + newDb.QueryFilter = this.QueryFilter; + return newDb; + } + + SqlSugarClient result; + if (_configAction != null) + result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig), _configAction); + else + result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); + result.QueryFilter = this.QueryFilter; + if (_AllClients != null) + { + foreach (var item in _AllClients) + { + if (!result.IsAnyConnection(item.ConnectionConfig.ConfigId)) + { + result.AddConnection(UtilMethods.CopyConfig(item.ConnectionConfig)); + } + } + } + return result; + } + public DateTime GetDate() + { + return this.Context.GetDate(); + } + public void InitMappingInfo(Type type) + { + this.Context.InitMappingInfo(type); + } + public void InitMappingInfo() + { + this.Context.InitMappingInfo(typeof(T)); + } + #endregion + + #region Helper + public Task AsyncLock(int timeOutSeconds = 30) + { + return this.Context.AsyncLock(timeOutSeconds); + } + public SplitTableContext SplitHelper() where T : class, new() + { + return this.Context.SplitHelper(); + } + public SplitTableContext SplitHelper(Type entityType) + { + return this.Context.SplitHelper(entityType); + } + public SplitTableContextResult SplitHelper(T data) where T : class, new() + { + return this.Context.SplitHelper(data); + } + public SplitTableContextResult SplitHelper(List dataList) where T : class, new() + { + return this.Context.SplitHelper(dataList); + } + private SqlSugarProvider GetContext() + { + SqlSugarProvider result = null; + //if (IsSameThreadAndShard()) + //{ + // result = SameThreadAndShard(); + //} + //else if (IsNoSameThreadAndShard()) + //{ + // result = NoSameThreadAndShard(); + //} + //else + //{ + result = Synchronization(); + //} + //Because SqlSugarScope implements thread safety + //else if (IsSingleInstanceAsync()) + //{ + // result = Synchronization();//Async no support Single Instance + //} + //else if (IsAsync()) + //{ + // result = Synchronization(); + //} + //else + //{ + // StackTrace st = new StackTrace(true); + // var methods = st.GetFrames(); + // var isAsync = UtilMethods.IsAnyAsyncMethod(methods); + // if (isAsync) + // { + // result = Synchronization(); + // } + // else + // { + // result = NoSameThread(); + // } + //} + if (result.Root == null) + { + result.Root = this; + } + return result; + } + + private SqlSugarProvider NoSameThreadAsync() + { + var result = GetCallContext(); + return result; + } + private SqlSugarProvider NoSameThread() + { + if (CallContext.ContextList.Value == null) + { + var context = CopyClient(); + AddCallContext(context); + return context; + } + else + { + var result = GetCallContext(); + if (result == null) + { + var copy = CopyClient(); + AddCallContext(copy); + return copy; + } + else + { + return result; + } + } + } + private void InitTenant() + { + if (this._AllClients == null) + { + this._AllClients = new List(); + this._AllClients.Add(new SugarTenant() + { + ConnectionConfig = this.CurrentConnectionConfig, + Context = this.Context + }); + } + } + + private SqlSugarProvider Synchronization() + { + _Context.MappingColumns = _MappingColumns; + _Context.MappingTables = _MappingTables; + _Context.IgnoreColumns = _IgnoreColumns; + _Context.IgnoreInsertColumns = _IgnoreInsertColumns; + return _Context; + } + + private SqlSugarProvider NoSameThreadAndShard() + { + if (CallContext.ContextList.Value.IsNullOrEmpty()) + { + var copy = CopyClient(); + AddCallContext(copy); + return copy; + } + else + { + var result = GetCallContext(); + if (result == null) + { + var copy = CopyClient(); + AddCallContext(copy); + return copy; + } + else + { + return result; + } + } + } + + private SqlSugarProvider SameThreadAndShard() + { + if (CallContext.ContextList.Value.IsNullOrEmpty()) + { + AddCallContext(_Context); + return _Context; + } + else + { + var result = GetCallContext(); + if (result == null) + { + var copy = CopyClient(); + AddCallContext(copy); + return copy; + } + else + { + return result; + } + } + } + + private bool IsAsync() + { + return AsyncId != null; + } + + private bool IsSingleInstanceAsync() + { + return IsSingleInstance == true && AsyncId != null; + } + + private bool IsSynchronization() + { + return _ThreadId == Environment.CurrentManagedThreadId.ToString(); + } + + //private bool IsNoSameThreadAndShard() + //{ + // return CurrentConnectionConfig.IsShardSameThread && _ThreadId != Thread.CurrentThread.ManagedThreadId.ToString(); + //} + + //private bool IsSameThreadAndShard() + //{ + // return CurrentConnectionConfig.IsShardSameThread && _ThreadId == Thread.CurrentThread.ManagedThreadId.ToString(); + //} + + private SqlSugarProvider CopyClient() + { + var result = new SqlSugarProvider(this.CurrentConnectionConfig); + result.MappingColumns = _MappingColumns; + result.MappingTables = _MappingTables; + result.IgnoreColumns = _IgnoreColumns; + result.IgnoreInsertColumns = _IgnoreInsertColumns; + + return result; + } + private void AddCallContext(SqlSugarProvider context) + { + CallContext.ContextList.Value = new List(); + CallContext.ContextList.Value.Add(context); + } + + private SqlSugarProvider GetCallContext() + { + return CallContext.ContextList.Value.FirstOrDefault(it => + it.CurrentConnectionConfig.DbType == _Context.CurrentConnectionConfig.DbType && + it.CurrentConnectionConfig.ConnectionString == _Context.CurrentConnectionConfig.ConnectionString && + it.CurrentConnectionConfig.InitKeyType == _Context.CurrentConnectionConfig.InitKeyType && + it.CurrentConnectionConfig.IsAutoCloseConnection == _Context.CurrentConnectionConfig.IsAutoCloseConnection + ); + } + + protected virtual void InitContext(ConnectionConfig config) + { + var aopIsNull = config.AopEvents == null; + if (aopIsNull) + { + config.AopEvents = new AopEvents(); + } + _Context = new SqlSugarProvider(config); + if (!aopIsNull) + _Context.Ado.IsEnableLogEvent = true; + this.CurrentConnectionConfig = config; + _ThreadId = Environment.CurrentManagedThreadId.ToString(); + if (this.MappingTables == null) + this.MappingTables = new MappingTableList(); + if (this.MappingColumns == null) + this.MappingColumns = new MappingColumnList(); + if (this.IgnoreColumns == null) + this.IgnoreColumns = new IgnoreColumnList(); + if (this.IgnoreInsertColumns == null) + this.IgnoreInsertColumns = new IgnoreColumnList(); + } + + private void InitConfigs(List configs) + { + foreach (var item in configs) + { + if (item.ConfigId == null) + { + item.ConfigId = ""; + } + } + } + private void AllClientEach(Action action) + { + if (this._AllClients == null) + { + this._AllClients = new List(); + this._AllClients.Add(new SugarTenant() { ConnectionConfig = this.CurrentConnectionConfig, Context = this.Context }); + } + if (_AllClients.HasValue()) + { + foreach (var item in _AllClients.Where(it => it.Context.HasValue())) + { + action(item.Context); + } + } + } + + + private async Task AllClientEachAsync(Func action) + { + if (this._AllClients == null) + { + this._AllClients = new List(); + this._AllClients.Add(new SugarTenant() { ConnectionConfig = this.CurrentConnectionConfig, Context = this.Context }); + } + if (_AllClients.HasValue()) + { + foreach (var item in _AllClients.Where(it => it.Context.HasValue())) + { + await action(item.Context).ConfigureAwait(false); + } + } + } + private void InitTenant(SugarTenant Tenant) + { + if (Tenant.Context == null) + { + Tenant.Context = new SqlSugarProvider(Tenant.ConnectionConfig); + } + _Context = Tenant.Context; + this.CurrentConnectionConfig = Tenant.ConnectionConfig; + } + #endregion + + #region Tenant Crud + public ISugarQueryable QueryableWithAttr() + { + var result = this.GetConnectionWithAttr().Queryable(); + result.QueryBuilder.IsCrossQueryWithAttr = true; + return result; + } + public IInsertable InsertableWithAttr(T insertObj) where T : class, new() + { + var result = this.GetConnectionWithAttr().Insertable(insertObj); + result.InsertBuilder.IsWithAttr = true; + return result; + } + public IInsertable InsertableWithAttr(List insertObjs) where T : class, new() + { + var result = this.GetConnectionWithAttr().Insertable(insertObjs); + result.InsertBuilder.IsWithAttr = true; + return result; + } + public IUpdateable UpdateableWithAttr(T updateObj) where T : class, new() + { + return this.GetConnectionWithAttr().Updateable(updateObj); + } + public IUpdateable UpdateableWithAttr() where T : class, new() + { + return this.GetConnectionWithAttr().Updateable(); + } + public IUpdateable UpdateableWithAttr(List updateObjs) where T : class, new() + { + return this.GetConnectionWithAttr().Updateable(updateObjs); + } + public IDeleteable DeleteableWithAttr(T deleteObject) where T : class, new() + { + return this.GetConnectionWithAttr().Deleteable(deleteObject); + } + public IDeleteable DeleteableWithAttr() where T : class, new() + { + return this.GetConnectionWithAttr().Deleteable(); + } + public IDeleteable DeleteableWithAttr(List deleteObjects) where T : class, new() + { + return this.GetConnectionWithAttr().Deleteable(deleteObjects); + } + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SqlSugarScope.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SqlSugarScope.cs new file mode 100644 index 000000000..8dcbf4f5c --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SqlSugarScope.cs @@ -0,0 +1,917 @@ +using System.Data; +using System.Dynamic; +using System.Linq.Expressions; + +namespace SqlSugar +{ + public partial class SqlSugarScope : ISqlSugarClient, ITenant + { + private SqlSugarScope() + { + + } + public SqlSugarScope(ConnectionConfig config) + { + _configs = new List() { config }; + } + public SqlSugarScope(List configs) + { + _configs = configs; + } + public SqlSugarScope(ConnectionConfig config, Action configAction) + { + _configs = new List() { config }; + this._configAction = configAction; + } + public SqlSugarScope(List configs, Action configAction) + { + _configs = configs; + this._configAction = configAction; + } + public SqlSugarClient ScopedContext { get { return GetContext(); } } + public SugarActionType SugarActionType { get => ScopedContext.SugarActionType; set => ScopedContext.SugarActionType = value; } + public MappingTableList MappingTables { get => ScopedContext.MappingTables; set => ScopedContext.MappingTables = value; } + public MappingColumnList MappingColumns { get => ScopedContext.MappingColumns; set => ScopedContext.MappingColumns = value; } + public IgnoreColumnList IgnoreColumns { get => ScopedContext.IgnoreColumns; set => ScopedContext.IgnoreColumns = value; } + public IgnoreColumnList IgnoreInsertColumns { get => ScopedContext.IgnoreInsertColumns; set => ScopedContext.IgnoreInsertColumns = value; } + public Dictionary TempItems { get => ScopedContext.TempItems; set => ScopedContext.TempItems = value; } + public ConfigQuery ConfigQuery { get => ScopedContext.ConfigQuery; set => ScopedContext.ConfigQuery = value; } + + public Guid ContextID { get => ScopedContext.ContextID; set => ScopedContext.ContextID = value; } + public ConnectionConfig CurrentConnectionConfig { get => ScopedContext.CurrentConnectionConfig; set => ScopedContext.CurrentConnectionConfig = value; } + + public IAdo Ado => ScopedContext.Ado; + + public AopProvider Aop => ScopedContext.Aop; + + public ICodeFirst CodeFirst => ScopedContext.CodeFirst; + + public IDbFirst DbFirst => ScopedContext.DbFirst; + + public IDbMaintenance DbMaintenance => ScopedContext.DbMaintenance; + + public EntityMaintenance EntityMaintenance { get => ScopedContext.EntityMaintenance; set => ScopedContext.EntityMaintenance = value; } + public QueryFilterProvider QueryFilter { get => ScopedContext.QueryFilter; set => ScopedContext.QueryFilter = value; } + public IContextMethods Utilities { get => ScopedContext.Utilities; set => ScopedContext.Utilities = value; } + public QueueList Queues { get => ScopedContext.Queues; set => ScopedContext.Queues = value; } + + public SugarCacheProvider DataCache => ScopedContext.DataCache; + + public ITenant AsTenant() + { + return ScopedContext.AsTenant(); + } + public void AddConnection(ConnectionConfig connection) + { + ScopedContext.AddConnection(connection); + } + + public void AddQueue(string sql, object parsmeters = null) + { + ScopedContext.AddQueue(sql, parsmeters); + } + + public void AddQueue(string sql, List parsmeters) + { + ScopedContext.AddQueue(sql, parsmeters); + } + + public void AddQueue(string sql, SugarParameter parsmeter) + { + ScopedContext.AddQueue(sql, parsmeter); + } + + public void BeginTran() + { + ScopedContext.BeginTran(); + } + public void BeginTran(IsolationLevel iso) + { + ScopedContext.BeginTran(iso); + } + public Task BeginTranAsync() + { + return ScopedContext.BeginTranAsync(); + } + public async Task BeginTranAsync(IsolationLevel iso) + { + await ScopedContext.BeginTranAsync(iso).ConfigureAwait(false); + } + public void ChangeDatabase(object configId) + { + ScopedContext.ChangeDatabase(configId); + } + + public void ChangeDatabase(Func changeExpression) + { + ScopedContext.ChangeDatabase(changeExpression); + } + + public void Close() + { + ScopedContext.Close(); + } + + public void CommitTran() + { + ScopedContext.CommitTran(); + } + public Task CommitTranAsync() + { + return ScopedContext.CommitTranAsync(); + } + public DeleteMethodInfo DeleteableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.DeleteableByObject(singleEntityObjectOrListObject); + } + public IDeleteable Deleteable() where T : class, new() + { + return ScopedContext.Deleteable(); + } + + public IDeleteable Deleteable(dynamic primaryKeyValue) where T : class, new() + { + return ScopedContext.Deleteable(primaryKeyValue); + } + + public IDeleteable Deleteable(dynamic[] primaryKeyValues) where T : class, new() + { + return ScopedContext.Deleteable(primaryKeyValues); + } + + public IDeleteable Deleteable(Expression> expression) where T : class, new() + { + return ScopedContext.Deleteable(expression); + } + + public IDeleteable Deleteable(List pkValue) where T : class, new() + { + return ScopedContext.Deleteable(pkValue); + } + + public IDeleteable Deleteable(List deleteObjs) where T : class, new() + { + return ScopedContext.Deleteable(deleteObjs); + } + + public IDeleteable Deleteable(T deleteObj) where T : class, new() + { + return ScopedContext.Deleteable(deleteObj); + } + + public void Dispose() + { + ScopedContext.Dispose(); + } + + public SqlSugarProvider GetConnection(object configId) + { + return ScopedContext.GetConnection(configId); + } + public SqlSugarScopeProvider GetConnectionScope(object configId) + { + return ScopedContext.GetConnectionScope(configId); + } + public SqlSugarProvider GetConnectionWithAttr() + { + return ScopedContext.GetConnectionWithAttr(); + } + public SqlSugarScopeProvider GetConnectionScopeWithAttr() + { + return ScopedContext.GetConnectionScopeWithAttr(); + } + public DateTime GetDate() + { + return ScopedContext.GetDate(); + } + + public T CreateContext(bool isTran = true) where T : SugarUnitOfWork, new() + { + return ScopedContext.CreateContext(isTran); + } + public SugarUnitOfWork CreateContext(bool isTran = true) + { + return ScopedContext.CreateContext(isTran); + } + + public SimpleClient GetSimpleClient() where T : class, new() + { + return ScopedContext.GetSimpleClient(); + } + public RepositoryType GetRepository() where RepositoryType : ISugarRepository, new() + { + return ScopedContext.GetRepository(); + } + public void InitMappingInfo(Type type) + { + ScopedContext.InitMappingInfo(type); + } + + public void InitMappingInfo() + { + ScopedContext.InitMappingInfo(); + } + + public IInsertable> InsertableByDynamic(object insertDynamicObject) + { + return ScopedContext.InsertableByDynamic(insertDynamicObject); + } + public IInsertable Insertable(Dictionary columnDictionary) where T : class, new() + { + return ScopedContext.Insertable(columnDictionary); + } + + public IInsertable Insertable(dynamic insertDynamicObject) where T : class, new() + { + return ScopedContext.Insertable((object)insertDynamicObject); + } + + public IInsertable Insertable(List insertObjs) where T : class, new() + { + return ScopedContext.Insertable(insertObjs); + } + + public IInsertable Insertable(T insertObj) where T : class, new() + { + return ScopedContext.Insertable(insertObj); + } + + public IInsertable Insertable(T[] insertObjs) where T : class, new() + { + return ScopedContext.Insertable(insertObjs); + } + public InsertMethodInfo InsertableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.InsertableByObject(singleEntityObjectOrListObject); + } + public void Open() + { + ScopedContext.Open(); + } + public ISugarQueryable SlaveQueryable() + { + return ScopedContext.SlaveQueryable(); + } + public ISugarQueryable MasterQueryable() + { + return ScopedContext.MasterQueryable(); + } + public ISugarQueryable Queryable(string tableName, string shortName) + { + return ScopedContext.Queryable(tableName, shortName); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(Expression> joinExpression) + { + return ScopedContext.Queryable(joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) + where T : class, new() + where T2 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) + where T : class, new() + where T2 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinType, joinExpression); + } + + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, JoinType joinType1, Expression> joinExpression1, JoinType joinType2, Expression> joinExpression2) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinType1, joinExpression1, joinType2, joinExpression2); + } + public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, ISugarQueryable joinQueryable4, JoinType joinType1, Expression> joinExpression1, JoinType joinType2, Expression> joinExpression2, JoinType joinType3, Expression> joinExpression3) + where T : class, new() + where T2 : class, new() + where T3 : class, new() + where T4 : class, new() + { + return ScopedContext.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinQueryable4, joinType1, joinExpression1, joinType2, joinExpression2, joinType3, joinExpression3); + } + public ISugarQueryable Queryable() + { + return ScopedContext.Queryable(); + } + + public ISugarQueryable Queryable(ISugarQueryable queryable) + { + return ScopedContext.Queryable(queryable); + } + public ISugarQueryable Queryable(ISugarQueryable queryable, string shortName) + { + return ScopedContext.Queryable(queryable, shortName); + } + + public ISugarQueryable Queryable(string shortName) + { + return ScopedContext.Queryable(shortName); + } + + public IReportable Reportable(T data) + { + return ScopedContext.Reportable(data); + } + + public IReportable Reportable(List list) + { + return ScopedContext.Reportable(list); + } + + public IReportable Reportable(T[] array) + { + return ScopedContext.Reportable(array); + } + + public void RollbackTran() + { + ScopedContext.RollbackTran(); + } + public Task RollbackTranAsync() + { + return ScopedContext.RollbackTranAsync(); + } + + [Obsolete("use Storageable")] + public ISaveable Saveable(List saveObjects) where T : class, new() + { + return ScopedContext.Saveable(saveObjects); + } + [Obsolete("use Storageable")] + public ISaveable Saveable(T saveObject) where T : class, new() + { + return ScopedContext.Saveable(saveObject); + } + + public int SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Tuple, List> SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public List SaveQueues(bool isTran = true) + { + return ScopedContext.SaveQueues(isTran); + } + + public Task SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task, List>> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public Task> SaveQueuesAsync(bool isTran = true) + { + return ScopedContext.SaveQueuesAsync(isTran); + } + + public ISugarQueryable SqlQueryable(string sql) where T : class, new() + { + return ScopedContext.SqlQueryable(sql); + } + public IStorageable Storageable(T[] dataList) where T : class, new() + { + return ScopedContext.Storageable(dataList); + } + public StorageableDataTable Storageable(List> dictionaryList, string tableName) + { + return ScopedContext.Storageable(dictionaryList, tableName); + } + public StorageableDataTable Storageable(Dictionary dictionary, string tableName) + { + return ScopedContext.Storageable(dictionary, tableName); + } + public IStorageable Storageable(List dataList) where T : class, new() + { + return ScopedContext.Storageable(dataList); + } + public IStorageable Storageable(IList dataList) where T : class, new() + { + return ScopedContext.Storageable(dataList?.ToList()); + } + public IStorageable Storageable(T data) where T : class, new() + { + return ScopedContext.Storageable(data); + } + public StorageableDataTable Storageable(DataTable data) + { + return ScopedContext.Storageable(data); + } + public StorageableMethodInfo StorageableByObject(object singleEntityObjectOrListObject) + { + return this.ScopedContext.StorageableByObject(singleEntityObjectOrListObject); + } + + public ISugarQueryable Union(List> queryables) where T : class + { + return ScopedContext.Union(queryables); + } + + public ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class + { + return ScopedContext.Union(queryables); + } + + public ISugarQueryable UnionAll(List> queryables) where T : class + { + return ScopedContext.UnionAll(queryables); + } + + public ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class + { + return ScopedContext.UnionAll(queryables); + } + public UpdateMethodInfo UpdateableByObject(object singleEntityObjectOrListObject) + { + return ScopedContext.UpdateableByObject(singleEntityObjectOrListObject); + } + public UpdateExpressionMethodInfo UpdateableByObject(Type entityType) + { + return ScopedContext.UpdateableByObject(entityType); + } + public IUpdateable> UpdateableByDynamic(object updateDynamicObject) + { + return ScopedContext.UpdateableByDynamic(updateDynamicObject); + } + public IUpdateable Updateable() where T : class, new() + { + return ScopedContext.Updateable(); + } + + public IUpdateable Updateable(Dictionary columnDictionary) where T : class, new() + { + return ScopedContext.Updateable(columnDictionary); + } + + public IUpdateable Updateable(dynamic updateDynamicObject) where T : class, new() + { + return ScopedContext.Updateable((object)updateDynamicObject); + } + + public IUpdateable Updateable(Expression> columns) where T : class, new() + { + return ScopedContext.Updateable(columns); + } + + public IUpdateable Updateable(Expression> columns) where T : class, new() + { + return ScopedContext.Updateable(columns); + } + + public IUpdateable Updateable(List UpdateObjs) where T : class, new() + { + return ScopedContext.Updateable(UpdateObjs); + } + + public IUpdateable Updateable(T UpdateObj) where T : class, new() + { + return ScopedContext.Updateable(UpdateObj); + } + + public IUpdateable Updateable(T[] UpdateObjs) where T : class, new() + { + return ScopedContext.Updateable(UpdateObjs); + } + public SplitTableContext SplitHelper() where T : class, new() + { + return ScopedContext.SplitHelper(); + } + public SplitTableContext SplitHelper(Type entityType) + { + return ScopedContext.SplitHelper(entityType); + } + public SplitTableContextResult SplitHelper(T data) where T : class, new() + { + return ScopedContext.SplitHelper(data); + } + public SplitTableContextResult SplitHelper(List dataList) where T : class, new() + { + return ScopedContext.SplitHelper(dataList); + } + public SqlSugarTransaction UseTran() + { + return ScopedContext.UseTran(); + } + public DbResult UseTran(Action action, Action errorCallBack = null) + { + return ScopedContext.UseTran(action, errorCallBack); + } + + public DbResult UseTran(Func action, Action errorCallBack = null) + { + return ScopedContext.UseTran(action, errorCallBack); + } + + public Task> UseTranAsync(Func action, Action errorCallBack = null) + { + return ScopedContext.UseTranAsync(action, errorCallBack); + } + + public Task> UseTranAsync(Func> action, Action errorCallBack = null) + { + return ScopedContext.UseTranAsync(action, errorCallBack); + } + + public bool IsAnyConnection(object configId) + { + return ScopedContext.IsAnyConnection(configId); + } + + public IFastest Fastest() where T : class, new() + { + return ScopedContext.Fastest(); + } + + public void ThenMapper(IEnumerable list, Action action) + { + ScopedContext.ThenMapper(list, action); + } + + public Task ThenMapperAsync(IEnumerable list, Func action) + { + return ScopedContext.ThenMapperAsync(list, action); + } + public ISugarQueryable QueryableWithAttr() + { + return ScopedContext.QueryableWithAttr(); + } + public IInsertable InsertableWithAttr(T insertObj) where T : class, new() + { + return ScopedContext.InsertableWithAttr(insertObj); + } + public IInsertable InsertableWithAttr(List insertObjs) where T : class, new() + { + return ScopedContext.InsertableWithAttr(insertObjs); + } + public IUpdateable UpdateableWithAttr(T updateObj) where T : class, new() + { + return ScopedContext.UpdateableWithAttr(updateObj); + } + + public IUpdateable UpdateableWithAttr() where T : class, new() + { + return ScopedContext.UpdateableWithAttr(); + } + + public IUpdateable UpdateableWithAttr(List updateObjs) where T : class, new() + { + return ScopedContext.UpdateableWithAttr(updateObjs); + } + public IDeleteable DeleteableWithAttr(T deleteObj) where T : class, new() + { + return ScopedContext.DeleteableWithAttr(deleteObj); + } + public IDeleteable DeleteableWithAttr() where T : class, new() + { + return ScopedContext.DeleteableWithAttr(); + } + public IDeleteable DeleteableWithAttr(List deleteObjs) where T : class, new() + { + return ScopedContext.DeleteableWithAttr(deleteObjs); + } + + public InsertNavTaskInit InsertNav(T data) where T : class, new() + { + return ScopedContext.InsertNav(data); + } + public InsertNavTaskInit InsertNav(List datas) where T : class, new() + { + return ScopedContext.InsertNav(datas); + } + public InsertNavTaskInit InsertNav(T data, InsertNavRootOptions rootOptions) where T : class, new() + { + return ScopedContext.InsertNav(data, rootOptions); + } + public InsertNavTaskInit InsertNav(List datas, InsertNavRootOptions rootOptions) where T : class, new() + { + return ScopedContext.InsertNav(datas, rootOptions); + } + public DeleteNavTaskInit DeleteNav(T data) where T : class, new() + { + return ScopedContext.DeleteNav(data); + } + public DeleteNavTaskInit DeleteNav(List datas) where T : class, new() + { + return ScopedContext.DeleteNav(datas); + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression) where T : class, new() + { + return ScopedContext.DeleteNav(whereExpression); + } + + + public DeleteNavTaskInit DeleteNav(T data, DeleteNavRootOptions options) where T : class, new() + { + return ScopedContext.DeleteNav(data, options); + } + public DeleteNavTaskInit DeleteNav(List datas, DeleteNavRootOptions options) where T : class, new() + { + return ScopedContext.DeleteNav(datas, options); + } + public DeleteNavTaskInit DeleteNav(Expression> whereExpression, DeleteNavRootOptions options) where T : class, new() + { + return ScopedContext.DeleteNav(whereExpression, options); + } + + public UpdateNavTaskInit UpdateNav(T data) where T : class, new() + { + return ScopedContext.UpdateNav(data); + } + public UpdateNavTaskInit UpdateNav(List datas) where T : class, new() + { + return ScopedContext.UpdateNav(datas); + } + public UpdateNavTaskInit UpdateNav(T data, UpdateNavRootOptions rootOptions) where T : class, new() + { + return ScopedContext.UpdateNav(data, rootOptions); + } + public UpdateNavTaskInit UpdateNav(List datas, UpdateNavRootOptions rootOptions) where T : class, new() + { + return ScopedContext.UpdateNav(datas, rootOptions); + } + public SqlSugarClient CopyNew() + { + var result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); + result.QueryFilter = this.QueryFilter; + if (this.ScopedContext._AllClients != null) + { + foreach (var item in this.ScopedContext._AllClients) + { + if (!result.IsAnyConnection(item.ConnectionConfig.ConfigId)) + { + result.AddConnection(UtilMethods.CopyConfig(item.ConnectionConfig)); + } + } + } + return result; + } + public DynamicBuilder DynamicBuilder() + { + return ScopedContext.DynamicBuilder(); + } + public void Tracking(T data) where T : class, new() + { + ScopedContext.Tracking(data); + } + public void Tracking(List datas) where T : class, new() + { + ScopedContext.Tracking(datas); + } + public void RemoveConnection(dynamic configId) + { + ScopedContext.RemoveConnection(configId); + } + public Task AsyncLock(int timeOutSeconds = 30) + { + return ScopedContext.AsyncLock(timeOutSeconds); + } + public QueryMethodInfo QueryableByObject(Type entityType) + { + return ScopedContext.QueryableByObject(entityType); + } + public QueryMethodInfo QueryableByObject(Type entityType, string shortName) + { + return ScopedContext.QueryableByObject(entityType, shortName); + } + public GridSaveProvider GridSave(List oldList, List saveList) where T : class, new() + { + return ScopedContext.GridSave(oldList, saveList); + } + public GridSaveProvider GridSave(List saveList) where T : class, new() + { + return ScopedContext.GridSave(saveList); + } + public void ClearTracking() + { + ScopedContext.ClearTracking(); + } + public string[] GetCurrentConfigIds() + { + return ScopedContext.GetCurrentConfigIds(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/SugarUnitOfWork.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/SugarUnitOfWork.cs new file mode 100644 index 000000000..e606ee6c8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/SugarUnitOfWork.cs @@ -0,0 +1,109 @@ +using System.Reflection; + +namespace SqlSugar +{ + public interface ISugarUnitOfWork where T : SugarUnitOfWork, new() + { + ISqlSugarClient Db { get; set; } + T CreateContext(bool isTran = true); + } + public class SugarUnitOfWork : ISugarUnitOfWork where T : SugarUnitOfWork, new() + { + public SugarUnitOfWork(ISqlSugarClient db) + { + this.Db = db; + } + public ISqlSugarClient Db { get; set; } + public T CreateContext(bool isTran = true) + { + return Db.CreateContext(isTran); + } + } + public interface ISugarUnitOfWorkClear + { + RepositoryType GetMyRepository() where RepositoryType : new(); + + bool Commit(); + } + /// + /// ISugarUnitOfWorkClear not exists SqlSugar method + /// ISugarUnitOfWork exists SqlSugar method + /// + public interface ISugarUnitOfWork : ISugarUnitOfWorkClear + { + ISqlSugarClient Db { get; } + ITenant Tenant { get; } + + SimpleClient GetRepository() where T : class, new(); + } + /// + /// SugarUnitOfWork->ISugarUnitOfWork->ISaugarUnitOfWorkClear + /// ISaugarUnitOfWorkClear not exists SqlSugar method + /// ISugarUnitOfWork exists SqlSugar method + /// + public class SugarUnitOfWork : IDisposable, ISugarUnitOfWork + { + public ISqlSugarClient Db { get; internal set; } + public ITenant Tenant { get; internal set; } + public bool IsTran { get; internal set; } + public bool IsCommit { get; internal set; } + public bool IsClose { get; internal set; } + + public void Dispose() + { + + if (this.IsTran && IsCommit == false) + { + this.Tenant.RollbackTran(); + } + if (this.Db.Ado.Transaction == null && IsClose == false) + { + this.Db.Close(); + } + } + + public SimpleClient GetRepository() where T : class, new() + { + TenantAttribute tenantAttribute = typeof(T).GetCustomAttribute(); + if (tenantAttribute == null) + { + return new SimpleClient(Db); + } + else + { + return new SimpleClient(Db.AsTenant().GetConnection(tenantAttribute.configId)); + } + } + + public RepositoryType GetMyRepository() where RepositoryType : new() + { + var result = (ISugarRepository)new RepositoryType(); + var type = typeof(RepositoryType).GetGenericArguments().FirstOrDefault(); + TenantAttribute tenantAttribute = type?.GetCustomAttribute(); + if (tenantAttribute == null) + { + result.Context = this.Db; + } + else + { + result.Context = this.Db.AsTenant().GetConnection(tenantAttribute.configId); + } + return (RepositoryType)result; + } + + public bool Commit() + { + if (this.IsTran && this.IsCommit == false) + { + this.Tenant.CommitTran(); + IsCommit = true; + } + if (this.Db.Ado.Transaction == null && this.IsClose == false) + { + this.Db.Close(); + IsClose = true; + } + return IsCommit; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CallContext.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CallContext.cs new file mode 100644 index 000000000..69c3e3e2d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CallContext.cs @@ -0,0 +1,8 @@ +namespace SqlSugar +{ + internal static class CallContext + { + public static ThreadLocal> ContextList = new ThreadLocal>(); + public static ThreadLocal> MapperExpression = new ThreadLocal>(); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CallContextAsync.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CallContextAsync.cs new file mode 100644 index 000000000..f47a0a89a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CallContextAsync.cs @@ -0,0 +1,22 @@ +using System.Collections.Concurrent; + +namespace SqlSugar +{ + public static class CallContextAsync + { + static ConcurrentDictionary> state = new ConcurrentDictionary>(); + public static void SetData(string name, T data) => + state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; + public static T GetData(string name) => + state.TryGetValue(name, out AsyncLocal data) ? data.Value : default(T); + } + + public static class CallContextThread + { + static ConcurrentDictionary> state = new ConcurrentDictionary>(); + public static void SetData(string name, T data) => + state.GetOrAdd(name, _ => new ThreadLocal()).Value = data; + public static T GetData(string name) => + state.TryGetValue(name, out ThreadLocal data) ? data.Value : default(T); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/Check.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/Check.cs new file mode 100644 index 000000000..52f63f25f --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/Check.cs @@ -0,0 +1,43 @@ +using System.Text; +namespace SqlSugar +{ + public static class Check + { + public static void ThrowNotSupportedException(string message) + { + message = message.IsNullOrEmpty() ? new NotSupportedException().Message : message; + throw new SqlSugarException("SqlSugarException.NotSupportedException:" + message); + } + + public static void ArgumentNullException(object checkObj, string message) + { + if (checkObj == null) + throw new SqlSugarException("SqlSugarException.ArgumentNullException:" + message); + } + + public static void ArgumentNullException(object[] checkObj, string message) + { + if (checkObj == null || checkObj.Length == 0) + throw new SqlSugarException("SqlSugarException.ArgumentNullException:" + message); + } + public static void Exception(bool isException, CompositeFormat compositeFormat, params string[] args) + { + if (isException) + throw new SqlSugarException(string.Format(null, compositeFormat, args)); + } + public static void Exception(bool isException, string message, params string[] args) + { + if (isException) + throw new SqlSugarException(string.Format(message, args)); + } + public static void ExceptionEasy(string enMessage, string cnMessage) + { + throw new SqlSugarException(ErrorMessage.GetThrowMessage(enMessage, cnMessage)); + } + public static void ExceptionEasy(bool isException, string enMessage, string cnMessage) + { + if (isException) + throw new SqlSugarException(ErrorMessage.GetThrowMessage(enMessage, cnMessage)); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CommonExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CommonExtensions.cs new file mode 100644 index 000000000..c4b0f90a6 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/CommonExtensions.cs @@ -0,0 +1,156 @@ +using System.Reflection; + +namespace SqlSugar +{ + public static class CommonExtensions + { + + public static string GetNonNegativeHashCodeString(this string input) + { + // 获取哈希码,然后取绝对值,转换为字符串 + string hashCode = "hs" + Math.Abs(input.GetHashCode()); + return hashCode; + } + public static string SafeSubstring(this string str, int startIndex, int length) + { + if (str == null) + { + throw new ArgumentNullException(nameof(str)); + } + + if (startIndex < 0) + { + startIndex = 0; + } + + if (startIndex >= str.Length) + { + return string.Empty; // 返回空字符串,因为起始索引超过字符串长度 + } + + if (length < 0) + { + length = 0; + } + + // 截取字符串时,确保不超过字符串的长度 + return str.Substring(startIndex, Math.Min(length, str.Length - startIndex)); + } + public static Dictionary ToDictionary(this List list, string keyPropertyName, string valuePropertyName) + { + var keyProperty = typeof(T).GetProperty(keyPropertyName); + var valueProperty = typeof(T).GetProperty(valuePropertyName); + + return list.ToDictionary( + item => keyProperty.GetValue(item) + "", + item => valueProperty.GetValue(item) + ); + } + public static MethodInfo GetMyMethod(this Type type, string name, int argCount) + { + return type.GetMethods().FirstOrDefault(it => it.Name == name && it.GetParameters().Length == argCount); + } + public static MethodInfo GetMyMethod(this Type type, string name, int argCount, Type parameterType) + { + return type.GetMethods().FirstOrDefault(it => + it.Name == name && + it.GetParameters().Length == argCount && + it.GetParameters().First().ParameterType == parameterType); + } + public static MethodInfo GetMyMethod(this Type type, string name, int argCount, bool isList) + { + var methods = type.GetMethods().Where(it => it.Name == name).Where(it => + it.GetParameters().Length == argCount && + it.GetParameters()[0].ToString().Contains("List`") == isList).ToList(); + return methods.First(); + } + + public static MethodInfo GetMyMethod(this Type type, string name, int argCount, Type parameterType, Type parameterType2) + { + return type.GetMethods().Where(it => it.Name == name).FirstOrDefault(it => + it.GetParameters().Length == argCount && + it.GetParameters().First().ParameterType == parameterType && + it.GetParameters()[1].ParameterType == parameterType2); + } + + public static MethodInfo GetMyMethodNoGen(this Type type, string name, int argCount, Type parameterType, Type parameterType2) + { + return type.GetMethods().Where(it => it.Name == name && it?.GetGenericArguments()?.Length == 0).FirstOrDefault(it => + it.GetParameters().Length == argCount && + it.GetParameters().First().ParameterType == parameterType && + it.GetParameters()[1].ParameterType == parameterType2); + } + public static MethodInfo GetMyMethod(this Type type, string name, int argCount, Type parameterType, Type parameterType2, Type parameterType3) + { + return type.GetMethods().Where(it => it.Name == name).FirstOrDefault(it => + it.GetParameters().Length == argCount && + it.GetParameters().First().ParameterType == parameterType && + it.GetParameters()[1].ParameterType == parameterType2 && + it.GetParameters()[2].ParameterType == parameterType3); + } + public static MethodInfo GetMyMethod(this Type type, string name, int argCount, Type parameterType, Type parameterType2, Type parameterType3, Type parameterType4) + { + return type.GetMethods().Where(it => it.Name == name).FirstOrDefault(it => + it.GetParameters().Length == argCount && + it.GetParameters().First().ParameterType == parameterType && + it.GetParameters()[1].ParameterType == parameterType2 && + it.GetParameters()[2].ParameterType == parameterType3 && + it.GetParameters()[3].ParameterType == parameterType4); + } + public static MethodInfo GetMyMethod(this Type type, string name, int argCount, Type parameterType, Type parameterType2, Type parameterType3, Type parameterType4, Type parameterType5) + { + return type.GetMethods().Where(it => it.Name == name).FirstOrDefault(it => + it.GetParameters().Length == argCount && + it.GetParameters().First().ParameterType == parameterType && + it.GetParameters()[1].ParameterType == parameterType2 && + it.GetParameters()[2].ParameterType == parameterType3 && + it.GetParameters()[3].ParameterType == parameterType4 && + it.GetParameters()[4].ParameterType == parameterType5); + } + public static List ToList(this T thisValue, Func action) where T : class, new() + { + return new List { thisValue }; + } + public static List ToList(this IEnumerable thisValue, Func action) where T : class, new() + { + return thisValue.ToList(); + } + public static IEnumerable WhereIF(this IEnumerable thisValue, bool isOk, Func predicate) + { + if (isOk) + { + return thisValue.Where(predicate); + } + else + { + return thisValue; + } + } + public static IEnumerable MappingField(this IEnumerable thisValue, Func leftField, Func rightField) + { + return thisValue; + } + public static List MappingField(this T thisValue, Func leftField, Func rightField) where T : class + { + return new List() { thisValue }; + } + public static bool Any(this IEnumerable thisValue, List conditionalModels) + { + throw new Exception("Can only be used in expressions"); + } + public static IEnumerable Where(this IEnumerable thisValue, List conditionalModels) + { + throw new Exception("Can only be used in expressions"); + } + } +} +namespace System.Collections.Generic +{ + public static class EnumerableExtensions + { + public static bool Contains(this IEnumerable thisValue, T likeKey, bool isNvarchar) + { + return thisValue.Contains(likeKey); + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/DataTableExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/DataTableExtensions.cs new file mode 100644 index 000000000..b3901f5b1 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/DataTableExtensions.cs @@ -0,0 +1,125 @@ +using System.Data; +using System.Dynamic; +using System.Linq.Expressions; + +namespace SqlSugar +{ + internal static class DataTableExtensions + { + public static DataTable ToPivotTable( + this IEnumerable source, + Func columnSelector, + Expression> rowSelector, + Func, TData> dataSelector) + { + + DataTable table = new DataTable(); + + var rowName = new List(); + var memberName = string.Empty; + if (rowSelector.Body is MemberExpression) + { + memberName = ((MemberExpression)rowSelector.Body).Member.Name; + rowName.Add(memberName); + } + else + rowName.AddRange(((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.Member.Name)); + + + table.Columns.AddRange(rowName.Select(x => new DataColumn(x)).ToArray()); + var columns = source.Select(columnSelector).Distinct(); + table.Columns.AddRange(columns.Select(x => new DataColumn(x?.ToString())).ToArray()); + + Action> action; + if (string.IsNullOrEmpty(memberName)) + { + action = (row, rowGroup) => + { + var properties = rowGroup.Key.GetType().GetProperties(); + foreach (var item in properties) + row[item.Name] = item.GetValue(rowGroup.Key, null); + }; + } + else + { + action = (row, rowGroup) => row[memberName] = rowGroup.Key; + } + + var rows = source.GroupBy(rowSelector.Compile()) + .Select(rowGroup => + { + var row = table.NewRow(); + action(row, rowGroup); + foreach (var x in columns.GroupJoin(rowGroup, c => c, r => columnSelector(r), + (c, columnGroup) => + { + var dic = new Dictionary(); + if (c != null) + dic[c.ToString()] = dataSelector(columnGroup); + return dic; + }) + .SelectMany(x => x)) + { + row[x.Key] = x.Value; + } + table.Rows.Add(row); + return row; + }) + .ToList(); + + return table; + } + + public static IEnumerable ToPivotList( + this IEnumerable source, + Func columnSelector, + Expression> rowSelector, + Func, TData> dataSelector) + { + + var memberName = string.Empty; + + if (rowSelector.Body is MemberExpression) + memberName = ((MemberExpression)rowSelector.Body).Member.Name; + + var columns = source.Select(columnSelector).Distinct(); + + Action, IGrouping> action; + if (string.IsNullOrEmpty(memberName)) + { + action = (row, rowGroup) => + { + var properties = rowGroup.Key.GetType().GetProperties(); + foreach (var item in properties) + row[item.Name] = item.GetValue(rowGroup.Key, null); + }; + } + else + { + action = (row, rowGroup) => row[memberName] = rowGroup.Key; + } + + var rows = source.GroupBy(rowSelector.Compile()) + .Select(rowGroup => + { + IDictionary row = new ExpandoObject(); + action(row, rowGroup); + foreach (var x in columns.GroupJoin(rowGroup, c => c, r => columnSelector(r), + (c, columnGroup) => + { + var dic = new Dictionary(); + if (c != null) + dic[c.ToString()] = dataSelector(columnGroup); + return dic; + }) + .SelectMany(x => x)) + { + row[x.Key] = x.Value; + } + return row; + }); + return rows; + + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/DbExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/DbExtensions.cs new file mode 100644 index 000000000..7de50e166 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/DbExtensions.cs @@ -0,0 +1,172 @@ +using System.Text.RegularExpressions; +namespace SqlSugar +{ + public static class DbExtensions + { + public static string ToJoinSqlInVals(this T[] array) + { + if (array == null || array.Length == 0) + { + return ToSqlValue(string.Empty); + } + else + { + return string.Join(",", array.Where(c => c != null).Select(it => it.ToSqlValue())); + } + } + public static string ToJoinSqlInValsByVarchar(this T[] array) + { + if (array == null || array.Length == 0) + { + return ToSqlValue(string.Empty); + } + else + { + return string.Join(",", array.Where(c => c != null).Select(it => "N" + it.ToSqlValue())); + } + } + public static string ToJoinSqlInValsN(this T[] array) + { + if (array == null || array.Length == 0) + { + return ToSqlValue(string.Empty); + } + else + { + return string.Join(",", array.Where(c => c != null).Select(it => "N" + it.ToSqlValue())); + } + } + public static string ToSqlValue(this object value) + { + if (value != null && UtilConstants.NumericalTypes.Contains(value.GetType())) + return value.ToString(); + + var str = value + ""; + return str.ToSqlValue(); + } + + public static string ToSqlValue(this string value) + { + return string.Format("'{0}'", value.ToSqlFilter()); + } + + /// + ///Sql Filter + /// + /// + /// + public static string ToSqlFilter(this string value) + { + if (!value.IsNullOrEmpty()) + { + var oldLength = value.Length; + value = value.Replace("'", "''"); + if (oldLength != value.Length && value.IndexOf(')') > 0 && value.IndexOf(@"\''") > 0) value = value.Replace("\\", "\\\\"); + } + return value; + } + + /// + /// Check field format + /// + /// + /// + public static string ToCheckField(this string value) + { + //You can override it because the default security level is very high + if (StaticConfig.Check_FieldFunc != null) + { + return StaticConfig.Check_FieldFunc(value); + } + + //Default method + else if (value != null) + { + if (value.IsContainsIn(";", "--")) + { + throw new Exception($"{value} format error "); + } + else if (value.IsContainsIn("//") && (value.Length - value.Replace("/", "").Length) >= 4) + { + throw new Exception($"{value} format error "); + } + else if (value.IsContainsIn('\'') && (value.Length - value.Replace("'", "").Length) % 2 != 0) + { + throw new Exception($"{value} format error "); + } + else if (IsUpdateSql(value, "/", "/")) + { + Check.ExceptionEasy($"{value} format error ", value + "不能存在 /+【update drop 等】+/ "); + } + else if (IsUpdateSql(value, "/", " ")) + { + Check.ExceptionEasy($"{value} format error ", value + "不能存在 /+【update drop 等】+空格 "); + } + else if (IsUpdateSql(value, " ", "/")) + { + Check.ExceptionEasy($"{value} format error ", value + "不能存在 空格+【update drop 等】+/ "); + } + else if (value.Contains(" update ", StringComparison.CurrentCultureIgnoreCase) + || value.Contains(" delete ", StringComparison.CurrentCultureIgnoreCase) + || value.Contains(" drop ", StringComparison.CurrentCultureIgnoreCase) + || value.Contains(" alert ", StringComparison.CurrentCultureIgnoreCase) + || value.Contains(" create ", StringComparison.CurrentCultureIgnoreCase) + || value.Contains(" insert ", StringComparison.CurrentCultureIgnoreCase)) + { + Check.ExceptionEasy($"{value} format error ", value + "不能存在 空格+【update drop 等】+空格 "); + } + } + return value; + } + + private static bool IsUpdateSql(string value, string left, string right) + { + return value.Contains(left + "update" + right, StringComparison.CurrentCultureIgnoreCase) + || value.Contains(left + "delete" + right, StringComparison.CurrentCultureIgnoreCase) + || value.Contains(left + "drop" + right, StringComparison.CurrentCultureIgnoreCase) + || value.Contains(left + "alert" + right, StringComparison.CurrentCultureIgnoreCase) + || value.Contains(left + "create" + right, StringComparison.CurrentCultureIgnoreCase) + || value.Contains(left + "insert" + right, StringComparison.CurrentCultureIgnoreCase); + } + public static bool ContainsChinese(string input) + { + // 正则表达式:匹配包含至少一个中文字符的字符串 + string pattern = @"[\u4e00-\u9fa5]"; + return Regex.IsMatch(input, pattern); + } + public static bool IsRegexWNoContainsChinese(this string value) + { + if (!ContainsChinese(value) && Regex.IsMatch(value, @"^\w+$")) + { + return true; + } + else + { + return false; + } + } + public static string ToCheckRegexW(this string value) + { + if (Regex.IsMatch(value, @"^\w+$")) + { + return value; + } + else + { + throw new Exception($"ToCheckRegexW {value} format error "); + } + } + internal static string ToLower(this string value, bool isAutoToLower) + { + if (value == null) return null; + if (isAutoToLower == false) return value; + return value.ToLower(); + } + internal static string ToUpper(this string value, bool isAutoToUpper) + { + if (value == null) return null; + if (isAutoToUpper == false) return value; + return value.ToUpper(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ErrorMessage.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ErrorMessage.cs new file mode 100644 index 000000000..0661bd2a4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ErrorMessage.cs @@ -0,0 +1,45 @@ +using System.Text; +namespace SqlSugar +{ + internal static partial class ErrorMessage + { + internal static LanguageType SugarLanguageType { get; set; } = LanguageType.Chinese; + + internal static CompositeFormat ObjNotExistCompositeFormat => SugarLanguageType == LanguageType.English ? privateEObjNotExistCompositeFormat : privateCObjNotExistCompositeFormat; + private static readonly CompositeFormat privateEObjNotExistCompositeFormat = CompositeFormat.Parse("{0} does not exist."); + private static readonly CompositeFormat privateCObjNotExistCompositeFormat = CompositeFormat.Parse("{0}不存在。"); + + internal static CompositeFormat EntityMappingErrorCompositeFormat => SugarLanguageType == LanguageType.English ? privateEEntityMappingErrorCompositeFormat : privateCEntityMappingErrorCompositeFormat; + private static readonly CompositeFormat privateEEntityMappingErrorCompositeFormat = CompositeFormat.Parse("Entity mapping error.{0}"); + private static readonly CompositeFormat privateCEntityMappingErrorCompositeFormat = CompositeFormat.Parse("Select 实体与表映射出错,可以注释实体类中的字段排查具体哪一个字段。【注意:如果用CodeFirt先配置禁止删列或更新】 {0}"); + + internal static CompositeFormat NotSupportedDictionaryCompositeFormat => SugarLanguageType == LanguageType.English ? privateENotSupportedDictionaryCompositeFormat : privateCNotSupportedDictionaryCompositeFormat; + private static readonly CompositeFormat privateENotSupportedDictionaryCompositeFormat = CompositeFormat.Parse("This type of Dictionary is not supported for the time being. You can try Dictionary, or contact the author!"); + private static readonly CompositeFormat privateCNotSupportedDictionaryCompositeFormat = CompositeFormat.Parse("暂时不支持该类型的Dictionary 你可以试试 Dictionary或者联系作者!"); + + internal static CompositeFormat NotSupportedArrayCompositeFormat => SugarLanguageType == LanguageType.English ? privateENotSupportedArrayCompositeFormat : privateCNotSupportedArrayCompositeFormat; + private static readonly CompositeFormat privateENotSupportedArrayCompositeFormat = CompositeFormat.Parse("This type of Array is not supported for the time being. You can try object[] or contact the author!"); + private static readonly CompositeFormat privateCNotSupportedArrayCompositeFormat = CompositeFormat.Parse("暂时不支持该类型的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/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ExpressionBuilderHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ExpressionBuilderHelper.cs new file mode 100644 index 000000000..5f85e96e8 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ExpressionBuilderHelper.cs @@ -0,0 +1,205 @@ +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; + +namespace SqlSugar +{ + public static class ExpressionBuilderHelper + { + public static object CallFunc(Type type, object[] param, object methodData, string methodName) + { + MethodInfo mi = methodData.GetType().GetMethod(methodName).MakeGenericMethod(new Type[] { type }); + var ret = mi.Invoke(methodData, param); + return ret; + } + public static T CallFunc(object param, object methodData, string methodName) + { + Type type = param.GetType(); + MethodInfo mi = methodData.GetType().GetMethod(methodName).MakeGenericMethod(new Type[] { type }); + var ret = mi.Invoke(methodData, new object[] { param }); + return (T)ret; + } + + public static T CallStaticFunc(object param, Type methodType, string methodName) + { + Type type = param.GetType(); + MethodInfo mi = methodType.GetMethod(methodName).MakeGenericMethod(new Type[] { type }); + var ret = mi.Invoke(null, new object[] { param }); + return (T)ret; + } + /// + /// Create Expression + /// + public static Expression CreateExpression(Expression left, Expression value, ExpressionType type) + { + + if (type == ExpressionType.Equal) + { + return Expression.Equal(left, Expression.Convert(value, left.Type)); + } + else if (type == ExpressionType.NotEqual) + { + return Expression.NotEqual(left, Expression.Convert(value, left.Type)); + } + else + { + //Not implemented, later used in writing + return Expression.Equal(left, Expression.Convert(value, left.Type)); + } + } + public static Expression CreateExpressionLike(Type entityType, string propertyName, List list) + { + var parameter = Expression.Parameter(entityType, "p"); + MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName); + MethodInfo method = typeof(List<>).MakeGenericType(typeof(ColumnType)).GetMethod("Contains"); + ConstantExpression constantCollection = Expression.Constant(list); + + MethodCallExpression methodCall = Expression.Call(constantCollection, method, memberProperty); + + var expression = Expression.Lambda(methodCall, parameter); + return expression; + } + public static Expression> CreateNewFields(EntityInfo entity, List propertyNames) + { + Type sourceType = typeof(T); + Dictionary sourceProperties = entity.Columns.Where(it => propertyNames.Contains(it.PropertyName)).ToDictionary(it => it.PropertyName, it => it.PropertyInfo); + + + if (StaticConfig.EnableAot) + { + Type dynamicType = typeof(T); + + ParameterExpression sourceItem = Expression.Parameter(sourceType, "t"); + IEnumerable bindings = dynamicType.GetProperties().Where(it => sourceProperties.Any(s => s.Key == it.Name)).Select(p => Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType(); + + return Expression.Lambda>(Expression.MemberInit( + Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem); + } + else + { + + + Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(sourceProperties.Values); + + ParameterExpression sourceItem = Expression.Parameter(sourceType, "t"); + IEnumerable bindings = dynamicType.GetRuntimeProperties().Select(p => Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType(); + + return Expression.Lambda>(Expression.MemberInit( + Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem); + } + } + public static Expression CreateExpressionSelectField(Type classType, string propertyName, Type propertyType, string shortName = "it") + { + ParameterExpression parameter = Expression.Parameter(classType, shortName); + + // 创建属性表达式 + PropertyInfo propertyInfo = classType.GetProperty(propertyName); + MemberExpression property = Expression.Property(parameter, propertyInfo); + + // 创建Lambda表达式 + Type funcType = typeof(Func<,>).MakeGenericType(classType, propertyType); + LambdaExpression lambda = Expression.Lambda(funcType, property, parameter); + return lambda; + } + public static Expression CreateExpressionSelectFieldObject(Type classType, string propertyName) + { + ParameterExpression parameter = Expression.Parameter(classType, "it"); + + + PropertyInfo propertyInfo = classType.GetProperty(propertyName); + MemberExpression property = Expression.Property(parameter, propertyInfo); + + UnaryExpression convert = Expression.Convert(property, typeof(object)); + var funcType = typeof(Func<,>).MakeGenericType(classType, typeof(object)); + LambdaExpression lambda = Expression.Lambda(funcType, convert, parameter); + return lambda; + } + } + internal static class LinqRuntimeTypeBuilder + { + private static readonly AssemblyName AssemblyName = new AssemblyName() { Name = "LinqRuntimeTypes4iTheoChan" }; + private static readonly ModuleBuilder ModuleBuilder; + private static readonly Dictionary BuiltTypes = new Dictionary(); + + static LinqRuntimeTypeBuilder() + { + ModuleBuilder = AssemblyBuilder.DefineDynamicAssembly(AssemblyName, AssemblyBuilderAccess.Run).DefineDynamicModule(AssemblyName.Name); + } + + private static string GetTypeKey(Dictionary properties) + { + //TODO: optimize the type caching -- if fields are simply reordered, that doesn't mean that they're actually different types, so this needs to be smarter + string key = string.Empty; + foreach (var prop in properties) + key += prop.Key + ";" + prop.Value.Name + ";"; + + return key; + } + + private const MethodAttributes RuntimeGetSetAttrs = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; + + public static Type BuildDynamicType(Dictionary properties) + { + if (null == properties) + throw new ArgumentNullException(nameof(properties)); + if (0 == properties.Count) + throw new ArgumentOutOfRangeException(nameof(properties), "fields must have at least 1 field definition"); + + try + { + // Acquires an exclusive lock on the specified object. + Monitor.Enter(BuiltTypes); + string className = GetTypeKey(properties); + + if (BuiltTypes.TryGetValue(className, out Type? value)) + return value; + + TypeBuilder typeBdr = ModuleBuilder.DefineType(className, TypeAttributes.Public | TypeAttributes.Class); + + foreach (var prop in properties) + { + var propertyBdr = typeBdr.DefineProperty(name: prop.Key, attributes: PropertyAttributes.None, returnType: prop.Value, parameterTypes: null); + var fieldBdr = typeBdr.DefineField("itheofield_" + prop.Key, prop.Value, FieldAttributes.Private); + + MethodBuilder getMethodBdr = typeBdr.DefineMethod("get_" + prop.Key, RuntimeGetSetAttrs, prop.Value, Type.EmptyTypes); + ILGenerator getIL = getMethodBdr.GetILGenerator(); + getIL.Emit(OpCodes.Ldarg_0); + getIL.Emit(OpCodes.Ldfld, fieldBdr); + getIL.Emit(OpCodes.Ret); + + MethodBuilder setMethodBdr = typeBdr.DefineMethod("set_" + prop.Key, RuntimeGetSetAttrs, null, new Type[] { prop.Value }); + ILGenerator setIL = setMethodBdr.GetILGenerator(); + setIL.Emit(OpCodes.Ldarg_0); + setIL.Emit(OpCodes.Ldarg_1); + setIL.Emit(OpCodes.Stfld, fieldBdr); + setIL.Emit(OpCodes.Ret); + + propertyBdr.SetGetMethod(getMethodBdr); + propertyBdr.SetSetMethod(setMethodBdr); + } + + BuiltTypes[className] = typeBdr.CreateType(); + + return BuiltTypes[className]; + } + catch + { + throw; + } + finally + { + Monitor.Exit(BuiltTypes); + } + } + + private static string GetTypeKey(IEnumerable properties) + { + return GetTypeKey(properties.ToDictionary(f => f.Name, f => f.PropertyType)); + } + + public static Type GetDynamicType(IEnumerable properties) + { + return BuildDynamicType(properties.ToDictionary(f => f.Name, f => f.PropertyType)); + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/FastCopy.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/FastCopy.cs new file mode 100644 index 000000000..1fd00a6c3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/FastCopy.cs @@ -0,0 +1,128 @@ +using System.Collections.Concurrent; +using System.Linq.Expressions; +using System.Reflection; + +using static System.Linq.Expressions.Expression; + +namespace SqlSugar +{ + internal static class FastCopy + { + static ConcurrentDictionary copiers = new ConcurrentDictionary(); + + /// + /// 复制两个对象同名属性值 + /// + /// + /// + /// 源对象 + /// 目标对象 + /// 源对象属性值为null时,是否将值复制给目标对象 + public static void Copy(S source, T target, bool copyNull = true) + { + string name = string.Format("{0}_{1}_{2}", typeof(S), typeof(T), copyNull); + + object targetCopier; + if (!copiers.TryGetValue(name, out targetCopier)) + { + Action copier = CreateCopier(copyNull); + copiers.TryAdd(name, copier); + targetCopier = copier; + } + + Action action = (Action)targetCopier; + action(source, target); + } + + /// + /// 为指定的两种类型编译生成属性复制委托 + /// + /// + /// + /// 源对象属性值为null时,是否将值复制给目标对象 + /// + private static Action CreateCopier(bool copyNull) + { + ParameterExpression source = Parameter(typeof(S)); + ParameterExpression target = Parameter(typeof(T)); + var sourceProps = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead).ToList(); + var targetProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanWrite).ToList(); + + // 查找可进行赋值的属性 + var copyProps = targetProps.Where(tProp => sourceProps.Where(sProp => sProp.Name == tProp.Name// 名称一致 且 + && ( + sProp.PropertyType == tProp.PropertyType// 属性类型一致 或 + || sProp.PropertyType.IsAssignableFrom(tProp.PropertyType) // 源属性类型 为 目标属性类型 的 子类;eg:object target = string source; 或 + || (tProp.PropertyType.IsValueType && sProp.PropertyType.IsValueType && // 属性为值类型且基础类型一致,但目标属性为可空类型 eg:int? num = int num; + ((tProp.PropertyType.GenericTypeArguments.Length > 0 ? tProp.PropertyType.GenericTypeArguments[0] : tProp.PropertyType) == sProp.PropertyType)) + )).Any()); + + List expressionList = new List(); + foreach (var prop in copyProps) + { + if (prop.PropertyType.IsValueType)// 属性为值类型 + { + PropertyInfo sProp = typeof(S).GetProperty(prop.Name); + PropertyInfo tProp = typeof(T).GetProperty(prop.Name); + if (sProp.PropertyType == tProp.PropertyType)// 属性类型一致 eg:int num = int num; 或 int? num = int? num; + { + var assign = Assign(Property(target, prop.Name), Property(source, prop.Name)); + expressionList.Add(assign); + } + else if (sProp.PropertyType.GenericTypeArguments.Length <= 0 && tProp.PropertyType.GenericTypeArguments.Length > 0)// 属性类型不一致且目标属性类型为可空类型 eg:int? num = int num; + { + var convert = Convert(Expression.Property(source, prop.Name), tProp.PropertyType); + var cvAssign = Assign(Expression.Property(target, prop.Name), convert); + expressionList.Add(cvAssign); + } + } + else// 属性为引用类型 + { + var assign = Assign(Property(target, prop.Name), Property(source, prop.Name));// 编译生成属性赋值语句 target.{PropertyName} = source.{PropertyName}; + var sourcePropIsNull = Equal(Constant(null, prop.PropertyType), Property(source, prop.Name));// 判断源属性值是否为Null;编译生成 source.{PropertyName} == null + var setNull = IsTrue(Constant(copyNull));// 判断是否复制Null值 编译生成 copyNull == True + var setNullTest = IfThen(setNull, assign); + var condition = IfThenElse(sourcePropIsNull, setNullTest, assign); + + /* + * 编译生成 + * if(source.{PropertyName} == null) + * { + * if(setNull) + * { + * target.{PropertyName} = source.{PropertyName}; + * } + * } + * else + * { + * target.{PropertyName} = source.{PropertyName}; + * } + */ + expressionList.Add(condition); + } + } + var block = Block(expressionList.ToArray()); + Expression> lambda = Lambda>(block, source, target); + return lambda.Compile(); + } + + internal static List GetDiff(T item, T trackingData) where T : class, new() + { + List result = new List(); + foreach (var t in typeof(T).GetProperties()) + { + var leftvalue = t.GetValue(item); + var rightvalue = t.GetValue(trackingData); + if ((leftvalue == null && rightvalue != null)) + { + result.Add(t.Name); + } + else if (leftvalue?.Equals(rightvalue) == false) + { + result.Add(t.Name); + } + } + return result; + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/FileHelper.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/FileHelper.cs new file mode 100644 index 000000000..6855d872b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/FileHelper.cs @@ -0,0 +1,69 @@ +using System.Text; + +namespace SqlSugar +{ + internal static 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); + + //Create File + FileInfo file = new FileInfo(filePath); + using (FileStream stream = file.Create()) + { + using (StreamWriter writer = new StreamWriter(stream, encoding)) + { + writer.Write(text); + writer.Flush(); + } + } + } + } + catch (Exception) + { + throw; + } + } + public static bool IsExistDirectory(string directoryPath) + { + return Directory.Exists(directoryPath); + } + public static void CreateDirectory(string directoryPath) + { + if (!IsExistDirectory(directoryPath)) + { + if (!string.IsNullOrEmpty(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) + { + return File.Exists(filePath); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/PropertyCallAdapterProvider.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/PropertyCallAdapterProvider.cs new file mode 100644 index 000000000..b40e78603 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/PropertyCallAdapterProvider.cs @@ -0,0 +1,76 @@ +using System.Reflection; +namespace SqlSugar +{ + public interface IPropertyCallAdapter + { + object InvokeGet(TThis @this); + //add void InvokeSet(TThis @this, object value) if necessary + } + public class PropertyCallAdapter : IPropertyCallAdapter + { + private readonly Func _getterInvocation; + + public PropertyCallAdapter(Func getterInvocation) + { + _getterInvocation = getterInvocation; + } + + public object InvokeGet(TThis @this) + { + return _getterInvocation.Invoke(@this); + } + } + public static class PropertyCallAdapterProvider + { + private static readonly System.Collections.Concurrent.ConcurrentDictionary> _instances = + new System.Collections.Concurrent.ConcurrentDictionary>(); + + public static IPropertyCallAdapter GetInstance(string forPropertyName) + { + IPropertyCallAdapter instance; + if (!_instances.TryGetValue(forPropertyName, out instance)) + { + PropertyInfo property = null; + var propertys = typeof(TThis).GetProperties( + + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(it => it.Name == forPropertyName); + if (propertys.Count() == 1) + { + property = propertys.First(); + } + else + { + property = propertys.First(); + } + + MethodInfo getMethod; + Delegate getterInvocation = null; + if (property != null && (getMethod = property.GetGetMethod(true)) != null) + { + var openGetterType = typeof(Func<,>); + var concreteGetterType = openGetterType + .MakeGenericType(typeof(TThis), property.PropertyType); + + getterInvocation = + Delegate.CreateDelegate(concreteGetterType, null, getMethod); + } + else + { + //throw exception or create a default getterInvocation returning null + } + + var openAdapterType = typeof(PropertyCallAdapter<,>); + var concreteAdapterType = openAdapterType + .MakeGenericType(typeof(TThis), property.PropertyType); + instance = Activator + .CreateInstance(concreteAdapterType, getterInvocation) + as IPropertyCallAdapter; + + _instances.GetOrAdd(forPropertyName, instance); + } + + return instance; + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ReflectionExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ReflectionExtensions.cs new file mode 100644 index 000000000..c55857dc2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ReflectionExtensions.cs @@ -0,0 +1,77 @@ +using System.Reflection; + +namespace SqlSugar +{ + + public static class ReflectionExtensions + { + public static Type GetTypeInfo(this Type typeInfo) + { + return typeInfo; + } + + public static Type[] GetGenericArguments(this Type type) + { + var reval = type.GetTypeInfo().GetGenericArguments(); + return reval; + } + public static bool IsGenericType(this Type type) + { + var reval = type.GetTypeInfo().IsGenericType; + return reval; + } + public static PropertyInfo[] GetProperties(this Type type) + { + var reval = type.GetTypeInfo().GetProperties(); + return reval; + } + public static PropertyInfo GetProperty(this Type type, string name) + { + var reval = type.GetTypeInfo().GetProperty(name); + return reval; + } + + public static FieldInfo GetField(this Type type, string name) + { + var reval = type.GetTypeInfo().GetField(name); + return reval; + } + + public static bool IsEnum(this Type type) + { + var reval = type.GetTypeInfo().IsEnum; + return reval; + } + + public static MethodInfo GetMethod(this Type type, string name) + { + var reval = type.GetTypeInfo().GetMethod(name); + return reval; + } + public static MethodInfo GetMethod(this Type type, string name, Type[] types) + { + var reval = type.GetTypeInfo().GetMethod(name, types); + return reval; + } + public static ConstructorInfo GetConstructor(this Type type, Type[] types) + { + var reval = type.GetTypeInfo().GetConstructor(types); + return reval; + } + + public static bool IsValueType(this Type type) + { + return type.GetTypeInfo().IsValueType; + } + + public static bool IsEntity(this Type type) + { + return type.GetTypeInfo().IsClass; + } + + public static Type ReflectedType(this MethodInfo method) + { + return method.ReflectedType; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/SugarAsyncLock.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/SugarAsyncLock.cs new file mode 100644 index 000000000..7e743282b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/SugarAsyncLock.cs @@ -0,0 +1,25 @@ +namespace SqlSugar +{ + public class SugarAsyncLock : IDisposable + { + static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1); + + + public SugarAsyncLock(SqlSugarProvider db) + { + + } + + public async Task AsyncLock(int timeOutSeconds) + { + TimeSpan timeout = TimeSpan.FromSeconds(timeOutSeconds); + await SemaphoreSlim.WaitAsync(timeout).ConfigureAwait(false); + return this; + } + + public void Dispose() + { + SemaphoreSlim.Release(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/SugarRetry.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/SugarRetry.cs new file mode 100644 index 000000000..4d54b8edd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/SugarRetry.cs @@ -0,0 +1,159 @@ +namespace SqlSugar +{ + public static class SugarRetry + { + + public static void Execute(Action action, TimeSpan retryInterval, int retryCount = 3) + { + Execute(() => + { + action(); + return null; + }, retryInterval, retryCount); + } + + + public static void Execute(Action action, T1 arg1, TimeSpan retryInterval, int retryCount = 3) + { + Execute((x1) => + { + action(arg1); + return null; + }, arg1, retryInterval, retryCount); + } + + + public static void Execute(Action action, T1 arg1, T2 arg2, TimeSpan retryInterval, int retryCount = 3) + { + Execute((x1, x2) => + { + action(arg1, arg2); + return null; + }, arg1, arg2, retryInterval, retryCount); + } + + + public static void Execute(Action action, T1 arg1, T2 arg2, T3 arg3, TimeSpan retryInterval, int retryCount = 3) + { + Execute((x1, x2, x3) => + { + action(arg1, arg2, arg3); + return null; + }, arg1, arg2, arg3, retryInterval, retryCount); + } + + + public static void Execute(Action action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, TimeSpan retryInterval, int retryCount = 3) + { + Execute((x1, x2, x3, x4) => + { + action(arg1, arg2, arg3, arg4); + return null; + }, arg1, arg2, arg3, arg4, retryInterval, retryCount); + } + + + public static T Execute(Func func, TimeSpan retryInterval, int retryCount = 3) + { + var exceptions = new List(); + + for (int retry = 0; retry < retryCount; retry++) + { + try + { + return func(); + } + catch (Exception ex) + { + exceptions.Add(ex); + Thread.Sleep(retryInterval); + } + } + + throw new AggregateException(exceptions); + } + + + public static T Execute(Func func, T1 arg1, TimeSpan retryInterval, int retryCount = 3) + { + var exceptions = new List(); + + for (int retry = 0; retry < retryCount; retry++) + { + try + { + return func(arg1); + } + catch (Exception ex) + { + exceptions.Add(ex); + Thread.Sleep(retryInterval); + } + } + + throw new AggregateException(exceptions); + } + + public static T Execute(Func func, T1 arg1, T2 arg2, TimeSpan retryInterval, int retryCount = 3) + { + var exceptions = new List(); + + for (int retry = 0; retry < retryCount; retry++) + { + try + { + return func(arg1, arg2); + } + catch (Exception ex) + { + exceptions.Add(ex); + Thread.Sleep(retryInterval); + } + } + + throw new AggregateException(exceptions); + } + + + public static T Execute(Func func, T1 arg1, T2 arg2, T3 arg3, TimeSpan retryInterval, int retryCount = 3) + { + var exceptions = new List(); + + for (int retry = 0; retry < retryCount; retry++) + { + try + { + return func(arg1, arg2, arg3); + } + catch (Exception ex) + { + exceptions.Add(ex); + Thread.Sleep(retryInterval); + } + } + + throw new AggregateException(exceptions); + } + + + public static T Execute(Func func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, TimeSpan retryInterval, int retryCount = 3) + { + var exceptions = new List(); + + for (int retry = 0; retry < retryCount; retry++) + { + try + { + return func(arg1, arg2, arg3, arg4); + } + catch (Exception ex) + { + exceptions.Add(ex); + Thread.Sleep(retryInterval); + } + } + + throw new AggregateException(exceptions); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilConstants.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilConstants.cs new file mode 100644 index 000000000..6abdfedee --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilConstants.cs @@ -0,0 +1,80 @@ +using System.Dynamic; +using System.Linq.Expressions; +namespace SqlSugar +{ + 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 static string ReplaceKey = "{" + Guid.NewGuid() + "}"; + internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + internal const string GroupReplaceKey = "{GroupReplaceKey_l33asdysaas1231s}"; + + internal static Type UShortType = typeof(ushort); + internal static Type ULongType = typeof(ulong); + internal static Type UIntType = typeof(uint); + internal static Type IntType = typeof(int); + internal static Type LongType = typeof(long); + internal static Type GuidType = typeof(Guid); + internal static Type BoolType = typeof(bool); + internal static Type BoolTypeNull = typeof(bool?); + internal static Type ByteType = typeof(Byte); + internal static Type SByteType = typeof(sbyte); + internal static Type ObjType = typeof(object); + internal static Type DobType = typeof(double); + internal static Type FloatType = typeof(float); + 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 SqlConvertType = typeof(SqlSugar.DbConvert.NoParameterCommonPropertyConvert); + + 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 CultureInfo EnCultureInfo = new CultureInfo("en"); + + internal static string[] DateTypeStringList = new string[] + { + "Year", + "Month", + "Day", + "Hour", + "Second" , + "Minute", + "Millisecond", + "Date" + }; + + public static ConstantExpression ExpTrue = Expression.Constant(true); + public static ConstantExpression ExpFalse = Expression.Constant(false); + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilConvert.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilConvert.cs new file mode 100644 index 000000000..168f2ab41 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilConvert.cs @@ -0,0 +1,192 @@ +using System.Linq.Expressions; +namespace SqlSugar +{ + internal static class UtilConvert + { + public static int ObjToInt(this object thisValue) + { + int reval = 0; + if (thisValue == null) return 0; + if (thisValue is Enum) + { + return Convert.ToInt32(thisValue); + } + if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return reval; + } + + public static long ObjToLong(this object thisValue) + { + long reval = 0; + if (thisValue == null) return 0; + if (thisValue is Enum) + { + return Convert.ToInt64(thisValue); + } + if (thisValue != null && thisValue != DBNull.Value && long.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 bool EqualCase(this string thisValue, string equalValue) + { + if (thisValue != null && equalValue != null) + { + return thisValue.Equals(equalValue, StringComparison.CurrentCultureIgnoreCase); + } + else + { + return thisValue == equalValue; + } + } + public static string ObjToString(this object thisValue, Func formatTime) + { + if (formatTime != null && thisValue is DateTime) + { + var dt = Convert.ToDateTime(thisValue); + return formatTime(dt); + } + else + { + return thisValue + string.Empty; + } + } + public static string ObjToString(this object thisValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return ""; + } + public static string ObjToStringNoTrim(this object thisValue) + { + if (thisValue != null) return thisValue.ToString(); + return ""; + } + public static string ObjToStringNew(this object thisValue) + { + if (thisValue != null && thisValue is byte[]) + { + return string.Join("|", thisValue as byte[]); + } + if (thisValue != null && thisValue?.GetType()?.Name == "DateOnly") + { + return Convert.ToDateTime(thisValue.ToString()).ToString("yyyy-MM-dd"); + } + if (thisValue != null) return thisValue.ToString().Trim(); + return ""; + } + + 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) + { + if (thisValue is DateTime) + { + return (DateTime)thisValue; + } + DateTime reval = DateTime.MinValue; + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) + { + reval = Convert.ToDateTime(thisValue); + } + return reval; + } + + public static DateTime ObjToDate(this object thisValue, DateTime errorValue) + { + if (thisValue is DateTime) + { + return (DateTime)thisValue; + } + 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; + } + + internal static MemberExpression ToMemberExpression(Expression parentIdExpression) + { + if (parentIdExpression is UnaryExpression) + { + return (parentIdExpression as UnaryExpression).Operand as MemberExpression; + } + else + { + return parentIdExpression as MemberExpression; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilExceptions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilExceptions.cs new file mode 100644 index 000000000..467ec11d4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilExceptions.cs @@ -0,0 +1,83 @@ +using System.Reflection; +namespace SqlSugar +{ + public class SqlSugarException : Exception + { + public string Sql { get; set; } + public object Parametres { get; set; } + public new Exception InnerException; + public new string StackTrace; + public new MethodBase TargetSite; + public new string Source; + + public SqlSugarException(string message) + : base(message) { } + + public SqlSugarException(SqlSugarProvider context, string message, string sql) + : base(message) + { + this.Sql = sql; + } + + public SqlSugarException(SqlSugarProvider context, string message, string sql, object pars) + : base(message) + { + this.Sql = sql; + this.Parametres = pars; + } + + public SqlSugarException(SqlSugarProvider context, Exception ex, string sql, object pars) + : base(ex.Message) + { + this.Sql = sql; + this.Parametres = pars; + this.InnerException = ex.InnerException; + this.StackTrace = ex.StackTrace; + this.TargetSite = ex.TargetSite; + this.Source = ex.Source; + } + + public SqlSugarException(SqlSugarProvider context, string message, object pars) + : base(message) + { + this.Parametres = pars; + } + + public SqlSugarException() : base() + { + } + + public SqlSugarException(string? message, Exception? innerException) : base(message, innerException) + { + } + } + public class VersionExceptions : SqlSugarException + { + public VersionExceptions(string message) + : base(message) { } + + public VersionExceptions(SqlSugarProvider context, string message, string sql) : base(context, message, sql) + { + } + + public VersionExceptions(SqlSugarProvider context, string message, string sql, object pars) : base(context, message, sql, pars) + { + } + + public VersionExceptions(SqlSugarProvider context, Exception ex, string sql, object pars) : base(context, ex, sql, pars) + { + } + + public VersionExceptions(SqlSugarProvider context, string message, object pars) : base(context, message, pars) + { + } + + public VersionExceptions() : base() + { + } + + public VersionExceptions(string? message, Exception? innerException) : base(message, innerException) + { + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilExtensions.cs new file mode 100644 index 000000000..4e76db6c9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilExtensions.cs @@ -0,0 +1,119 @@ +namespace SqlSugar.Extensions +{ + /// + ///Common Extensions for external users + /// + public static class UtilExtensions + { + 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 ""; + } + + 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)) + { + reval = Convert.ToDateTime(thisValue); + } + 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/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilMethods.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilMethods.cs new file mode 100644 index 000000000..67c1dbf77 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilMethods.cs @@ -0,0 +1,1954 @@ +using Dm.util; + +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; + +using ThingsGateway.NewLife; + +namespace SqlSugar +{ + public static class UtilMethods + { + public static DataTable ConvertDateTimeOffsetToDateTime(DataTable table) + { + if (!table.Columns.Cast().Any(it => it.DataType == typeof(DateTimeOffset))) + { + return table; + } + DataTable newTable = table.Clone(); + newTable.TableName = table.TableName; + // 替换所有 DateTimeOffset 列为 DateTime + foreach (DataColumn column in newTable.Columns) + { + if (column.DataType == typeof(DateTimeOffset)) + { + column.DataType = typeof(DateTime); // 会报错,不能直接改 + } + } + + // 需要重新构建新表结构 + DataTable finalTable = new DataTable(); + finalTable.TableName = table.TableName; + foreach (DataColumn column in table.Columns) + { + Type newType = column.DataType == typeof(DateTimeOffset) ? typeof(DateTime) : column.DataType; + finalTable.Columns.Add(column.ColumnName, newType); + } + + // 拷贝并转换数据 + foreach (DataRow row in table.Rows) + { + DataRow newRow = finalTable.NewRow(); + foreach (DataColumn column in table.Columns) + { + var value = row[column]; + if (value is DateTimeOffset dto) + newRow[column.ColumnName] = dto.DateTime; + else + newRow[column.ColumnName] = value; + } + finalTable.Rows.Add(newRow); + } + + return finalTable; + } + public static string EscapeLikeValue(ISqlSugarClient db, string value, char wildcard = '%') + { + var dbType = db.CurrentConnectionConfig.DbType; + if (db.CurrentConnectionConfig?.MoreSettings?.DatabaseModel != null) + { + dbType = db.CurrentConnectionConfig.MoreSettings.DatabaseModel.Value; + } + if (string.IsNullOrEmpty(value)) + return value; + + string wildcardStr = wildcard.ToString(); + + switch (dbType) + { + // 支持标准 SQL LIKE 转义,通常使用中括号 [] 或反斜杠 \ 进行转义 + case DbType.SqlServer: + case DbType.Access: + case DbType.Odbc: + case DbType.TDSQLForPGODBC: + // SQL Server 使用中括号转义 %, _ 等 + var keyLeft = "[[]"; + var keyRight = "[]]"; + var leftGuid = Guid.NewGuid().toString(); + var rightGuid = Guid.NewGuid().toString(); + value = value.Replace("[", leftGuid) + .Replace("]", rightGuid); + + value = value.Replace(leftGuid, keyLeft) + .Replace(rightGuid, keyRight); + value = value + .Replace(wildcardStr, $"[{wildcard}]"); + break; + + // PostgreSQL 风格数据库,使用反斜杠进行 LIKE 转义 + case DbType.PostgreSQL: + case DbType.OpenGauss: + case DbType.TDSQL: + case DbType.GaussDB: + case DbType.GaussDBNative: + // MySQL 和兼容库,使用反斜杠进行转义 + case DbType.MySql: + case DbType.MySqlConnector: + case DbType.Tidb: + case DbType.PolarDB: + case DbType.OceanBase: + case DbType.Oracle: + case DbType.OceanBaseForOracle: + case DbType.HG: + case DbType.Dm: + case DbType.GBase: + case DbType.DB2: + case DbType.HANA: + case DbType.GoldenDB: + case DbType.Sqlite: + case DbType.DuckDB: + case DbType.QuestDB: + case DbType.Doris: + case DbType.Xugu: + case DbType.Vastbase: + default: + value = value + .Replace(wildcardStr, "\\" + wildcard); + break; + } + + return value; + } + + + public static List CopySugarParameters(List pars) + { + if (pars == null) return null; + var newParameters = pars.Select(it => new SugarParameter(it.ParameterName, it.Value) + { + TypeName = it.TypeName, + Value = it.Value, + IsRefCursor = it.IsRefCursor, + IsArray = it.IsArray, + IsJson = it.IsJson, + ParameterName = it.ParameterName, + IsNvarchar2 = it.IsNvarchar2, + IsNClob = it.IsClob, + IsClob = it.IsClob, + UdtTypeName = it.UdtTypeName, + CustomDbType = it.CustomDbType, + DbType = it.DbType, + Direction = it.Direction, + Precision = it.Precision, + Size = it.Size, + Scale = it.Scale, + IsNullable = it.IsNullable, + SourceColumn = it.SourceColumn, + SourceColumnNullMapping = it.SourceColumnNullMapping, + SourceVersion = it.SourceVersion, + TempDate = it.TempDate, + _Size = it._Size + }); + return newParameters.ToList(); + } + public static bool IsTuple(Type tType, List classProperties) + { + if (classProperties == null || classProperties?.Count == 0) + { + return false; + } + return tType.FullName?.StartsWith("System.Tuple`") == true && classProperties.FirstOrDefault()?.Name == "Item1"; + } + + internal static string GetTableByDbLink(SqlSugarProvider context, string tableName, string oldTableName, TenantAttribute attr) + { + QueryBuilder queryBuilder = InstanceFactory.GetQueryBuilderWithContext(context); + var dbLinkName = context.Root.GetConnection(attr.configId).CurrentConnectionConfig.DbLinkName; + if (dbLinkName != null) + { + if (dbLinkName.First() == '@') + { + tableName = queryBuilder.Builder.GetTranslationColumnName(oldTableName) + dbLinkName; + } + else if (dbLinkName.Last() == '_') + { + tableName = dbLinkName + oldTableName; + } + else + { + tableName = dbLinkName + "." + queryBuilder.Builder.GetTranslationColumnName(oldTableName); + } + } + return tableName; + } + public static List> GetColumnInfo(IDataReader reader) + { + var columnInfo = new List>(); + + // 获取列的数量 + int columnCount = reader.FieldCount; + + // 遍历每一列 + for (int i = 0; i < columnCount; i++) + { + // 获取列名 + string columnName = reader.GetName(i); + + // 获取列的数据类型 + Type columnType = reader.GetFieldType(i); + + // 将列名和类型添加到列表中 + columnInfo.Add(Tuple.Create(columnName, columnType)); + } + + return columnInfo; + } + public static object ConvertToObjectList(Type targetType, List sourceList) + { + // 创建 List 类型的实例 + object resultList = Activator.CreateInstance(typeof(List<>).MakeGenericType(targetType)); + // 获取 Add 方法 + var addMethod = resultList.GetType().GetMethod("Add"); + foreach (var obj in sourceList) + { + addMethod.Invoke(resultList, new object[] { obj }); + } + return resultList; + } + public static Dictionary DataRowToDictionary(DataRow row) + { + Dictionary dictionary = new Dictionary(); + + // 遍历所有列并将其添加到字典中 + foreach (DataColumn column in row.Table.Columns) + { + if (column.ColumnName != "Items" && column.DataType.Name.IsCollectionsList() == false) + { + dictionary.Add(column.ColumnName, row[column]); + } + } + + return dictionary; + } + public static IEnumerable BuildTree(ISqlSugarClient db, IEnumerable list, string idName, string pIdName, string childName, object rootValue) + { + var entityInfo = db.EntityMaintenance.GetEntityInfo(); ; + var mainIdProp = entityInfo.Type.GetProperty(idName); + var pIdProp = entityInfo.Type.GetProperty(pIdName); + var childProp = entityInfo.Type.GetProperty(childName); + + Dictionary kvList; + IEnumerable> group; + BuildTreeGroup(list, mainIdProp, pIdProp, out kvList, out group); + + var root = rootValue != null ? group.FirstOrDefault(x => x.Key == rootValue.ObjToString()) : group.FirstOrDefault(x => x.Key == null || string.IsNullOrEmpty(x.Key) || x.Key == "0" || x.Key == Guid.Empty.ToString()); + + if (root != null) + { + foreach (var item in group) + { + if (kvList.TryGetValue(item.Key, out var parent)) + { + childProp.SetValue(parent, item.ToList()); + } + } + } + + return root; + } + + private static void BuildTreeGroup(IEnumerable list, PropertyInfo mainIdProp, PropertyInfo pIdProp, out Dictionary kvList, out IEnumerable> group) + { + kvList = list.ToDictionary(x => mainIdProp.GetValue(x).ObjToString()); + group = list.GroupBy(x => pIdProp.GetValue(x).ObjToString()); + } + + internal static bool? _IsErrorDecimalString { get; set; } + private static readonly char[] separator = new char[] { '9' }; + + internal static bool? IsErrorDecimalString() + { + if (_IsErrorDecimalString == null) + { + decimal dec = Convert.ToDecimal(1.1); + _IsErrorDecimalString = dec.ToString().Contains(','); + } + return _IsErrorDecimalString; + } + internal static bool IsParameterConverter(EntityColumnInfo columnInfo) + { + return columnInfo?.SqlParameterDbType != null && columnInfo.SqlParameterDbType is Type + && typeof(ISugarDataConverter).IsAssignableFrom(columnInfo.SqlParameterDbType as Type); + } + internal static SugarParameter GetParameterConverter(int index, ISqlSugarClient db, object value, Expression oppoSiteExpression, EntityColumnInfo columnInfo) + { + var entity = db.EntityMaintenance.GetEntityInfo(oppoSiteExpression.Type); + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; + return p; + } + internal static SugarParameter GetParameterConverter(int index, ISqlSugarClient db, object value, EntityInfo entity, EntityColumnInfo columnInfo) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; + return p; + } + internal static object QueryConverter(int index, ISqlSugarClient db, IDataReader dataReader, EntityInfo entity, EntityColumnInfo columnInfo) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("QueryConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { dataReader, index }); + return p; + } + internal static bool IsErrorParameterName(ConnectionConfig connectionConfig, DbColumnInfo columnInfo) + { + return connectionConfig.MoreSettings?.IsCorrectErrorSqlParameterName == true && + columnInfo.DbColumnName.IsContainsIn("-", " ", ".", "(", ")", "(", ")"); + } + + public static bool StringCheckFirstAndLast(string withString, string first, string last) + { + return withString.StartsWith(first) && withString.EndsWith(last); + } + public static bool HasInterface(Type targetType, Type interfaceType) + { + if (targetType == null || interfaceType?.IsInterface != true) + { + return false; + } + + return interfaceType.IsAssignableFrom(targetType); + } + public static void ClearPublicProperties(T obj, EntityInfo entity) + { + if (obj == null) + { + throw new ArgumentNullException(nameof(obj)); + } + + Type type = typeof(T); + + foreach (var column in entity.Columns) + { + if (column.PropertyInfo.CanWrite && column.PropertyInfo.GetSetMethod() != null) + { + Type propertyType = column.PropertyInfo.PropertyType; + object defaultValue = propertyType.IsValueType ? Activator.CreateInstance(propertyType) : null; + column.PropertyInfo.SetValue(obj, defaultValue); + } + } + } + + internal static Expression GetIncludeExpression(string navMemberName, EntityInfo entityInfo, out Type properyItemType, out bool isList) + { + var navInfo = entityInfo.Columns.Where(it => it.Navigat != null && it.PropertyName.EqualCase(navMemberName)).FirstOrDefault(); + var properyType = navInfo.PropertyInfo.PropertyType; + properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + isList = true; + } + else + { + isList = false; + } + return ExpressionBuilderHelper.CreateExpressionSelectField(entityInfo.Type, navInfo.PropertyName, properyType); + } + public static string RemoveEqualOne(string value) + { + value = value.TrimEnd(' ').TrimEnd('1').TrimEnd('='); + return value; + } + /// + /// Available only in Select,Handles logic that cannot be completed by an expression + /// + /// + /// + /// + internal static object GetFormatValue(object addValue, QueryableFormat valueFomatInfo) + { + if (valueFomatInfo.MethodName == "ToString") + { + if (valueFomatInfo.Type == UtilConstants.GuidType) + { + addValue = Guid.Parse(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.ByteType) + { + addValue = Convert.ToByte(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.IntType) + { + addValue = Convert.ToInt32(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.LongType) + { + addValue = Convert.ToInt64(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.UIntType) + { + addValue = Convert.ToUInt32(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.ULongType) + { + addValue = Convert.ToUInt64(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.DecType) + { + addValue = Convert.ToDecimal(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.DobType) + { + addValue = Convert.ToDouble(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.TypeString == "Enum") + { + addValue = ChangeType2(addValue, valueFomatInfo.Type)?.ToString(); + } + } + else if (valueFomatInfo.MethodName == "OnlyInSelectConvertToString") + { + + var methodInfo = valueFomatInfo.MethodInfo; + if (methodInfo != null) + { + // 如果方法是静态的,传递null作为第一个参数,否则传递类的实例 + object instance = methodInfo.IsStatic ? null : Activator.CreateInstance(methodInfo.ReflectedType); + + // 创建一个包含参数值的object数组 + object[] parameters = new object[] { addValue }; + + // 调用方法 + addValue = methodInfo.Invoke(instance, parameters); + } + } + return addValue; + } + public static int CountSubstringOccurrences(string mainString, string searchString) + { + string[] substrings = mainString.Split(new string[] { searchString }, StringSplitOptions.None); + return substrings.Length - 1; + } + public static string RemoveBeforeFirstWhere(string query) + { + int whereIndex = query.IndexOf("WHERE", StringComparison.OrdinalIgnoreCase); + if (whereIndex >= 0) + { + return query.Substring(whereIndex + "WHERE".Length); + } + else + { + return query; + } + } + public static List ConvertToListOfObjects(object inValues) + { + // 创建一个新的List并逐个将元素转换并添加到其中 + List resultList = new List(); + foreach (var item in (IEnumerable)inValues) + { + resultList.Add(item); + } + + return resultList; + } + public static bool IsValueTypeArray(object memberValue) + { + return memberValue is List || + memberValue is string[] || + memberValue is List || + memberValue is int[] || + memberValue is List || + memberValue is Guid[] || + memberValue is List || + memberValue is long[] || + memberValue is List || + memberValue is int?[] || + memberValue is List || + memberValue is Guid?[] || + memberValue is List || + memberValue is long?[] || + memberValue is List || + memberValue is float[] || + memberValue is List || + memberValue is double[] || + memberValue is List || + memberValue is decimal[] || + memberValue is List || + memberValue is DateTime[] || + memberValue is List || + memberValue is TimeSpan[] || + memberValue is List || + memberValue is bool[] || + memberValue is List || + memberValue is byte[] || + memberValue is List || + memberValue is char[] || + memberValue is List || + memberValue is short[] || + memberValue is List || + memberValue is ushort[] || + memberValue is List || + memberValue is uint[] || + memberValue is List || + memberValue is ulong[] || + memberValue is List || + memberValue is sbyte[] || + memberValue is List || + memberValue is object[] || + memberValue is List || + memberValue is int?[] || + memberValue is List || + memberValue is Guid?[] || + memberValue is List || + memberValue is long?[]; + } + internal static void EndCustomSplitTable(ISqlSugarClient context, Type entityType) + { + if (context == null || entityType == null) + { + return; + } + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute == null) + { + return; + } + if (splitTableAttribute.CustomSplitTableService != null) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = null; + } + } + + internal static void StartCustomSplitTable(ISqlSugarClient context, Type entityType) + { + if (context == null || entityType == null) + { + return; + } + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute == null) + { + return; + } + if (splitTableAttribute.CustomSplitTableService != null) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService + = (ISplitTableService)Activator.CreateInstance(splitTableAttribute.CustomSplitTableService); + } + if ( + context?.CurrentConnectionConfig?.ConfigureExternalServices?.SplitTableService != null + && splitTableAttribute.CustomSplitTableService == null + && context.EntityMaintenance.GetEntityInfo(entityType).DbTableName?.EndsWith("_{year}{month}{day}") == true + && !context.EntityMaintenance.GetEntityInfo(entityType).DbTableName?.Replace("_{year}{month}{day}", "")?.Contains('{') == true + ) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService + = null; + } + } + public static void ConvertParameter(SugarParameter p, ISqlBuilder builder) + { + if (!p.ParameterName.StartsWith(builder.SqlParameterKeyWord)) + { + p.ParameterName = (builder.SqlParameterKeyWord + p.ParameterName.TrimStart('@')); + } + } + public static object SetAnonymousObjectPropertyValue(object obj, string propertyName, object propertyValue) + { + if (obj.GetType().IsAnonymousType()) // 判断是否为匿名对象 + { + var objType = obj.GetType(); + var objFields = objType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); + foreach (var field in objFields) // 遍历字段列表,查找需要修改的属性 + { + if (field.Name == $"<{propertyName}>i__Field") + { + field.SetValue(obj, propertyValue); // 使用反射修改属性值 + break; + } + } + } + else + { + obj.GetType().GetProperty(propertyName).SetValue(obj, propertyValue); + } + return obj; + } + + internal static bool IsNumberArray(Type type) + { + + return type.IsIn(typeof(int[]), + typeof(long[]), + typeof(short[]), + typeof(uint[]), + typeof(ulong[]), + typeof(ushort[]), + typeof(int?[]), + typeof(long?[]), + typeof(short?[]), + typeof(uint?[]), + typeof(ulong?[]), + typeof(ushort?[]), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List)); + } + public static string GetNativeSql(string sql, SugarParameter[] pars) + { + if (pars == null || pars.Length == 0) + return "\r\n[Sql]:" + sql + "\r\n"; + return $"\r\n[Sql]:{sql} \r\n[Pars]:{string.Join(" ", pars.Select(it => $"\r\n[Name]:{it.ParameterName} [Value]:{it.Value} [Type]:{it.DbType} {(it.IsNvarchar2 ? "nvarchar2" : "")} "))} \r\n"; + } + public static string ToUnderLine(string str, bool isToUpper = false) + { + if (str?.Contains('_') != false) + { + return str; + } + else if (isToUpper) + { + return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToUpper(); + } + else + { + return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); + } + } + internal static bool IsArrayMember(Expression expression, SqlSugarProvider context) + { + if (expression == null) + return false; + if (!(expression is LambdaExpression)) + return false; + var lambda = (LambdaExpression)expression; + if (!(lambda.Body is MemberExpression)) + return false; + var member = lambda.Body as MemberExpression; + if (!(member.Type.IsClass())) + return false; + if (member.Expression == null) + return false; + var entity = context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var json = entity.Columns.FirstOrDefault(z => z.IsArray && z.PropertyName == member.Member.Name); + return json != null; + } + internal static bool IsJsonMember(Expression expression, SqlSugarProvider context) + { + if (expression == null) + return false; + if (!(expression is LambdaExpression)) + return false; + var lambda = (LambdaExpression)expression; + if (!(lambda.Body is MemberExpression)) + return false; + var member = lambda.Body as MemberExpression; + if (!(member.Type.IsClass())) + return false; + if (member.Expression == null) + return false; + var entity = context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var json = entity.Columns.FirstOrDefault(z => z.IsJson && z.PropertyName == member.Member.Name); + return json != null; + } + public static string GetSeparatorChar() + { + return Path.Combine("a", "a").Replace("a", ""); + } + public static bool IsParentheses(object name) + { + return name.ObjToString().Trim().Last() == ')' && name.ObjToString().Trim().First() == '('; + } + + internal static bool IsDefaultValue(object value) + { + if (value == null) return true; + return value.Equals(UtilMethods.GetDefaultValue(value.GetType())); + } + + 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) + { + return 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(); + if (destinationType.Name == "DateOnly" && sourceType == typeof(string)) + { + var type = Type.GetType("System.DateOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromDateTime"); + return method.Invoke(null, new object[] { Convert.ToDateTime(value) }); + } + else if (destinationType.FullName == "System.Ulid") + { + var method = destinationType.GetMyMethod("Parse", 1); + if (method != null) + { + var result = method.Invoke(null, new object[] { value }); + return result; + } + } + else if (value is byte[] bytes && bytes.Length == 1 && destinationType == typeof(char)) + { + return (char)(bytes)[0]; + } + else if (value is DateTime && destinationType == typeof(TimeSpan)) + { + value = Convert.ToDateTime(value).TimeOfDay; + } + else if (value is DateTime && destinationType.FullName == "System.TimeOnly") + { + value = Convert.ToDateTime(value).TimeOfDay; + } + var destinationConverter = TypeDescriptor.GetConverter(destinationType); + if (destinationConverter?.CanConvertFrom(value.GetType()) == true) + return destinationConverter.ConvertFrom(null, culture, value); + + var sourceConverter = TypeDescriptor.GetConverter(sourceType); + if (sourceConverter?.CanConvertTo(destinationType) == true) + return sourceConverter.ConvertTo(null, culture, value, destinationType); + + if (destinationType.IsEnum && value is int) + return Enum.ToObject(destinationType, (int)value); + + if (destinationType.Name == "TimeOnly" && sourceType.Name != "TimeOnly") + { + var type = Type.GetType("System.TimeOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromTimeSpan"); + return method.Invoke(null, new object[] { value }); + } + if (destinationType.Name == "DateOnly" && sourceType.Name != "DateOnly") + { + var type = Type.GetType("System.DateOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromDateTime"); + return method.Invoke(null, new object[] { value }); + } + + if (!destinationType.IsInstanceOfType(value)) + return Convert.ChangeType(value, destinationType, culture); + } + return value; + } + public static bool IsAnyAsyncMethod(StackFrame[] methods) + { + bool isAsync = false; + foreach (var item in methods) + { + if (UtilMethods.IsAsyncMethod(item.GetMethod())) + { + isAsync = true; + break; + } + } + return isAsync; + } + + + public static ConnectionConfig CopyConfig(ConnectionConfig it) + { + return new ConnectionConfig() + { + AopEvents = it.AopEvents == null ? null : new AopEvents() + { + DataExecuting = it.AopEvents?.DataExecuting, + OnDiffLogEvent = it.AopEvents?.OnDiffLogEvent, + OnError = it.AopEvents?.OnError, + OnExecutingChangeSql = it.AopEvents?.OnExecutingChangeSql, + OnLogExecuted = it.AopEvents?.OnLogExecuted, + OnLogExecuting = it.AopEvents?.OnLogExecuting, + DataExecuted = it.AopEvents?.DataExecuted, + CheckConnectionExecuted = it.AopEvents?.CheckConnectionExecuted, + CheckConnectionExecuting = it.AopEvents?.CheckConnectionExecuting, + OnGetDataReadered = it.AopEvents?.OnGetDataReadered, + OnGetDataReadering = it.AopEvents?.OnGetDataReadering, + }, + ConfigId = it.ConfigId, + ConfigureExternalServices = it.ConfigureExternalServices == null ? null : new ConfigureExternalServices() + { + AppendDataReaderTypeMappings = it.ConfigureExternalServices.AppendDataReaderTypeMappings, + DataInfoCacheService = it.ConfigureExternalServices.DataInfoCacheService, + EntityNameService = it.ConfigureExternalServices.EntityNameService, + EntityService = it.ConfigureExternalServices.EntityService, + RazorService = it.ConfigureExternalServices.RazorService, + ReflectionInoCacheService = it.ConfigureExternalServices.ReflectionInoCacheService, + SerializeService = it.ConfigureExternalServices.SerializeService, + SplitTableService = it.ConfigureExternalServices.SplitTableService, + SqlFuncServices = it.ConfigureExternalServices.SqlFuncServices + }, + ConnectionString = it.ConnectionString, + DbType = it.DbType, + DbLinkName = it.DbLinkName, + IndexSuffix = it.IndexSuffix, + InitKeyType = it.InitKeyType, + IsAutoCloseConnection = it.IsAutoCloseConnection, + LanguageType = it.LanguageType, + MoreSettings = it.MoreSettings == null ? null : new ConnMoreSettings() + { + DefaultCacheDurationInSeconds = it.MoreSettings.DefaultCacheDurationInSeconds, + DisableNvarchar = it.MoreSettings.DisableNvarchar, + PgSqlIsAutoToLower = it.MoreSettings.PgSqlIsAutoToLower, + PgSqlIsAutoToLowerCodeFirst = it.MoreSettings.PgSqlIsAutoToLowerCodeFirst, + IsAutoRemoveDataCache = it.MoreSettings.IsAutoRemoveDataCache, + IsWithNoLockQuery = it.MoreSettings.IsWithNoLockQuery, + DisableWithNoLockWithTran = it.MoreSettings.DisableWithNoLockWithTran, + TableEnumIsString = it.MoreSettings.TableEnumIsString, + DisableMillisecond = it.MoreSettings.DisableMillisecond, + DbMinDate = it.MoreSettings.DbMinDate, + IsNoReadXmlDescription = it.MoreSettings.IsNoReadXmlDescription, + SqlServerCodeFirstNvarchar = it.MoreSettings.SqlServerCodeFirstNvarchar, + OracleCodeFirstNvarchar2 = it.MoreSettings.OracleCodeFirstNvarchar2, + IsAutoToUpper = it.MoreSettings.IsAutoToUpper, + IsAutoDeleteQueryFilter = it.MoreSettings.IsAutoDeleteQueryFilter, + IsAutoUpdateQueryFilter = it.MoreSettings.IsAutoUpdateQueryFilter, + EnableModelFuncMappingColumn = it.MoreSettings.EnableModelFuncMappingColumn, + EnableOracleIdentity = it.MoreSettings.EnableOracleIdentity, + IsWithNoLockSubquery = it.MoreSettings.IsWithNoLockSubquery, + EnableCodeFirstUpdatePrecision = it.MoreSettings.EnableCodeFirstUpdatePrecision, + SqliteCodeFirstEnableDefaultValue = it.MoreSettings.SqliteCodeFirstEnableDefaultValue, + SqliteCodeFirstEnableDescription = it.MoreSettings.SqliteCodeFirstEnableDescription, + IsCorrectErrorSqlParameterName = it.MoreSettings.IsCorrectErrorSqlParameterName, + SqliteCodeFirstEnableDropColumn = it.MoreSettings.SqliteCodeFirstEnableDropColumn, + MaxParameterNameLength = it.MoreSettings.MaxParameterNameLength, + DisableQueryWhereColumnRemoveTrim = it.MoreSettings.DisableQueryWhereColumnRemoveTrim, + DatabaseModel = it.MoreSettings.DatabaseModel, + EnableILike = it.MoreSettings.EnableILike, + ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal, + PgSqlIsAutoToLowerSchema = it.MoreSettings.PgSqlIsAutoToLowerSchema + + }, + SqlMiddle = it.SqlMiddle == null ? null : new SqlMiddle + { + IsSqlMiddle = it.SqlMiddle.IsSqlMiddle, + ExecuteCommand = it.SqlMiddle.ExecuteCommand, + ExecuteCommandAsync = it.SqlMiddle.ExecuteCommandAsync, + GetDataReader = it.SqlMiddle.GetDataReader, + GetDataReaderAsync = it.SqlMiddle.GetDataReaderAsync, + GetDataSetAll = it.SqlMiddle.GetDataSetAll, + GetDataSetAllAsync = it.SqlMiddle.GetDataSetAllAsync, + GetScalar = it.SqlMiddle.GetScalar, + GetScalarAsync = it.SqlMiddle.GetScalarAsync + }, + SlaveConnectionConfigs = it.SlaveConnectionConfigs + }; + } + + internal static object GetRandomByType(Type underType) + { + if (underType == UtilConstants.GuidType) + { + return Guid.NewGuid(); + } + else if (underType == UtilConstants.LongType) + { + return SnowFlakeSingle.Instance.NextId(); + } + else if (underType == UtilConstants.StringType) + { + return Guid.NewGuid() + ""; + } + else if (underType == UtilConstants.DateType) + { + return System.DateTime.Now; + } + else + { + return Guid.NewGuid() + ""; + } + } + + public static 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; + } + //if (method?.DeclaringType?.FullName?.Contains("Furion.InternalApp")==true) + //{ + // return false; + //} + Type attType = typeof(AsyncStateMachineAttribute); + var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType); + return (attrib != null); + } + + public static StackTraceInfo GetStackTrace() + { + + StackTrace st = new StackTrace(true); + StackTraceInfo info = new StackTraceInfo(); + info.MyStackTraceList = new List(); + info.SugarStackTraceList = new List(); + for (int i = 0; i < st.FrameCount; i++) + { + var frame = st.GetFrame(i); + if (!frame.GetMethod().Module.Name.Equals("sqlsugar.dll", StringComparison.CurrentCultureIgnoreCase) && 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 object GetConvertValue(object entityValue) + { + if (entityValue != null && entityValue is DateTime) + { + entityValue = entityValue.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + return entityValue; + } + + internal static T To(object value) + { + return (T)To(value, typeof(T)); + } + + 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; + } + } + + public static Type GetUnderType(Type oldType) + { + Type type = Nullable.GetUnderlyingType(oldType); + return type == null ? oldType : type; + } + public static object GetDefaultValue(Type type) + { + return type.IsValueType ? Activator.CreateInstance(type) : null; + } + public static string ReplaceFirstMatch(string input, string pattern, string replacement) + { + Regex regex = new Regex(pattern); + return regex.Replace(input, replacement, 1); + } + public static string ReplaceSqlParameter(string itemSql, SugarParameter itemParameter, string newName) + { + itemSql = Regex.Replace(itemSql, string.Format(@"{0} ", "\\" + itemParameter.ParameterName), newName + " ", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\)", "\\" + itemParameter.ParameterName), newName + ")", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\,", "\\" + itemParameter.ParameterName), newName + ",", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}$", "\\" + itemParameter.ParameterName), newName, RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\+{0}\+", "\\" + itemParameter.ParameterName), "+" + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\+{0} ", "\\" + itemParameter.ParameterName), "+" + newName + " ", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@" {0}\+", "\\" + itemParameter.ParameterName), " " + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\|\|{0}\|\|", "\\" + itemParameter.ParameterName), "||" + newName + "||", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\={0}\+", "\\" + itemParameter.ParameterName), "=" + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\|\|", "\\" + itemParameter.ParameterName), newName + "||", RegexOptions.IgnoreCase); + return itemSql; + } + internal static Type GetRootBaseType(Type entityType) + { + var baseType = entityType.BaseType; + while (baseType != null && baseType.BaseType != UtilConstants.ObjType) + { + baseType = baseType.BaseType; + } + return baseType; + } + + + internal static Type GetUnderType(PropertyInfo propertyInfo, ref bool isNullable) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + isNullable = unType != null; + unType = unType ?? propertyInfo.PropertyType; + return unType; + } + + internal static Type GetUnderType(PropertyInfo propertyInfo) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + unType = unType ?? propertyInfo.PropertyType; + return unType; + } + + internal static bool IsNullable(PropertyInfo propertyInfo) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + return unType != null; + } + + internal static bool IsNullable(Type type) + { + Type unType = Nullable.GetUnderlyingType(type); + return unType != null; + } + internal static T IsNullReturnNew(T returnObj) where T : new() + { + if (returnObj.IsNullOrEmpty()) + { + returnObj = new T(); + } + return returnObj; + } + public static object ChangeType2(object value, Type type) + { + if (value is byte[] && type == UtilConstants.StringType) + { + return Encoding.UTF8.GetString(value as byte[]); + } + if (value == null && type.IsGenericType) return Activator.CreateInstance(type); + if (value == null) return null; + if (type == value.GetType()) return value; + if (type.IsEnum) + { + if (value is string) + return Enum.Parse(type, value as string); + else + return Enum.ToObject(type, value); + } + if (value is string && type == typeof(Guid?)) return value.IsNullOrEmpty() ? null : (Guid?)new Guid(value as string); + if (!type.IsInterface && type.IsGenericType) + { + Type innerType = type.GetGenericArguments()[0]; + object innerValue = ChangeType(value, innerType); + return Activator.CreateInstance(type, new object[] { innerValue }); + } + if (value is string && type == typeof(Guid)) return new Guid(value as string); + if (value is string && type == typeof(Version)) return new Version(value as string); + if (!(value is IConvertible)) return value; + if (value is DateTime && type.FullName == "System.DateOnly") + { + value = UtilMethods.DateTimeToDateOnly(value); + } + return Convert.ChangeType(value, type); + } + + internal static T ChangeType(T obj, Type type) + { + return (T)Convert.ChangeType(obj, type); + } + + internal static T ChangeType(T obj) + { + return (T)Convert.ChangeType(obj, typeof(T)); + } + + internal static DateTimeOffset GetDateTimeOffsetByDateTime(DateTime date) + { + date = DateTime.SpecifyKind(date, DateTimeKind.Utc); + DateTimeOffset utcTime2 = date; + return utcTime2; + } + + internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + { + if (appendSql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + string newName = name + append + addIndex; + appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + parameter.ParameterName = newName; + } + } + } + internal static void RepairReplicationParameters(ISqlSugarClient db, ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + { + if (appendSql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + string newName = name + append + addIndex; + var maxLength = db.CurrentConnectionConfig.MoreSettings.MaxParameterNameLength; + if (newName.Length > maxLength) + { + newName = (name.Substring(0, 1) + name.GetNonNegativeHashCodeString() + "_" + addIndex); + } + appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + parameter.ParameterName = newName; + } + } + } + + internal static string GetPackTable(string sql, string shortName) + { + return string.Format(" ({0}) {1} ", sql, shortName); + } + + public static Func GetTypeConvert(object value) + { + if (value is int || value is uint || value is int? || value is uint?) + { + return x => Convert.ToInt32(x); + } + else if (value is short || value is ushort || value is short? || value is ushort?) + { + return x => Convert.ToInt16(x); + } + else if (value is long || value is long? || value is ulong? || value is long?) + { + return x => Convert.ToInt64(x); + } + else if (value is DateTime || value is DateTime?) + { + return x => Convert.ToDateTime(x); + } + else if (value is bool || value is bool?) + { + return x => Convert.ToBoolean(x); + } + return null; + } + + internal static string GetTypeName(object value) + { + if (value == null) + { + return null; + } + else + { + return value.GetType().Name; + } + } + + internal static string GetParenthesesValue(string dbTypeName) + { + if (Regex.IsMatch(dbTypeName, @"\(.+\)")) + { + if (Regex.IsMatch(dbTypeName, @"SimpleAggregateFunction")) + dbTypeName = Regex.Match(dbTypeName, @"((?<=,\s)[^Nullable]\w+)|((?<=Nullable\()\w+)").Value; + else + dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", ""); + } + dbTypeName = dbTypeName.Trim(); + return dbTypeName; + } + + internal static T GetOldValue(T value, Action action) + { + action(); + return value; + } + + internal static object DefaultForType(Type targetType) + { + return targetType.IsValueType ? Activator.CreateInstance(targetType) : null; + } + + internal static Int64 GetLong(byte[] bytes) + { + return Convert.ToInt64(string.Join("", bytes).PadRight(20, '0')); + } + public static object GetPropertyValue(T t, string PropertyName) + { + return t.GetType().GetProperty(PropertyName).GetValue(t, null); + } + internal static string GetMD5(string myString) + { + return myString.MD5(); + } + + public static string EncodeBase64(string code) + { + if (StaticConfig.Encode != null) + { + return StaticConfig.Encode(code); + } + if (code.IsNullOrEmpty()) return code; + string encode = ""; + byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(code); + try + { + encode = Convert.ToBase64String(bytes); + } + catch + { + encode = code; + } + return encode; + } + public static string ConvertNumbersToString(string value) + { + string[] splitInt = value.Split(separator, StringSplitOptions.RemoveEmptyEntries); + + var splitChars = splitInt.Select(s => Convert.ToChar( + Convert.ToInt32(s, 8) + ).ToString()); + + return string.Join("", splitChars); + } + public static string ConvertStringToNumbers(string value) + { + StringBuilder sb = new StringBuilder(); + + foreach (char c in value) + { + int cAscil = (int)c; + sb.Append(Convert.ToString(c, 8) + "9"); + } + + return sb.ToString(); + } + + public static string DecodeBase64(string code) + { + try + { + if (StaticConfig.Decode != null) + { + return StaticConfig.Decode(code); + } + if (code.IsNullOrEmpty()) return code; + string decode = ""; + byte[] bytes = Convert.FromBase64String(code); + try + { + decode = Encoding.GetEncoding("utf-8").GetString(bytes); + } + catch + { + decode = code; + } + return decode; + } + catch + { + return code; + } + } + + public static string GetSqlValue(object value) + { + if (value == null) + { + return "null"; + } + else if (UtilMethods.IsNumber(value.GetType().Name)) + { + return value.ObjToString(); + } + else if (value is DateTime) + { + return UtilMethods.GetConvertValue(value) + ""; + } + else + { + return value.ToSqlValue(); + } + } + + public static void DataInoveByExpresson(Type[] datas, MethodCallExpression callExpresion) + { + var methodInfo = callExpresion.Method; + foreach (var item in datas) + { + if (item != null) + { + if (callExpresion.Arguments.Count == 0) + { + methodInfo.Invoke(item, null); + } + else + { + List methodParameters = new List(); + foreach (var callItem in callExpresion.Arguments) + { + var parameter = callItem.GetType().GetProperties().FirstOrDefault(it => it.Name == "Value"); + if (parameter == null) + { + var value = LambdaExpression.Lambda(callItem).Compile().DynamicInvoke(); + methodParameters.Add(value); + } + else + { + var value = parameter.GetValue(callItem, null); + methodParameters.Add(value); + } + } + methodInfo.Invoke(item, methodParameters.ToArray()); + } + } + } + } + + public static Dictionary EnumToDictionary() + { + Dictionary dic = new Dictionary(); + if (!typeof(T).IsEnum) + { + return dic; + } + string desc = string.Empty; + foreach (var item in Enum.GetValues(typeof(T))) + { + var key = item.ToString().ToLower(); + if (!dic.ContainsKey(key)) + dic.Add(key, (T)item); + } + return dic; + } + + public static Type GetTypeByTypeName(string ctypename) + { + + if (ctypename.EqualCase(UtilConstants.DecType.Name)) + { + return UtilConstants.DecType; + } + else if (ctypename.EqualCase(UtilConstants.DobType.Name)) + { + return UtilConstants.DobType; + } + else if (ctypename.EqualCase(UtilConstants.DateType.Name)) + { + return UtilConstants.DateType; + } + else if (ctypename.EqualCase(UtilConstants.IntType.Name)) + { + return UtilConstants.IntType; + } + else if (ctypename.EqualCase(UtilConstants.BoolType.Name)) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase(UtilConstants.LongType.Name)) + { + return UtilConstants.LongType; + } + else if (ctypename.EqualCase(UtilConstants.ShortType.Name)) + { + return UtilConstants.ShortType; + } + else if (ctypename.EqualCase(UtilConstants.DateTimeOffsetType.Name)) + { + return UtilConstants.DateTimeOffsetType; + } + else if (ctypename.EqualCase(UtilConstants.GuidType.Name)) + { + return UtilConstants.GuidType; + } + else if (ctypename.EqualCase("int")) + { + return UtilConstants.IntType; + } + else if (ctypename.EqualCase("long")) + { + return UtilConstants.LongType; + } + else if (ctypename.EqualCase("short")) + { + return UtilConstants.ShortType; + } + else if (ctypename.EqualCase("byte")) + { + return UtilConstants.ByteType; + } + else if (ctypename.EqualCase("uint")) + { + return UtilConstants.UIntType; + } + else if (ctypename.EqualCase("ulong")) + { + return UtilConstants.ULongType; + } + else if (ctypename.EqualCase("ushort")) + { + return UtilConstants.UShortType; + } + else if (ctypename.EqualCase("uint32")) + { + return UtilConstants.UIntType; + } + else if (ctypename.EqualCase("uint64")) + { + return UtilConstants.ULongType; + } + else if (ctypename.EqualCase("bool")) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase("ToBoolean")) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase("uint16")) + { + return UtilConstants.UShortType; + } + else if (ctypename.EqualCase(UtilConstants.ByteArrayType.Name)) + { + return UtilConstants.ByteArrayType; + } + else + { + return UtilConstants.StringType; + } + } + public static object ConvertDataByTypeName(string ctypename, string value) + { + var item = new ConditionalModel() + { + CSharpTypeName = ctypename, + FieldValue = value + }; + if (string.IsNullOrEmpty(item.FieldValue) && item.CSharpTypeName.HasValue() && !item.CSharpTypeName.EqualCase("string")) + { + return null; + } + if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) + { + return Convert.ToDecimal(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) + { + return Convert.ToDouble(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DateType.Name)) + { + return Convert.ToDateTime(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) + { + return Convert.ToInt32(item.FieldValue); + } + else if (item.FieldValue != null && item.CSharpTypeName.EqualCase(UtilConstants.BoolType.Name)) + { + return Convert.ToBoolean(item.FieldValue.ToLower()); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) + { + return Convert.ToInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) + { + return Convert.ToInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DateTimeOffsetType.Name)) + { + DateTimeOffset dt; + if (DateTimeOffset.TryParse(item.FieldValue, out dt)) + { + return dt; + } + return UtilMethods.GetDateTimeOffsetByDateTime(Convert.ToDateTime(item.FieldValue)); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.GuidType.Name)) + { + return Guid.Parse(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("int")) + { + return Convert.ToInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("long")) + { + return Convert.ToInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("float")) + { + return Convert.ToSingle(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("single")) + { + return Convert.ToSingle(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("short")) + { + return Convert.ToInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("byte")) + { + return Convert.ToByte(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint")) + { + return Convert.ToUInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ulong")) + { + return Convert.ToUInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ushort")) + { + return Convert.ToUInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint32")) + { + return Convert.ToUInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint64")) + { + return Convert.ToUInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("bool")) + { + return Convert.ToBoolean(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ToBoolean")) + { + return Convert.ToBoolean(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint16")) + { + return Convert.ToUInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("byte[]") && item.FieldValue?.Contains('|') == true) + { + return item.FieldValue.Split('|').Select(it => Convert.ToByte(it)).ToArray(); + } + else + { + return item.FieldValue; + } + } + + public static bool IsNumber(string ctypename) + { + if (ctypename.IsNullOrEmpty()) + { + return false; + } + var item = new ConditionalModel() + { + CSharpTypeName = ctypename, + }; + if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("int")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("long")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("short")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("byte")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("ulong")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("ushort")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint32")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint64")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint16")) + { + return true; + } + else + { + return false; + } + } + + /// + /// Get Week Last Day Sun + /// + /// + /// + public static DateTime GetWeekLastDaySun(DateTime datetime) + { + //星期天为最后一天 + int weeknow = Convert.ToInt32(datetime.DayOfWeek); + weeknow = (weeknow == 0 ? 7 : weeknow); + int daydiff = (7 - weeknow); + + //本周最后一天 + string LastDay = datetime.AddDays(daydiff).ToString("yyyy-MM-dd"); + return Convert.ToDateTime(LastDay); + } + /// + /// Get Week First Day Mon + /// + /// + /// + public static DateTime GetWeekFirstDayMon(DateTime datetime) + { + //星期一为第一天 + int weeknow = Convert.ToInt32(datetime.DayOfWeek); + + //因为是以星期一为第一天,所以要判断weeknow等于0时,要向前推6天。 + weeknow = (weeknow == 0 ? (7 - 1) : (weeknow - 1)); + int daydiff = (-1) * weeknow; + + //本周第一天 + string FirstDay = datetime.AddDays(daydiff).ToString("yyyy-MM-dd"); + return Convert.ToDateTime(FirstDay); + } + public static string GetSqlString(DbType dbType, string sql, SugarParameter[] parametres, bool DisableNvarchar = false) + { + if (parametres == null) + parametres = Array.Empty(); + return GetSqlString(new ConnectionConfig() + { + DbType = dbType, + MoreSettings = new ConnMoreSettings() + { + DisableNvarchar = DisableNvarchar + } + }, new KeyValuePair>(sql, parametres.ToList())); + } + public static string GetSqlString(ConnectionConfig connectionConfig, KeyValuePair> sqlObj) + { + var guid = Guid.NewGuid() + ""; + var result = sqlObj.Key; + if (sqlObj.Value != null) + { + foreach (var item in UtilMethods.CopySugarParameters(sqlObj.Value).OrderByDescending(it => it.ParameterName.Length)) + { + if (item.ParameterName.StartsWith(':') && !result.Contains(item.ParameterName)) + { + item.ParameterName = "@" + item.ParameterName.TrimStart(':'); + } + if (connectionConfig.MoreSettings == null) + { + connectionConfig.MoreSettings = new ConnMoreSettings(); + } + if (item.Value != null && item.Value is DateTime && ((DateTime)item.Value == DateTime.MinValue)) + { + item.Value = connectionConfig.MoreSettings.DbMinDate; + } + if (item.Value == null || item.Value == DBNull.Value) + { + result = result.Replace(item.ParameterName, "null"); + } + else if (UtilMethods.IsNumber(item.Value.GetType().Name)) + { + result = result.Replace(item.ParameterName, item.Value.ObjToString()); + } + else if (item.Value is DateTime && connectionConfig.DbType == DbType.SqlServer) + { + result = result.Replace(item.ParameterName, "CAST('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff") + "' AS DATETIME)"); + } + else if (item.Value is DateTime && connectionConfig.DbType.IsIn(DbType.Dm, DbType.Oracle)) + { + if (item.DbType == System.Data.DbType.Date || connectionConfig?.MoreSettings?.DisableMillisecond == true) + { + var value = "to_date('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; ; + result = result.Replace(item.ParameterName, value); + } + else + { + var value = "to_timestamp('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + result = result.Replace(item.ParameterName, value); + } + } + else if (item.Value is DateTime) + { + result = result.Replace(item.ParameterName, "'" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"); + } + else if (item.IsArray) + { + result = result.Replace(item.ParameterName, "'{" + new SerializeService().SerializeObject(item.Value).TrimStart('[').TrimEnd(']') + "}'"); + } + else if (item.Value is byte[] && connectionConfig.DbType == DbType.PostgreSQL) + { + result = result.Replace(item.ParameterName, ByteArrayToPostgreByteaLiteral(item.Value as byte[])); + } + else if (item.Value is byte[]) + { + result = result.Replace(item.ParameterName, "0x" + Convert.ToHexString((byte[])item.Value)); + } + else if (item.Value is bool) + { + if (connectionConfig.DbType == DbType.PostgreSQL) + { + result = result.Replace(item.ParameterName, (Convert.ToBoolean(item.Value) ? "true" : "false")); + } + else + { + result = result.Replace(item.ParameterName, (Convert.ToBoolean(item.Value) ? 1 : 0) + ""); + } + } + else if (item.Value.GetType() != UtilConstants.StringType && connectionConfig.DbType == DbType.PostgreSQL && PostgreSQLDbBind.MappingTypesConst.Any(x => x.Value.ToString().EqualCase(item.Value.GetType().Name))) + { + var type = PostgreSQLDbBind.MappingTypesConst.First(x => x.Value.ToString().EqualCase(item.Value.GetType().Name)).Key; + var replaceValue = string.Format("CAST('{0}' AS {1})", item.Value, type); + result = result.Replace(item.ParameterName, replaceValue); + } + else if (connectionConfig.MoreSettings?.DisableNvarchar == true || item.DbType == System.Data.DbType.AnsiString || connectionConfig.DbType == DbType.Sqlite) + { + result = result.Replace(item.ParameterName, $"'{item.Value.ObjToString().Replace("@", guid).ToSqlFilter()}'"); + } + else + { + result = result.Replace(item.ParameterName, $"N'{item.Value.ObjToStringNoTrim().Replace("@", guid).ToSqlFilter()}'"); + } + } + } + result = result.Replace(guid, "@"); + return result; + } + public static string ByteArrayToPostgreByteaLiteral(byte[] data) + { + var sb = new StringBuilder("E'"); + + foreach (var b in data) + { + if (b >= 32 && b < 127 && !char.IsControl((char)b)) // 可打印的ASCII字符 + { + sb.Append((char)b); + } + else // 非打印字符或控制字符 + { + sb.Append("\\\\"); + sb.Append(Convert.ToString(b, 8).PadLeft(3, '0')); + } + } + + sb.Append("'::bytea"); + return sb.ToString(); + } + public static void CheckArray(T[] insertObjs) where T : class, new() + { + + if (insertObjs?.Length == 1 + && insertObjs.FirstOrDefault()?.GetType().FullName.Contains("System.Collections.Generic.List`") == true) + { + Check.ExceptionEasy("Insertable(T []) is an array and your argument is a List", "二次封装引起的进错重载,当前方法是 Insertable(T []) 参数是一个数组,而你的参数是一个List"); + } + } + + [Obsolete("请使用新名字:FieldNameSql")] + public static string FiledNameSql() + { + return $"[value=sql{UtilConstants.ReplaceKey}]"; + } + public static string FieldNameSql() + { + if (StaticConfig.TableQuerySqlKey != Guid.Empty) + { + return $"[value=sql{StaticConfig.TableQuerySqlKey}]"; + } + return $"[value=sql{UtilConstants.ReplaceKey}]"; + } + + internal static object TimeOnlyToTimeSpan(object value) + { + if (value == null) return null; + var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToTimeSpan"); + return method.Invoke(value, Array.Empty()); + } + + internal static object DateOnlyToDateTime(object value) + { + if (value == null) return null; + var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToShortDateString"); + return method.Invoke(value, Array.Empty()); + } + internal static object DateTimeToDateOnly(object value) + { + if (value == null) return null; + + // 获取DateOnly类型 + Type dateOnlyType = Type.GetType("System.DateOnly, System.Runtime", throwOnError: false); + if (dateOnlyType == null) + { + throw new InvalidOperationException("DateOnly type not found."); + } + + // 获取DateOnly的构造函数 + var constructor = dateOnlyType.GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + if (constructor == null) + { + throw new InvalidOperationException("DateOnly constructor not found."); + } + + // 使用反射调用DateTime的属性 + var yearProperty = value.GetType().GetProperty("Year"); + var monthProperty = value.GetType().GetProperty("Month"); + var dayProperty = value.GetType().GetProperty("Day"); + + if (yearProperty == null || monthProperty == null || dayProperty == null) + { + throw new InvalidOperationException("DateTime properties not found."); + } + + int year = (int)yearProperty.GetValue(value); + int month = (int)monthProperty.GetValue(value); + int day = (int)dayProperty.GetValue(value); + + // 使用反射创建DateOnly实例 + return constructor.Invoke(new object[] { year, month, day }); + } + + + internal static void AddDiscrimator(Type type, ISugarQueryable queryable, string shortName = null) + { + var entityInfo = queryable.Context?.EntityMaintenance?.GetEntityInfoWithAttr(type); + if (entityInfo?.Discrimator.HasValue() == true) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + queryable.Where(shortName + name, "=", value); + } + } + } + internal static string GetDiscrimator(EntityInfo entityInfo, ISqlBuilder builer) + { + List wheres = new List(); + if (entityInfo?.Discrimator.HasValue() == true) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + wheres.Add($"{builer.GetTranslationColumnName(name)}={value.ToSqlValue()} "); + } + } + return string.Join(" AND ", wheres); + } + + internal static bool NoErrorParameter(string parameterName) + { + if (parameterName == null) + { + return false; + } + if (parameterName.Contains(' ')) + { + return false; + } + if (parameterName.Contains('(')) + { + return false; + } + if (parameterName.Contains('(')) + { + return false; + } + if (parameterName.Contains('.')) + { + return false; + } + return true; + } + + internal static ConnMoreSettings GetMoreSetting(ExpressionContext context) + { + return context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings ?? new ConnMoreSettings(); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilRandom.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilRandom.cs new file mode 100644 index 000000000..a45f14521 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/UtilRandom.cs @@ -0,0 +1,28 @@ +namespace SqlSugar +{ + public static class UtilRandom + { + public static Random Random = new Random(); + public static int GetRandomIndex(Dictionary pars) + { + int maxValue = 0; + foreach (var item in pars) + { + maxValue += item.Value; + } + var num = Random.Next(1, maxValue); + var result = 0; + var endValue = 0; + foreach (var item in pars) + { + var index = pars.ToList().IndexOf(item); + var beginValue = index == 0 ? 0 : pars[index - 1]; + endValue += item.Value; + result = item.Key; + if (num >= beginValue && num <= endValue) + break; + } + return result; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ValidateExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ValidateExtensions.cs new file mode 100644 index 000000000..eec763c2e --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/Utilities/ValidateExtensions.cs @@ -0,0 +1,186 @@ +using System.Text.RegularExpressions; +namespace SqlSugar +{ + internal static class ValidateExtensions + { + public static bool IsInRange(this int thisValue, int begin, int end) + { + return thisValue >= begin && thisValue <= end; + } + + public static bool IsInRange(this DateTime thisValue, DateTime begin, DateTime end) + { + return thisValue >= begin && thisValue <= end; + } + + public static bool IsIn(this T thisValue, params T[] values) + { + return values.Contains(thisValue); + } + + public static bool IsContainsIn(this string thisValue, params char[] inValues) + { + return inValues.Any(it => thisValue.Contains(it)); + } + public static bool IsContainsIn(this string thisValue, params string[] inValues) + { + return inValues.Any(it => thisValue.Contains(it)); + } + public static bool IsContainsStartWithIn(this string thisValue, params string[] inValues) + { + return inValues.Any(it => thisValue.StartsWith(it)); + } + + public static bool IsNullOrEmpty(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return true; + return string.IsNullOrEmpty(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) + { + return thisValue == Guid.Empty; + } + + public static bool IsNullOrEmpty(this IEnumerable thisValue) + { + if (thisValue?.Any() != true) return true; + return false; + } + + public static bool HasValue(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return false; + return !string.IsNullOrEmpty(thisValue.ToString()); + } + + public static bool HasValue(this IEnumerable thisValue) + { + if (thisValue?.Any() != true) return false; + return true; + } + + public static bool IsValuable(this IEnumerable> thisValue) + { + if (thisValue?.Any() != true) return false; + return true; + } + + public static bool IsZero(this object thisValue) + { + return (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 IsIterator(this Type type) + { + if (type.BaseType == null) + { + return false; + } + if (type.BaseType.IsGenericType) + { + return type.BaseType?.GetGenericTypeDefinition()?.FullName == "System.Linq.Enumerable+Iterator`1"; + } + return false; + } + public static bool IsStringArray(this string thisValue) + { + return (thisValue + "").IsMatch(@"System\.[a-z,A-Z,0-9]+?\[\]"); + } + public static bool IsEnumerable(this string thisValue) + { + return (thisValue + "").StartsWith("System.Linq.Enumerable"); + } + + public static Type StringType = typeof(string); + + public static bool IsClass(this Type thisValue) + { + return thisValue != StringType && thisValue.IsEntity() && thisValue != UtilConstants.ByteArrayType; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/Dm.nuspec b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/Dm.nuspec new file mode 100644 index 000000000..22db9aaa3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/Dm.nuspec @@ -0,0 +1,22 @@ + + + + SqlSugarCore.Dm + 1.0 + sunkaixuan + Landa + http://www.apache.org/licenses/LICENSE-2.0.html + https://github.com/sunkaixuan/SqlSugar + https://secure.gravatar.com/avatar/a82c03402497b2e58fd65038a3699b30 + false + dm sqlsugar .net core + Copyright 2016 + Asp.net core orm + + + + + + + + \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/Kdbndp.nuspec b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/Kdbndp.nuspec new file mode 100644 index 000000000..487c66610 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/Kdbndp.nuspec @@ -0,0 +1,22 @@ + + + + SqlSugarCore.Kdbndp + 1.0 + sunkaixuan + Landa + http://www.apache.org/licenses/LICENSE-2.0.html + https://github.com/sunkaixuan/SqlSugar + https://secure.gravatar.com/avatar/a82c03402497b2e58fd65038a3699b30 + false + dm sqlsugar .net core + Copyright 2016 + Asp.net core orm + + + + + + + + \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/NuGet.exe b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/NuGet.exe new file mode 100644 index 000000000..6bb79fe53 Binary files /dev/null and b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/NuGet.exe differ diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/dm.bat b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/dm.bat new file mode 100644 index 000000000..86e7ca499 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/dm.bat @@ -0,0 +1 @@ +%~dp0nuget.exe pack %~dp0Dm.nuspec -OutputDirectory %~dp0 \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/kdbndp.bat b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/kdbndp.bat new file mode 100644 index 000000000..5b98853d9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/Sugar/dll/kdbndp.bat @@ -0,0 +1 @@ +%~dp0nuget.exe pack %~dp0Kdbndp.nuspec -OutputDirectory %~dp0 \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/STable.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/STable.cs new file mode 100644 index 000000000..08dfe0e3d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/STable.cs @@ -0,0 +1,14 @@ +namespace SqlSugar.TDengine +{ + public class STable + { + [SugarColumn(IsIgnore = true)] + public string TagsTypeId { get; set; } + public static List Tags = null; + } + public class ColumnTagInfo + { + public string Name { get; set; } + public string Value { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/STableAttribute.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/STableAttribute.cs new file mode 100644 index 000000000..2df09baea --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/STableAttribute.cs @@ -0,0 +1,13 @@ +namespace SqlSugar.TDengine +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public class STableAttribute : Attribute + { + public string Tags { get; set; } + public string Tag1 { get; set; } + public string Tag2 { get; set; } + public string Tag3 { get; set; } + public string Tag4 { get; set; } + public string STableName { get; set; } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/CodeFirst/TDengineCodeFirst.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/CodeFirst/TDengineCodeFirst.cs new file mode 100644 index 000000000..5f5d31732 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/CodeFirst/TDengineCodeFirst.cs @@ -0,0 +1,309 @@ +using System.Data; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDengine +{ + public class TDengineCodeFirst : CodeFirstProvider + { + protected override void Execute(Type entityType, EntityInfo entityInfo) + { + var attr = GetCommonSTableAttribute(entityInfo.Type.GetCustomAttribute()); + if (attr?.STableName != null && attr?.Tag1 != null) + { + entityInfo.DbTableName = attr.STableName; + Context.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName); + } + //var entityInfo = this.Context.EntityMaintenance.GetEntityInfoNoCache(entityType); + if (entityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + entityInfo.Columns.Add(new EntityColumnInfo() { PropertyInfo = typeof(DiscriminatorObject).GetProperty(nameof(DiscriminatorObject.FieldName)), IsOnlyIgnoreUpdate = true, DbColumnName = name, UnderType = typeof(string), PropertyName = name, Length = 50 }); + } + } + if (this.MappingTables.TryGetValue(entityType, out string? v)) + { + entityInfo.DbTableName = v; + this.Context.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName); + } + if (this.DefultLength > 0) + { + foreach (var item in entityInfo.Columns) + { + if (item.PropertyInfo.PropertyType == UtilConstants.StringType && item.DataType.IsNullOrEmpty() && item.Length == 0) + { + item.Length = DefultLength; + } + if (item.DataType?.Contains(',') == true && !Regex.IsMatch(item.DataType, @"\d\,\d")) + { + var types = item.DataType.Split(',').Select(it => it.ToLower()).ToList(); + var mapingTypes = this.Context.Ado.DbBind.MappingTypes.Select(it => it.Key.ToLower()).ToList(); + var mappingType = types.FirstOrDefault(it => mapingTypes.Contains(it)); + if (mappingType != null) + { + item.DataType = mappingType; + } + if (item.DataType == "varcharmax") + { + item.DataType = "nvarchar(max)"; + } + } + } + } + var tableName = GetTableName(entityInfo); + this.Context.MappingTables.Add(entityInfo.EntityName, tableName); + entityInfo.DbTableName = tableName; + entityInfo.Columns.ForEach(it => + { + it.DbTableName = tableName; + if (it.UnderType?.Name == "DateOnly" && it.DataType == null) + { + it.DataType = "Date"; + } + if (it.UnderType?.Name == "TimeOnly" && it.DataType == null) + { + it.DataType = "Time"; + } + }); + var isAny = this.Context.DbMaintenance.IsAnyTable(tableName, false); + if (isAny && entityInfo.IsDisabledUpdateAll) + { + return; + } + if (isAny) + ExistLogic(entityInfo); + else + NoExistLogic(entityInfo); + + this.Context.DbMaintenance.AddRemark(entityInfo); + //this.Context.DbMaintenance.AddIndex(entityInfo); + //base.CreateIndex(entityInfo); + this.Context.DbMaintenance.AddDefaultValue(entityInfo); + } + + public override void ExistLogic(EntityInfo entityInfo) + { + if (entityInfo.Columns.HasValue() && entityInfo.IsDisabledUpdateAll == false) + { + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Multiple primary keys do not support modifications"); + + var tableName = GetTableName(entityInfo); + var dbColumns = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName, false); + ConvertColumns(dbColumns); + var attr = GetCommonSTableAttribute(entityInfo.Type.GetCustomAttribute()); + var entityColumns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + if (attr?.Tag1 != null) + { + entityColumns = entityInfo.Columns.Where(it => it.IsIgnore == false + || it.DbColumnName?.ToLower() == attr.Tag1?.ToLower() + || it.DbColumnName?.ToLower() == attr.Tag2?.ToLower() + || it.DbColumnName?.ToLower() == attr.Tag3?.ToLower() + || it.DbColumnName?.ToLower() == attr.Tag4?.ToLower() + ).ToList(); + foreach (var item in entityColumns) + { + if (item.DbColumnName == null) + { + item.DbColumnName = item.PropertyName; + } + } + } + var dropColumns = dbColumns + .Where(dc => !entityColumns.Any(ec => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(dc => !entityColumns.Any(ec => dc.DbColumnName.Equals(ec.DbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .ToList(); + var addColumns = entityColumns + .Where(ec => ec.OldDbColumnName.IsNullOrEmpty() || !dbColumns.Any(dc => dc.DbColumnName.Equals(ec.OldDbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .Where(ec => !dbColumns.Any(dc => ec.DbColumnName.Equals(dc.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList(); + + var renameColumns = entityColumns + .Where(it => !string.IsNullOrEmpty(it.OldDbColumnName)) + .Where(entityColumn => dbColumns.Any(dbColumn => entityColumn.OldDbColumnName.Equals(dbColumn.DbColumnName, StringComparison.CurrentCultureIgnoreCase))) + .ToList(); + + + var isMultiplePrimaryKey = dbColumns.Where(it => it.IsPrimarykey).Count() > 1 || entityColumns.Where(it => it.IsPrimarykey).Count() > 1; + + + var isChange = false; + foreach (var item in addColumns) + { + this.Context.DbMaintenance.AddColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + isChange = true; + } + if (entityInfo.IsDisabledDelete == false) + { + foreach (var item in dropColumns) + { + this.Context.DbMaintenance.DropColumn(tableName, item.DbColumnName); + isChange = true; + } + } + //foreach (var item in alterColumns) + //{ + + // if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) + // { + // var entityColumnItem = entityColumns.FirstOrDefault(y => y.DbColumnName == item.DbColumnName); + // if (entityColumnItem != null && !string.IsNullOrEmpty(entityColumnItem.DataType)) + // { + // continue; + // } + // } + + // this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + // isChange = true; + //} + foreach (var item in renameColumns) + { + this.Context.DbMaintenance.RenameColumn(tableName, item.OldDbColumnName, item.DbColumnName); + isChange = true; + } + //var isAddPrimaryKey = false; + //foreach (var item in entityColumns) + //{ + // var dbColumn = dbColumns.FirstOrDefault(dc => dc.DbColumnName.Equals(item.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + // if (dbColumn == null) continue; + // bool pkDiff, idEntityDiff; + // KeyAction(item, dbColumn, out pkDiff, out idEntityDiff); + // if (dbColumn != null && pkDiff && !idEntityDiff && isMultiplePrimaryKey == false) + // { + // var isAdd = item.IsPrimarykey; + // if (isAdd) + // { + // isAddPrimaryKey = true; + // this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + // } + // else + // { + // this.Context.DbMaintenance.DropConstraint(tableName, string.Format("PK_{0}_{1}", tableName, item.DbColumnName)); + // } + // } + // else if ((pkDiff || idEntityDiff) && isMultiplePrimaryKey == false) + // { + // ChangeKey(entityInfo, tableName, item); + // } + //} + //if (isAddPrimaryKey == false && entityColumns.Count(it => it.IsPrimarykey) == 1 && dbColumns.Count(it => it.IsPrimarykey) == 0) + //{ + // //var addPk = entityColumns.First(it => it.IsPrimarykey); + // //this.Context.DbMaintenance.AddPrimaryKey(tableName, addPk.DbColumnName); + //} + //if (isMultiplePrimaryKey) + //{ + // var oldPkNames = dbColumns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName.ToLower()).OrderBy(it => it).ToList(); + // var newPkNames = entityColumns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName.ToLower()).OrderBy(it => it).ToList(); + // if (!Enumerable.SequenceEqual(oldPkNames, newPkNames)) + // { + // Check.Exception(true, ErrorMessage.GetThrowMessage("Modification of multiple primary key tables is not supported. Delete tables while creating", "不支持修改多主键表,请删除表在创建")); + // } + + //} + if (isChange && IsBackupTable) + { + this.Context.DbMaintenance.BackupTable(tableName, tableName + DateTime.Now.ToString("yyyyMMddHHmmss"), MaxBackupDataRows); + } + ExistLogicEnd(entityColumns); + } + } + public override void NoExistLogic(EntityInfo entityInfo) + { + List dbColumns = new List(); + foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore != true).Where(it => it.PropertyName != "TagsTypeId").OrderBy(it => it.UnderType == typeof(DateTime) ? 0 : 1)) + { + var addItem = EntityColumnToDbColumn(entityInfo, entityInfo.DbTableName, item); + dbColumns.Add(addItem); + } + var attr = GetCommonSTableAttribute(entityInfo.Type.GetCustomAttribute()); + var oldTableName = entityInfo.DbTableName; + if (attr != null) + { + entityInfo.DbTableName += ("{stable}" + this.Context.Utilities.SerializeObject(attr)); + } + if (attr?.Tag1 != null) + { + dbColumns = dbColumns.Where(it => + it.DbColumnName?.ToLower() != attr.Tag1?.ToLower() + && it.DbColumnName?.ToLower() != attr.Tag2?.ToLower() + && it.DbColumnName?.ToLower() != attr.Tag3?.ToLower() + && it.DbColumnName?.ToLower() != attr.Tag4?.ToLower() + ).ToList(); + } + var dbMain = (TDengineDbMaintenance)this.Context.DbMaintenance; + dbMain.EntityInfo = entityInfo; + dbMain.CreateTable(entityInfo.DbTableName, dbColumns); + entityInfo.DbTableName = oldTableName; + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + DbColumnInfo result = new DbColumnInfo() { Length = item.Length, DecimalDigits = item.DecimalDigits, Scale = item.DecimalDigits, TableName = tableName, DbColumnName = item.DbColumnName, DataType = item.DataType }; + if (result.DataType.IsNullOrEmpty()) + { + result.DataType = GetDatabaseTypeName(item.UnderType.Name); + } + return result; + } + + private STableAttribute GetCommonSTableAttribute(STableAttribute sTableAttribute) + { + return SqlSugar.TDengine.UtilMethods.GetCommonSTableAttribute(this.Context, sTableAttribute); + } + public string GetDatabaseTypeName(string typeName) + { + switch (typeName.ToLower()) + { + case "bool": + return "BOOL"; + case "datetime": + return "TIMESTAMP"; + case "boolean": + return "BOOL"; + case "byte": + return "TINYINT UNSIGNED"; + case "sbyte": + return "TINYINT"; + case "char": + return "NCHAR"; + case "decimal": + return "FLOAT"; + case "double": + return "DOUBLE"; + case "float": + case "single": + return "FLOAT"; + case "int": + return "INT"; + case "int32": + return "INT"; + case "int16": + return "INT"; + case "int64": + return "BIGINT"; + case "uint": + case "uint32": + return "INT UNSIGNED"; + case "long": + return "BIGINT"; + case "ulong": + case "uint64": + return "BIGINT UNSIGNED"; + case "short": + return "SMALLINT"; + case "ushort": + case "uint16": + return "SMALLINT UNSIGNED"; + case "string": + return "VARCHAR"; + // 添加其他类型的映射关系 + + default: + return "VARCHAR"; // 如果未识别到类型,则返回原始类型名称 + } + } + } +} \ No newline at end of file diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbBind/TDengineDbBind.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbBind/TDengineDbBind.cs new file mode 100644 index 000000000..b6fd0a75b --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbBind/TDengineDbBind.cs @@ -0,0 +1,146 @@ +namespace SqlSugar.TDengine +{ + public class TDengineDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "bytea"; + if (string.Equals(csharpTypeName, "int32", StringComparison.OrdinalIgnoreCase)) + csharpTypeName = "int"; + if (string.Equals(csharpTypeName, "int16", StringComparison.OrdinalIgnoreCase)) + csharpTypeName = "short"; + if (string.Equals(csharpTypeName, "int64", StringComparison.OrdinalIgnoreCase)) + csharpTypeName = "long"; + if (csharpTypeName.ToLower().IsIn("boolean", "bool")) + csharpTypeName = "bool"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + if (mappings?.Count > 0) + return mappings.First().Key; + else + return "varchar"; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + if (dbTypeName == "int32") + { + dbTypeName = "int"; + } + else if (dbTypeName == "int16") + { + dbTypeName = "short"; + } + else if (dbTypeName == "int64") + { + dbTypeName = "long"; + } + else if (dbTypeName == "string") + { + dbTypeName = "string"; + } + else if (dbTypeName == "boolean") + { + dbTypeName = "bool"; + } + else if (dbTypeName == "bool") + { + dbTypeName = "bool"; + } + else if (dbTypeName == "sbyte") + { + dbTypeName = "sbyte"; + } + else if (dbTypeName == "double") + { + dbTypeName = "double"; + } + else if (dbTypeName == "binary") + { + dbTypeName = "string"; + } + else if (dbTypeName == "timestamp") + { + dbTypeName = "DateTime"; + } + else if (dbTypeName == "bigint") + { + dbTypeName = "long"; + } + else if (dbTypeName == "char") + { + dbTypeName = "string"; + } + else if (dbTypeName == "smallint") + { + dbTypeName = "short"; + } + else if (dbTypeName == "int unsigned") + { + dbTypeName = "int"; + } + else if (dbTypeName == "bigint unsigned") + { + dbTypeName = "long"; + } + else if (dbTypeName == "tinyint unsigned") + { + dbTypeName = "byte"; + } + else if (TDengineDbBind.MappingTypesConst.FirstOrDefault(it => (it.Key).Equals(dbTypeName, StringComparison.CurrentCultureIgnoreCase)) is { } data) + { + dbTypeName = data.Value.ToString(); + } + else + { + + } + return dbTypeName; + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService?.AppendDataReaderTypeMappings.HasValue() == true) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("BOOL",CSharpDataType.@bool), + new KeyValuePair("TINYINT",CSharpDataType.@byte), + new KeyValuePair("TINYINT",CSharpDataType.@int), + new KeyValuePair("SMALLINT",CSharpDataType.@short), + new KeyValuePair("INT",CSharpDataType.@int), + new KeyValuePair("BIGINT",CSharpDataType.@long), + new KeyValuePair("TINYINT UNSIGNED",CSharpDataType.@byte), + new KeyValuePair("TINYINT UNSIGNED",CSharpDataType.@int), + new KeyValuePair("SMALLINT UNSIGNED",CSharpDataType.@short), + new KeyValuePair("INT UNSIGNED",CSharpDataType.@int), + new KeyValuePair("BIGINT UNSIGNED",CSharpDataType.@long), + new KeyValuePair("FLOAT",CSharpDataType.Single), + new KeyValuePair("DOUBLE",CSharpDataType.@double), + new KeyValuePair("float8",CSharpDataType.@double), + new KeyValuePair("BINARY",CSharpDataType.@string), + new KeyValuePair("TIMESTAMP",CSharpDataType.DateTime), + new KeyValuePair("NCHAR",CSharpDataType.@string), + new KeyValuePair("JSON",CSharpDataType.@string) + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbFirst/TDengineDbFirst.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbFirst/TDengineDbFirst.cs new file mode 100644 index 000000000..336286069 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbFirst/TDengineDbFirst.cs @@ -0,0 +1,6 @@ +namespace SqlSugar.TDengine +{ + public class TDengineDbFirst : DbFirstProvider + { + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbMaintenance/TDengineDbMaintenance.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbMaintenance/TDengineDbMaintenance.cs new file mode 100644 index 000000000..bae870b59 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/DbMaintenance/TDengineDbMaintenance.cs @@ -0,0 +1,588 @@ +using System.Data; +using System.Reflection; + +namespace SqlSugar.TDengine +{ + public class TDengineDbMaintenance : DbMaintenanceProvider + { + public EntityInfo EntityInfo { get; set; } + + #region DML + + protected override string GetViewInfoListSql => throw new NotImplementedException(); + protected override string GetDataBaseSql + { + get + { + return "show databases"; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + throw new NotSupportedException("TDengineCode暂时不支持DbFirst等方法,还在开发"); + } + } + + protected override string GetTableInfoListSql + { + get + { + return ""; + } + } + + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE IF NOT EXISTS {0} WAL_RETENTION_PERIOD 3600"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "alter table {0} MODIFY COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return "mysqldump.exe {0} -uroot -p > {1} "; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE STABLE IF NOT EXISTS {0}(\r\n{1} ) TAGS(" + SqlBuilder.GetTranslationColumnName("TagsTypeId") + " VARCHAR(100))"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {0} as (select * from {1} limit {2} offset 0)"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} RENAME {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 { throw new NotSupportedException(); } } + + protected override string AddTableRemarkSql => "comment on table {0} is '{1}'"; + + protected override string DeleteTableRemarkSql => "comment on table {0} is ''"; + + protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } } + + protected override string RenameTableSql => "alter table {0} to {1}"; + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}"; + } + } + protected override string IsAnyIndexSql + { + get + { + return " SELECT count(1) WHERE upper('{0}') IN ( SELECT upper(indexname) FROM pg_indexes )"; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "SHOW DATABASES"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return " "; + } + } + protected override string CreateTableNotNull + { + get + { + return " "; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "serial"; + } + } + #endregion + + #region Methods + public override List GetTableInfoList(bool isCache = true) + { + var sb = new List(); + + // 第一个循环:获取超级表名称 + var dt = GetSTables(); + foreach (DataRow item in dt.Rows) + { + sb.Add(item["stable_name"].ObjToString().ToSqlFilter()); + } + + // 第二个循环:获取子表名称 + var dt2 = GetTables(); + foreach (DataRow item in dt2.Rows) + { + sb.Add(item["table_name"].ObjToString().ToSqlFilter()); + } + var result = sb.Select(it => new DbTableInfo() { Name = it, DbObjectType = DbObjectType.Table }).ToList(); + return result; + } + public override bool AddColumn(string tableName, DbColumnInfo columnInfo) + { + if (columnInfo.DbColumnName == "TagsTypeId") + { + return true; + } + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var isAddNotNUll = columnInfo.IsNullable == false && columnInfo.DefaultValue.HasValue(); + if (isAddNotNUll) + { + columnInfo = this.Context.Utilities.TranslateCopy(columnInfo); + columnInfo.IsNullable = true; + } + string sql = GetAddColumnSql(tableName, columnInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override List GetViewInfoList(bool isCache = true) + { + return new List(); + } + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + var db = this.Context.CopyNew(); + db.Ado.Connection.ChangeDatabase(""); + var sql = CreateDataBaseSql; + if (this.Context.CurrentConnectionConfig.ConnectionString.Contains("config_us", StringComparison.OrdinalIgnoreCase)) + { + sql += " PRECISION 'us'"; + } + else if (this.Context.CurrentConnectionConfig.ConnectionString.Contains("config_ns", StringComparison.OrdinalIgnoreCase)) + { + sql += " PRECISION 'ns'"; + } + db.Ado.ExecuteCommand(string.Format(sql, databaseName)); + return true; + } + public override List GetIndexList(string tableName) + { + var sql = $"SELECT indexname, indexdef FROM pg_indexes WHERE upper(tablename) = upper('{tableName}')"; + return this.Context.Ado.SqlQuery(sql); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT proname FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname = '{dbName}'"; + return this.Context.Ado.SqlQuery(sql); + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + return base.AddDefaultValue(this.SqlBuilder.GetTranslationTableName(tableName), this.SqlBuilder.GetTranslationTableName(columnName), defaultValue); + } + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string sql = string.Format(this.AddColumnRemarkSql, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddTableRemark(string tableName, string description) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + return base.AddTableRemark(tableName, description); + } + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + string sql = GetUpdateColumnSql(tableName, columnInfo); + this.Context.Ado.ExecuteCommand(sql); + var isnull = columnInfo.IsNullable ? " DROP NOT NULL " : " SET NOT NULL "; + this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}", tableName, columnName, isnull)); + return true; + } + + protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + //if (!string.IsNullOrEmpty(dataType)) + //{ + // dataType = " type " + dataType; + //} + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + + public override bool AddRemark(EntityInfo entity) + { + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + item.Length = 10; + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower(isAutoToLowerCodeFirst))))); + + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + 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 = item.DbColumnName; + string dataType = item.DataType; + if (dataType == "varchar" && item.Length == 0) + { + item.Length = 1; + } + //if (dataType == "uuid") + //{ + // item.Length = 50; + // dataType = "varchar"; + //} + string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + //if (item.DecimalDigits > 0&&item.Length>0 && dataType?.ToLower()== "float") + //{ + // item.Length = 0; + // dataSize = $"({item.Length},{item.DecimalDigits})"; + //} + //if (item.DecimalDigits > 0 && item.Length > 0 && dataType?.ToLower() == "double") + //{ + + // dataSize = $"({item.Length},{item.DecimalDigits})"; + //} + //if (item.DecimalDigits > 0 && item.Length > 0 && dataType?.ToLower() == "decimal") + //{ + // dataSize = $"({item.Length},{item.DecimalDigits})"; + //} + //if (item.DecimalDigits == 0 && item.Length == 0 && dataType?.ToLower() == "float") + //{ + // dataType = $"FLOAT(18,4)"; + //} + //if (item.DecimalDigits == 0 && item.Length == 0 && dataType?.ToLower() == "double") + //{ + // dataType = $"DOUBLE(18,4)"; + //} + if (item.Length == 0 && dataType?.ToLower()?.IsIn("nchar", "varchar") == true) + { + dataType = "VARCHAR(200)"; + } + if (dataType?.ToLower()?.IsIn("float", "double") == true) + { + dataSize = null; + } + string primaryKey = null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), dataType, dataSize, null, primaryKey, ""); + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName("STable_" + tableName.ToLower(isAutoToLowerCodeFirst)), string.Join(",\r\n", columnArray)); + var childTableName = this.SqlBuilder.GetTranslationTableName(tableName.ToLower(isAutoToLowerCodeFirst)); + var stableName = this.SqlBuilder.GetTranslationTableName("STable_" + tableName.ToLower(isAutoToLowerCodeFirst)); + var isAttr = tableName.Contains("{stable}"); + var isTag1 = false; + if (isAttr) + { + var attr = this.Context.Utilities.DeserializeObject(tableName.Split("{stable}").Last()); + stableName = this.SqlBuilder.GetTranslationTableName(attr.STableName.ToLower(isAutoToLowerCodeFirst)); + tableString = string.Format(this.CreateTableSql, stableName, string.Join(",\r\n", columnArray)); + tableName = childTableName = this.SqlBuilder.GetTranslationTableName(tableName.Split("{stable}").First().ToLower(isAutoToLowerCodeFirst)); + if (attr.Tags == null && attr.Tag1 != null) + { + isTag1 = true; + STable.Tags = new List() { + new ColumnTagInfo(){ Name=attr.Tag1 }, + new ColumnTagInfo(){ Name=attr.Tag2 }, + new ColumnTagInfo(){ Name=attr.Tag3 }, + new ColumnTagInfo(){ Name=attr.Tag4 } + }.Where(it => it.Name.HasValue()).ToList(); + } + else + { + STable.Tags = this.Context.Utilities.DeserializeObject>(attr.Tags); + } + } + if (STable.Tags?.Count > 0) + { + var colums = STable.Tags.Select(it => this.SqlBuilder.GetTranslationTableName(it.Name) + " VARCHAR(100) "); + tableString = tableString.Replace(SqlBuilder.GetTranslationColumnName("TagsTypeId"), string.Join(",", colums)); + tableString = tableString.Replace(" VARCHAR(100) VARCHAR(100)", " VARCHAR(100)"); + if (this.EntityInfo != null) + { + foreach (var item in STable.Tags) + { + var tagColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.DbColumnName == item.Name || it.PropertyName == item.Name); + if (tagColumn != null && tagColumn.UnderType != UtilConstants.StringType) + { + var tagType = new TDengineDbBind() { Context = this.Context }.GetDbTypeName(tagColumn.UnderType.Name); + tableString = tableString.Replace($"{SqlBuilder.GetTranslationColumnName(tagColumn.DbColumnName)} VARCHAR(100)", $"{SqlBuilder.GetTranslationColumnName(tagColumn.DbColumnName)} {tagType} "); + } + else if (tagColumn != null && tagColumn.UnderType == UtilConstants.StringType && tagColumn.Length < 100 && tagColumn.Length > 0) + { + tableString = tableString.Replace($"{SqlBuilder.GetTranslationColumnName(tagColumn.DbColumnName)} VARCHAR(100)", $"{SqlBuilder.GetTranslationColumnName(tagColumn.DbColumnName)} VARCHAR({tagColumn.Length}) "); + } + } + } + } + this.Context.Ado.ExecuteCommand(tableString); + var createChildSql = $"CREATE TABLE IF NOT EXISTS {childTableName} USING {stableName} TAGS('default')"; + if (STable.Tags?.Count > 0) + { + var colums = STable.Tags.Select(it => it.Value.ToSqlValue()); + createChildSql = createChildSql.Replace("TAGS('default')", $"TAGS({string.Join(",", colums)})"); + } + if (isTag1) + { + //No create child table + } + else + { + this.Context.Ado.ExecuteCommand(createChildSql); + } + return tableString; + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported"); + return false; + } + public override void AddDefaultValue(EntityInfo entityInfo) + { + var talbeName = entityInfo.DbTableName; + var attr = GetCommonSTableAttribute(entityInfo.Type.GetCustomAttribute()); + if (attr?.Tag1 != null) + { + talbeName = attr.STableName; + } + var dbColumns = this.GetColumnInfosByTableName(talbeName, false); + var db = this.Context; + var columns = entityInfo.Columns.Where(it => it.IsIgnore == false).ToList(); + foreach (var item in columns) + { + if (item.DefaultValue.HasValue()) + { + if (!IsAnyDefaultValue(entityInfo.DbTableName, item.DbColumnName, dbColumns)) + { + this.AddDefaultValue(entityInfo.DbTableName, item.DbColumnName, item.DefaultValue); + } + } + } + } + + private STableAttribute GetCommonSTableAttribute(STableAttribute sTableAttribute) + { + return SqlSugar.TDengine.UtilMethods.GetCommonSTableAttribute(this.Context, sTableAttribute); + } + + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + + var sql = $"select * from {this.SqlBuilder.GetTranslationColumnName(tableName)} where 1=2 "; + List result = new List(); + DataTable dt = null; + try + { + dt = this.Context.Ado.GetDataTable(sql); + } + catch (Exception) + { + sql = $"select * from `{tableName}` where 1=2 "; + dt = this.Context.Ado.GetDataTable(sql); + } + foreach (DataColumn item in dt.Columns) + { + var addItem = new DbColumnInfo() + { + DbColumnName = item.ColumnName, + DataType = item.DataType.Name + }; + result.Add(addItem); + } + if (result.Count(it => it.DataType == "DateTime") == 1) + { + result.First(it => it.DataType == "DateTime").IsPrimarykey = true; + } + return result; + } + #endregion + + #region Helper + private bool isAutoToLowerCodeFirst + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true; + else if ( + this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower == false && + this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLowerCodeFirst == false) + { + return false; + } + else + { + return true; + } + } + } + + private string GetSchema() + { + var schema = "public"; + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + + return schema; + } + + private DataTable GetTables() + { + return this.Context.Ado.GetDataTable("SHOW TABLES"); + } + + private DataTable GetSTables() + { + return this.Context.Ado.GetDataTable("SHOW STABLES"); + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Insertable/TDengineInserttable.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Insertable/TDengineInserttable.cs new file mode 100644 index 000000000..8aa27c6d0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Insertable/TDengineInserttable.cs @@ -0,0 +1,90 @@ +namespace SqlSugar.TDengine +{ + public class TDengineInsertable : InsertableProvider where T : class, new() + { + public override int ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string identityColumn = GetIdentityColumn(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn)); + RestoreMapping(); + var result = Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ObjToInt(); + After(sql, result); + return result; + } + public override async Task ExecuteReturnIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string identityColumn = GetIdentityColumn(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn)); + RestoreMapping(); + var obj = await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false); + var result = obj.ObjToInt(); + After(sql, result); + return result; + } + public override KeyValuePair> ToSql() + { + var result = base.ToSql(); + var primaryKey = GetPrimaryKeys().FirstOrDefault(); + if (primaryKey != null) + { + primaryKey = this.SqlBuilder.GetTranslationColumnName(primaryKey); + } + return new KeyValuePair>(result.Key.Replace("$PrimaryKey", primaryKey), result.Value); + } + + public override long ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + var result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0"); + After(sql, result); + return result; + } + public override async Task ExecuteReturnBigIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + var result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ConfigureAwait(false) ?? "0"); + After(sql, result); + return result; + } + + public override bool ExecuteCommandIdentityIntoEntity() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (identityKeys.Count == 0) { return this.ExecuteCommand() > 0; } + var idValue = ExecuteReturnBigIdentity(); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else + setValue = Convert.ToInt32(idValue); + var propertyName = this.Context.EntityMaintenance.GetPropertyName(identityKey); + typeof(T).GetProperties().First(t => string.Equals(t.Name, propertyName, StringComparison.OrdinalIgnoreCase)).SetValue(result, setValue, null); + return idValue > 0; + } + + private string GetIdentityColumn() + { + var identityColumn = GetIdentityKeys().FirstOrDefault(); + if (identityColumn == null) + { + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(InsertBuilder.GetTableNameString); + identityColumn = columns.First(it => it.IsIdentity || it.IsPrimarykey).DbColumnName; + } + return identityColumn; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Insertable/TagInserttable.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Insertable/TagInserttable.cs new file mode 100644 index 000000000..ce5dd2ce0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Insertable/TagInserttable.cs @@ -0,0 +1,129 @@ +using SqlSugar.TDengine; + +using System.Reflection; + +namespace SqlSugar +{ + public class TagInserttable where T : class, new() + { + internal IInsertable thisValue; + internal Func getChildTableNamefunc; + + internal SqlSugarProvider Context; + + public int ExecuteCommand() + { + var provider = (InsertableProvider)thisValue; + var inserObjects = provider.InsertObjs; + var attr = GetCommonSTableAttribute(typeof(T).GetCustomAttribute()); + Check.ExceptionEasy(attr == null || attr?.Tag1 == null, $"", $"{nameof(T)}缺少特性STableAttribute和Tag1"); + // 根据所有非空的 Tag 进行分组 + var groups = GetGroupInfos(inserObjects, attr); + foreach (var item in groups) + { + var childTableName = getChildTableNamefunc(attr.STableName, item.First()); + this.Context.Utilities.PageEach(item, 500, pageItems => + { + var sTableName = provider.SqlBuilder.GetTranslationColumnName(attr.STableName); + var tags = new List(); + List tagValues = GetTagValues(pageItems, attr); + var tagString = string.Join(",", tagValues.Where(v => !string.IsNullOrEmpty(v)).Select(v => $"'{v.ToSqlFilter()}'")); + tags.Add(tagString); + this.Context.Ado.ExecuteCommand($"CREATE TABLE IF NOT EXISTS {childTableName} USING {sTableName} TAGS ({tagString})"); + this.Context.Insertable(pageItems).IgnoreColumns(GetTagNames(pageItems.First(), attr).ToArray()).AS(childTableName).ExecuteCommand(); + }); + } + return inserObjects.Length; + } + + public async Task ExecuteCommandAsync() + { + var provider = (InsertableProvider)thisValue; + var inserObjects = provider.InsertObjs; + var attr = GetCommonSTableAttribute(typeof(T).GetCustomAttribute()); + Check.ExceptionEasy(attr == null || attr?.Tag1 == null, $"", $"{nameof(T)}缺少特性STableAttribute和Tag1"); + // 根据所有非空的 Tag 进行分组 + var groups = GetGroupInfos(inserObjects, attr); + foreach (var item in groups) + { + var childTableName = getChildTableNamefunc(attr.STableName, item.First()); + await this.Context.Utilities.PageEachAsync(item, 500, async pageItems => + { + var sTableName = provider.SqlBuilder.GetTranslationColumnName(attr.STableName); + var tags = new List(); + List tagValues = GetTagValues(pageItems, attr); + var tagString = string.Join(",", tagValues.Where(v => !string.IsNullOrEmpty(v)).Select(v => $"'{v.ToSqlFilter()}'")); + tags.Add(tagString); + await Context.Ado.ExecuteCommandAsync($"CREATE TABLE IF NOT EXISTS {childTableName} USING {sTableName} TAGS ({tagString})").ConfigureAwait(false); + await Context.Insertable(pageItems).IgnoreColumns(GetTagNames(pageItems.First(), attr).ToArray()).AS(childTableName).ExecuteCommandAsync().ConfigureAwait(false); + }).ConfigureAwait(false); + } + return inserObjects.Length; + } + + private static List GetTagValues(List pageItems, STableAttribute attr) + { + var tagValues = new List(); + var obj = pageItems.First(); + if (attr.Tag1 != null) + tagValues.Add(obj.GetType().GetProperty(attr.Tag1)?.GetValue(obj)?.ToString()); + + if (attr.Tag2 != null) + tagValues.Add(obj.GetType().GetProperty(attr.Tag2)?.GetValue(obj)?.ToString()); + + if (attr.Tag3 != null) + tagValues.Add(obj.GetType().GetProperty(attr.Tag3)?.GetValue(obj)?.ToString()); + + if (attr.Tag4 != null) + tagValues.Add(obj.GetType().GetProperty(attr.Tag4)?.GetValue(obj)?.ToString()); + return tagValues; + } + + private static List GetTagNames(T obj, STableAttribute attr) + { + var tagValues = new List(); + if (attr.Tag1 != null) + tagValues.Add(attr.Tag1); + + if (attr.Tag2 != null) + tagValues.Add(attr.Tag2); + + if (attr.Tag3 != null) + tagValues.Add(attr.Tag3); + + if (attr.Tag4 != null) + tagValues.Add(attr.Tag4); + return tagValues; + } + + private static IEnumerable> GetGroupInfos(T[] inserObjects, STableAttribute? attr) + { + var groups = inserObjects.GroupBy(it => + { + // 动态生成分组键 + var groupKey = new List(); + + if (attr.Tag1 != null) + groupKey.Add(it.GetType().GetProperty(attr.Tag1)?.GetValue(it)?.ToString()); + + if (attr.Tag2 != null) + groupKey.Add(it.GetType().GetProperty(attr.Tag2)?.GetValue(it)?.ToString()); + + if (attr.Tag3 != null) + groupKey.Add(it.GetType().GetProperty(attr.Tag3)?.GetValue(it)?.ToString()); + + if (attr.Tag4 != null) + groupKey.Add(it.GetType().GetProperty(attr.Tag4)?.GetValue(it)?.ToString()); + + // 将非空的 Tag 值用下划线连接作为分组键 + return string.Join("_", groupKey.Where(k => !string.IsNullOrEmpty(k))); + }); + return groups; + } + private STableAttribute GetCommonSTableAttribute(STableAttribute sTableAttribute) + { + return SqlSugar.TDengine.UtilMethods.GetCommonSTableAttribute(this.Context, sTableAttribute); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Queryable/TDengineSqlQueryable.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Queryable/TDengineSqlQueryable.cs new file mode 100644 index 000000000..5d1129b5d --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/Queryable/TDengineSqlQueryable.cs @@ -0,0 +1,63 @@ +namespace SqlSugar.TDengine +{ + public class TDengineQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + this.GroupBy(groupFileds); + return this; + } + } + public class TDengineQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } + public class TDengineQueryable : QueryableProvider + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineBuilder.cs new file mode 100644 index 000000000..dfe78013a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineBuilder.cs @@ -0,0 +1,133 @@ +namespace SqlSugar.TDengine +{ + public class TDengineBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft + { + get + { + return "`"; + } + } + public override string SqlTranslationRight + { + get + { + return "`"; + } + } + public override string SqlDateNow + { + get + { + return "current_date"; + } + } + public override string FullSqlDateNow + { + get + { + return " now() "; + } + } + + public bool isAutoToLower + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true; + else if ( + this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower == false && + this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLowerCodeFirst == false) + { + return false; + } + else + { + return true; + } + } + } + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains('.') && !propertyName.Contains(SqlTranslationLeft)) + { + return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToLower(isAutoToLower)}{SqlTranslationRight}")); + } + + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + else + return SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight; + } + + //public override string GetNoTranslationColumnName(string name) + //{ + // return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower(); + //} + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToLower(isAutoToLower) + SqlTranslationRight); + } + + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + var context = this.Context; + + var mappingInfo = context + .MappingTables + .FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo == null && name.Contains('.') && name.Contains('`')) + { + return name; + } + name = (mappingInfo == null ? name : mappingInfo.DbTableName); + if (name.Contains('.') && !name.Contains('(') && !name.Contains("\".\"")) + { + return string.Join(".", name.ToLower(isAutoToLower).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else if (name.Contains('(')) + { + return name; + } + else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else + { + return SqlTranslationLeft + name.ToLower(isAutoToLower).TrimEnd('"').TrimStart('"') + SqlTranslationRight; + } + } + public override string GetUnionFomatSql(string sql) + { + return " ( " + sql + " ) "; + } + + public override Type GetNullType(string tableName, string columnName) + { + if (tableName != null) + tableName = tableName.Trim(); + var columnInfo = this.Context.DbMaintenance.GetColumnInfosByTableName(tableName).FirstOrDefault(z => z.DbColumnName?.ToLower() == columnName?.ToLower()); + if (columnInfo != null) + { + var cTypeName = this.Context.Ado.DbBind.GetCsharpTypeNameByDbTypeName(columnInfo.DataType); + var value = SqlSugar.UtilMethods.GetTypeByTypeName(cTypeName); + if (value != null) + { + var key = "GetNullType_" + tableName + columnName; + return new ReflectionInoCacheService().GetOrCreate(key, () => value); + } + } + return null; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineDeleteBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineDeleteBuilder.cs new file mode 100644 index 000000000..b8eed82e4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar.TDengine +{ + public class TDengineDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineExpressionContext.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineExpressionContext.cs new file mode 100644 index 000000000..51cd249e2 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineExpressionContext.cs @@ -0,0 +1,444 @@ +using Dm.util; +namespace SqlSugar.TDengine +{ + public class TDengineExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public TDengineExpressionContext() + { + base.DbMehtods = new TDengineExpressionContextMethod(); + } + public override string SqlTranslationLeft + { + get + { + return "`"; + } + } + public override string SqlTranslationRight + { + get + { + return "`"; + } + } + public override string GetTranslationText(string name) + { + return SqlTranslationLeft + name.ToLower(isAutoToLower) + SqlTranslationRight; + } + public bool isAutoToLower + { + get + { + return base.PgSqlIsAutoToLower; + } + } + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + + var tableName = mappingInfo?.DbTableName + ""; + if (tableName.Contains('.')) + { + tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + return tableName; + } + + return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToLower(isAutoToLower) + SqlTranslationRight; + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public override string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(null, ErrorMessage.ObjNotExistCompositeFormat, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord) + { + return columnName; + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public override string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToLower(isAutoToLower); + } + else + { + return propertyName.ToLower(isAutoToLower); + } + } + + public string GetValue(object entityValue) + { + if (entityValue == null) + return null; + var type = UtilMethods.GetUnderType(entityValue.GetType()); + if (UtilConstants.NumericalTypes.Contains(type)) + { + return entityValue.ToString(); + } + else if (type == UtilConstants.DateType) + { + return this.DbMehtods.ToDate(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + else + { + return this.DbMehtods.ToString(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + } + } + public class TDengineExpressionContextMethod : DefaultDbMethod, IDbMethods + { + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string TrueValue() + { + return "true"; + } + public override string FalseValue() + { + return "false"; + } + + public override string Substring(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter2.MemberValue is int && parameter3.MemberValue is int) + { + model.Parameters.RemoveAll(it => it.ParameterName.Equals(parameter2.MemberName) || it.ParameterName.Equals(parameter3.MemberName)); + return string.Format("SUBSTR({0},{1},{2})", parameter.MemberName, Convert.ToInt32(parameter2.MemberValue) + 1, parameter3.MemberValue); + } + else + { + return string.Format("SUBSTR({0},{1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + } + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" TIMEDIFF({1},{2},1{0}) ", parameter.MemberValue.ObjToString().ToLower().First(), parameter2.MemberName, parameter3.MemberName); + } + public override string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter.Type == UtilConstants.BoolType) + { + parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); + parameter2.MemberName = false; + parameter3.MemberName = true; + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var format = parameter2.MemberValue.ObjToString(); + return string.Format(" {0}({1}) ", format, parameter.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.MemberValue + "%").ToSqlValue()); + } + + 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.MemberValue).ToSqlValue()); + } + + 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.MemberValue + "%").ToSqlValue()); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL )", parameter.MemberName); + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + DateType dateType = (DateType)parameter3.MemberValue; + var format = "yyyy-MM-dd"; + if (dateType == DateType.Quarter) + { + return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName, format); + } + switch (dateType) + { + case DateType.Year: + format = "yyyy"; + break; + case DateType.Month: + format = "yyyy-MM"; + break; + case DateType.Day: + break; + case DateType.Hour: + format = "yyyy-MM-dd HH"; + break; + case DateType.Second: + format = "yyyy-MM-dd HH:mm:ss"; + break; + case DateType.Minute: + format = "yyyy-MM-dd HH:mm"; + break; + case DateType.Millisecond: + format = "yyyy-MM-dd HH:mm.ms"; + break; + default: + break; + } + return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS timestamp)", parameter.MemberName); + } + public override string ToDateShort(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST( SUBSTR(TO_ISO8601({0}),1,10) AS timestamp)", parameter.MemberName); + } + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + var result = string.Format(" {1}+{2}{0} ", parameter3.MemberValue.ObjToString().ToLower().First(), parameter.MemberName, parameter2.MemberValue); + return result.replace("+-", "-"); + } + + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} + ({1}||'day')::INTERVAL) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT4)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT8)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS UUID)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DOUBLE)", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS boolean)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DOUBLE)", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string MergeString(params string[] strings) + { + return " concat(" + string.Join(",", strings).Replace("+", "") + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName); + } + public override string GetDate() + { + return "NOW()"; + } + public override string GetRandom() + { + return "RANDOM()"; + } + + public override string EqualTrue(string fieldName) + { + return "( " + fieldName + "=true )"; + } + + public override string JsonField(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + //var parameter2 = model.Args[2]; + //var parameter3= model.Args[3]; + var result = GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count == 2); + if (model.Args.Count > 2) + { + result = GetJson(result, model.Args[2].MemberName, model.Args.Count == 3); + } + if (model.Args.Count > 3) + { + result = GetJson(result, model.Args[3].MemberName, model.Args.Count == 4); + } + if (model.Args.Count > 4) + { + result = GetJson(result, model.Args[4].MemberName, model.Args.Count == 5); + } + if (model.Args.Count > 5) + { + result = GetJson(result, model.Args[5].MemberName, model.Args.Count == 6); + } + return result; + } + + public override string JsonContainsFieldName(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})"; + } + + private string GetJson(object memberName1, object memberName2, bool isLast) + { + if (isLast) + { + return $"({memberName1}::json->>{memberName2})"; + } + else + { + return $"({memberName1}->{memberName2})"; + } + } + + public override string JsonArrayLength(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" json_array_length({parameter.MemberName}::json) "; + } + + public override string JsonParse(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" ({parameter.MemberName}::json) "; + } + + public override string JsonArrayAny(MethodCallExpressionModel model) + { + if (SqlSugar.UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name)) + { + return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb"; + } + else + { + return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb"; + } + } + public override string JsonListObjectAny(MethodCallExpressionModel model) + { + if (SqlSugar.UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) + { + return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}]'::jsonb"; + } + else + { + return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}]'::jsonb"; + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineFastBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineFastBuilder.cs new file mode 100644 index 000000000..9a22d14fd --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineFastBuilder.cs @@ -0,0 +1,218 @@ + +using SqlSugar.TDengineAdo; + +using System.Data; +using System.Globalization; +using System.Text; + +namespace SqlSugar.TDengine +{ + public class TDengineFastBuilder : FastBuilder, IFastBuilder + { + public const string TagKey = "TDengineFastBuilderTagNames"; + public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() + { + NoPage = true + }; + + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + // 移除自增列 + var identities = this.FastEntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); + foreach (var identity in identities) + { + if (dt.Columns.Contains(identity)) + { + dt.Columns.Remove(identity); + } + } + var db = this.Context; + string[] tagNames = null; + if (db.TempItems?.ContainsKey(TagKey) == true) + { + tagNames = db.TempItems[TagKey] as string[]; + } + await BulkInsertToTDengine((TDengineConnection)Context.Ado.Connection, dt.TableName, dt, Context.Ado.IsNoTran(), tagNames).ConfigureAwait(false); + return dt.Rows.Count; + } + + public async Task BulkInsertToTDengine(TDengineConnection conn, string tableName, DataTable table, bool isTran, string[] tagColumns) + { + + string insertSql = string.Empty; + try + { + + if (tagColumns?.Length > 0) + { + StringBuilder sb = new StringBuilder(); + StringBuilder sbTables = new StringBuilder(); + // 创建一个列名映射(忽略大小写) + var columnMap = table.Columns.Cast() + .ToDictionary(c => c.ColumnName, c => c, StringComparer.OrdinalIgnoreCase); + + // 检查所有 tagColumns 是否在 DataTable 中存在 + foreach (var col in tagColumns) + { + if (!columnMap.ContainsKey(col)) + throw new Exception($"Column '{col}' not found in DataTable."); + } + + // 用 LINQ 分组 + var groups = table.AsEnumerable() + .GroupBy(row => string.Join("||", tagColumns.Select(tc => row[columnMap[tc]].ToString()))); + + foreach (var group in groups) + { + // 构建一个新的子表(结构与原表一致) + DataTable childTable = table.Clone(); + + // 将分组行复制到子表中 + foreach (var row in group) + { + childTable.ImportRow(row); + } + + // 调用 InsertChildTable + InsertChildTable(tableName, childTable, tagColumns, sb, sbTables); + + var sql = sb.ToString(); + var result = await Context.Ado.ExecuteCommandAsync(sql).ConfigureAwait(false); + sb.Clear(); + } + } + else + { + // Build the column names and value placeholders + var valuePlaceholdersList = table.Rows.Cast().Select(row => + { + var values = row.ItemArray.Select(item => FormatValue(item)).ToList(); + return $"({string.Join(", ", values)})"; + }).ToList(); + + var valuePlaceholders = string.Join(", ", valuePlaceholdersList); + // Construct SQL without tags + var columnNames = string.Join(", ", table.Columns.Cast().Select(c => c.ColumnName)); + insertSql = $"INSERT INTO {tableName} ({columnNames}) VALUES {valuePlaceholders}"; + + // Execute the command asynchronously + await Context.Ado.ExecuteCommandAsync(insertSql).ConfigureAwait(false); + } + } + catch (Exception ex) + { + throw new Exception(ex.Message + "\r\n" + insertSql); + } + finally + { + this.Context.TempItems.Remove(TagKey); + } + } + + private StringBuilder InsertChildTable(string tableName, DataTable table, string[] tagColumns, StringBuilder sb, StringBuilder sbtables) + { + var builder = InstanceFactory.GetSqlBuilderWithContext(this.Context); + var columnMap = table.Columns.Cast() + .ToDictionary(c => c.ColumnName, c => c.ColumnName, StringComparer.OrdinalIgnoreCase); + + var firstRow = table.Rows[0]; + string tags = string.Join(", ", tagColumns.Select(tag => FormatValue(firstRow[columnMap[tag]]))); + string tagsValues = string.Join("_", tagColumns.Select(tag => firstRow[columnMap[tag]].ToString())); + + // 移除标签列,只留下数据列 + foreach (var item in tagColumns) + { + table.Columns.Remove(item); + } + + var columnNames = string.Join(", ", table.Columns.Cast() + .Select(c => builder.GetTranslationColumnName(c.ColumnName))); + + var action = this.Context.TempItems[TagKey + "action"] as Func; + var subTableName = builder.GetTranslationColumnName(action(tagsValues, tableName.Replace("`", ""))); + + // sbtables.AppendLine($"CREATE TABLE {subTableName} USING {tableName} TAGS({tags});"); + + var sqlBuilder = sb; + var valuesList = new List(); + + foreach (DataRow row in table.Rows) + { + var values = row.ItemArray.Select(item => FormatValue(item)).ToList(); + var valuePart = $"({string.Join(", ", values)})"; + valuesList.Add(valuePart); + } + + if (valuesList.Count > 0) + { + string insertSql = $"INSERT INTO {subTableName} USING {tableName} TAGS({tags}) ({columnNames}) VALUES {string.Join(", ", valuesList)};"; + sqlBuilder.AppendLine(insertSql); + } + + return sqlBuilder; + } + + + public static void SetTags(ISqlSugarClient db, Func action, params string[] tagNames) + { + if (db.TempItems == null) + { + db.TempItems = new Dictionary(); + } + // 删除旧的值(如果存在) + db.TempItems.Remove(TagKey); + db.TempItems.Remove(TagKey + "action"); + db.TempItems.Add(TagKey, tagNames); + db.TempItems.Add(TagKey + "action", action); + } + + public object FormatValue(object value) + { + if (value == null || value == DBNull.Value) + { + return "NULL"; + } + else + { + var type = value.GetType(); + if (type == UtilConstants.DateType) + { + return Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss.fffffff").ToSqlValue(); + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + 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 if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else if (value is decimal v) + { + return v.ToString(CultureInfo.InvariantCulture); + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineInsertBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineInsertBuilder.cs new file mode 100644 index 000000000..1bae0573a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineInsertBuilder.cs @@ -0,0 +1,184 @@ +using System.Text; + +namespace SqlSugar.TDengine +{ + public class TDengineInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) "; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2})"; + + } + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + public override string SqlTemplateBatchUnion => " VALUES "; + + public override string SqlTemplateBatchSelect => " {0} "; + + public override Func ConvertInsertReturnIdFunc { get; set; } = (name, sql) => + { + return sql.Trim().TrimEnd(';') + $"returning {name} "; + }; + 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))); + ActionMinDate(); + return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 10000000; + int pageIndex = 1; + if (IsNoPage && IsReturnPkList) + { + pageSize = groupList.Count; + } + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + 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 ( " + string.Join(",", columns.Select(it => + { + if (it.InsertServerTime || it.InsertSql.HasValue() || it.SqlParameterDbType is Type || it?.PropertyType?.Name == "DateOnly" || it?.PropertyType?.Name == "TimeOnly") + { + if (it.InsertServerTime) + { + return DateTime.Now.AddMilliseconds(i).ToString("yyyy-MM-dd HH:mm:ss.ffffff").ToSqlValue(); + } + return GetDbColumn(it, null); + } + object value = null; + if (it?.Value is DateTime) + { + value = it.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + else if (it?.Value is bool) + { + value = it.Value?.ToString()?.ToLower(); + } + else if (it.Value is DateTimeOffset) + { + return FormatDateTimeOffset(it.Value); + } + else if (it.IsArray && it.Value != null) + { + return FormatValue(it.Value, it.PropertyName, i, it); + } + else + { + value = it.Value; + } + if (value == null || value == DBNull.Value) + { + return string.Format(SqlTemplateBatchSelect, "NULL"); + } + return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToStringNoTrim().ToSqlFilter() + "'"); + })) + "),"); + ++i; + } + pageIndex++; + batchInsetrSql.Remove(batchInsetrSql.Length - 1, 1).Append("\r\n;\r\n"); + } + return batchInsetrSql.ToString(); + } + } + + public object FormatValue(object value, string name, int i, DbColumnInfo columnInfo) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = value.GetType(); + if (type == UtilConstants.DateType || columnInfo.IsArray || columnInfo.IsJson) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + var paramter = new SugarParameter(parameterName, value); + if (columnInfo.IsJson) + { + paramter.IsJson = true; + } + if (columnInfo.IsArray) + { + paramter.IsArray = true; + } + this.Parameters.Add(paramter); + return parameterName; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + 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.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineQueryBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineQueryBuilder.cs new file mode 100644 index 000000000..fca351ab3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineQueryBuilder.cs @@ -0,0 +1,120 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDengine +{ + public partial class TDengineQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 10 offset 0 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {6} offset {5}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override string GetTableNameString + { + get + { + if (this.TableShortName != null && this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower == false) + { + this.TableShortName = Builder.GetTranslationColumnName(this.TableShortName); + } + return base.GetTableNameString; + } + } + public override bool IsComplexModel(string sql) + { + return 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 (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; + } + + #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?.Count > 0) + { + result = SubToListMethod(result); + } + return result; + } + } + + #endregion + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineUpdateBuilder.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineUpdateBuilder.cs new file mode 100644 index 000000000..50ec566cb --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/SqlBuilder/TDengineUpdateBuilder.cs @@ -0,0 +1,16 @@ +namespace SqlSugar.TDengine +{ + public class TDengineUpdateBuilder : UpdateBuilder + { + public override string ToSqlString() + { + throw new NotSupportedException("TDengine库不支持更新操作"); + } + protected override string TomultipleSqlString(List> groupList) + { + throw new NotSupportedException("TDengine库不支持更新操作"); + } + + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/TDengineProvider.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/TDengineProvider.cs new file mode 100644 index 000000000..8d2db64b4 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengine/TDengineProvider.cs @@ -0,0 +1,124 @@ +using SqlSugar.TDengineAdo; + +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; +namespace SqlSugar.TDengine +{ + public partial class TDengineProvider : AdoProvider + { + public TDengineProvider() + { + + + } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + var TDengineConnectionString = base.Context.CurrentConnectionConfig.ConnectionString; + TDengineConnectionString = Regex.Replace(TDengineConnectionString, @"\;db\=", ";Database=", RegexOptions.IgnoreCase); + base._DbConnection = new TDengineConnection(TDengineConnectionString); + } + catch (Exception) + { + throw; + + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + public override void BeginTran() + { + + } + + public override void BeginTran(string transactionName) + { + + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + + } + public override IDataAdapter GetAdapter() + { + return new SqlSugar.TDengineCore.TDengineDataAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + TDengineCommand sqlCommand = new TDengineCommand(sql, (TDengineConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + //if (this.Transaction != null) + //{ + // sqlCommand.Transaction = (TDengineTransaction)this.Transaction; + //} + if (parameters.HasValue()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((TDengineParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((SqlSugar.TDengineCore.TDengineDataAdapter)dataAdapter).SelectCommand = (TDengineCommand)command; + } + public static bool _IsIsNanosecond { get; set; } + public static bool _IsMicrosecond { get; set; } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + TDengineParameter[] result = new TDengineParameter[parameters.Length]; + int i = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + if (parameter.Value is bool) + { + parameter.Value = parameter.Value?.ToString()?.ToLower(); + } + var sqlParameter = new TDengineParameter(parameter.ParameterName, parameter.Value, parameter.DbType, 0); + if (parameter.CustomDbType?.Equals(System.Data.DbType.DateTime2) == true || (parameter.Value is DateTime && _IsMicrosecond)) + { + sqlParameter.IsMicrosecond = true; + } + else if (parameter.CustomDbType?.Equals(typeof(Date19)) == true || (parameter.Value is DateTime && _IsIsNanosecond)) + { + sqlParameter.IsNanosecond = true; + } + else if (parameter.Value is DateTime && this.Context.CurrentConnectionConfig.ConnectionString.Contains("config_")) + { + _IsIsNanosecond = sqlParameter.IsNanosecond = this.Context.CurrentConnectionConfig.ConnectionString.Contains("config_ns"); + _IsMicrosecond = sqlParameter.IsMicrosecond = this.Context.CurrentConnectionConfig.ConnectionString.Contains("config_us"); + } + result[i] = sqlParameter; + i++; + } + return result; + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengineDataAdapter.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengineDataAdapter.cs new file mode 100644 index 000000000..ac68a5c7a --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/TDengineDataAdapter.cs @@ -0,0 +1,173 @@ +using SqlSugar.TDengineAdo; + +using System.Data; +using System.Data.Common; +using System.Text; + +namespace SqlSugar.TDengineCore +{ + /// + /// 数据填充器 + /// + public class TDengineDataAdapter : IDataAdapter + { + private TDengineCommand command; + private string sql; + private TDengineConnection _TDengineConnection; + + /// + /// SqlDataAdapter + /// + /// + public TDengineDataAdapter(TDengineCommand command) + { + this.command = command; + } + + public TDengineDataAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public TDengineDataAdapter(string sql, TDengineConnection _TDengineConnection) + { + this.sql = sql; + this._TDengineConnection = _TDengineConnection; + } + + /// + /// SelectCommand + /// + public TDengineCommand SelectCommand + { + get + { + if (this.command == null) + { + this.command = new TDengineCommand(this.sql, this._TDengineConnection); + } + return this.command; + } + set + { + this.command = value; + } + } + + public MissingMappingAction MissingMappingAction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public MissingSchemaAction MissingSchemaAction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public ITableMappingCollection TableMappings => throw new NotImplementedException(); + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (DbDataReader dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (DbDataReader dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + var type = dr.GetFieldType(i); + if (type == UtilConstants.ByteArrayType) + { + type = UtilConstants.StringType; + } + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, type)); + else + { + columns.Add(new DataColumn(name + i, type)); + } + + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + var value = dr.GetValue(i); + if (value is byte[]) + { + daRow[columns[i].ColumnName] = Encoding.UTF8.GetString((byte[])value); + } + else + { + if (value == null) + { + value = DBNull.Value; + } + daRow[columns[i].ColumnName] = value; + } + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + + public DataTable[] FillSchema(DataSet dataSet, SchemaType schemaType) + { + throw new NotImplementedException(); + } + + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/DateTime16.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/DateTime16.cs new file mode 100644 index 000000000..f0ac157a9 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/DateTime16.cs @@ -0,0 +1,21 @@ +using System.Data; + +namespace SqlSugar +{ + public class DateTime16 : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + var name = "@Common" + columnIndex; + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + return new SugarParameter(name, columnValue, undertype) { CustomDbType = System.Data.DbType.DateTime2 }; + } + + public T QueryConverter(IDataRecord dr, int i) + { + + var value = dr.GetValue(i); + return (T)UtilMethods.ChangeType2(value, typeof(T)); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/DateTime19.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/DateTime19.cs new file mode 100644 index 000000000..e24e7c0a0 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/DateTime19.cs @@ -0,0 +1,25 @@ +using System.Data; + +namespace SqlSugar +{ + internal enum Date19 + { + time = 19 + } + public class DateTime19 : ISugarDataConverter + { + public SugarParameter ParameterConverter(object columnValue, int columnIndex) + { + var name = "@Common" + columnIndex; + Type undertype = SqlSugar.UtilMethods.GetUnderType(typeof(T));//获取没有nullable的枚举类型 + return new SugarParameter(name, columnValue, undertype) { CustomDbType = typeof(Date19) }; + } + + public T QueryConverter(IDataRecord dr, int i) + { + + var value = dr.GetValue(i); + return (T)UtilMethods.ChangeType2(value, typeof(T)); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/FileHelper.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/FileHelper.cs new file mode 100644 index 000000000..5ed3a34e3 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/FileHelper.cs @@ -0,0 +1,66 @@ +using System.Text; + +namespace SqlSugar.TDengine +{ + internal static 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); + + //Create File + FileInfo file = new FileInfo(filePath); + using (FileStream stream = file.Create()) + { + using (StreamWriter writer = new StreamWriter(stream, encoding)) + { + writer.Write(text); + writer.Flush(); + } + } + } + } + catch + { + throw; + } + } + 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) + { + return File.Exists(filePath); + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/SqlSugarExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/SqlSugarExtensions.cs new file mode 100644 index 000000000..e3a810c24 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/SqlSugarExtensions.cs @@ -0,0 +1,36 @@ +using SqlSugar.TDengine; + +using System.Reflection; + +namespace SqlSugar +{ + public static class SqlSugarExtensions + { + public static ISugarQueryable AsTDengineSTable(this ISugarQueryable queryable) where T : class, new() + { + var attr = SqlSugar.TDengine.UtilMethods.GetCommonSTableAttribute(queryable.Context, typeof(T).GetCustomAttribute()); + queryable.AS(attr.STableName); + return queryable; + } + public static IDeleteable AsTDengineSTable(this IDeleteable queryable) where T : class, new() + { + var attr = SqlSugar.TDengine.UtilMethods.GetCommonSTableAttribute(((DeleteableProvider)queryable).Context, typeof(T).GetCustomAttribute()); + queryable.AS(attr.STableName); + return queryable; + } + public static void MappingSTableName(this ISqlSugarClient db, string newSTableName) + { + STableAttribute sTableAttribute = typeof(T).GetCustomAttribute(); + if (db.TempItems == null) + { + db.TempItems = new Dictionary(); + } + if (sTableAttribute != null) + { + var key = "GetCommonSTableAttribute_" + sTableAttribute.STableName; + db.TempItems.Remove(key); + db.TempItems.Add(key, newSTableName); + } + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilConstants.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilConstants.cs new file mode 100644 index 000000000..9ff77f845 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilConstants.cs @@ -0,0 +1,69 @@ +using System.Dynamic; +namespace SqlSugar.TDengine +{ + 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/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilExtensions.cs new file mode 100644 index 000000000..e831c9a30 --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilExtensions.cs @@ -0,0 +1,140 @@ +namespace SqlSugar.TDengine +{ + /// + ///Common Extensions for external users + /// + public static class UtilExtensions + { + public static TagInserttable SetTDengineChildTableName(this IInsertable thisValue, Func getChildTableNamefunc) where T : class, new() + { + TagInserttable result = new TagInserttable(); + result.thisValue = thisValue; + result.Context = ((InsertableProvider)thisValue).Context; + result.getChildTableNamefunc = getChildTableNamefunc; + return result; + } + public static string ObjToStringNoTrim(this object thisValue) + { + if (thisValue != null) return thisValue.ToString(); + return ""; + } + 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 ""; + } + + 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)) + { + reval = Convert.ToDateTime(thisValue); + } + 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/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilMethods.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilMethods.cs new file mode 100644 index 000000000..ae5286bba --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/UtilMethods.cs @@ -0,0 +1,513 @@ +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDengine +{ + public static class UtilMethods + { + public static STableAttribute GetCommonSTableAttribute(ISqlSugarClient db, STableAttribute sTableAttribute) + { + var key = "GetCommonSTableAttribute_" + sTableAttribute?.STableName; + if (db.TempItems?.ContainsKey(key) == true) + { + sTableAttribute.STableName = db.TempItems[key] + ""; + } + return sTableAttribute!; + } + public static long ToUnixTimestamp(DateTime dateTime) + { + // If the DateTime is Utc, use ToUnixTimeMilliseconds directly + if (dateTime.Kind == DateTimeKind.Utc) + { + return new DateTimeOffset(dateTime).ToUnixTimeMilliseconds(); + } + else + { + // Convert local DateTime to Utc before converting to Unix timestamp + return new DateTimeOffset(dateTime.ToUniversalTime()).ToUnixTimeMilliseconds(); + } + } + 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) + { + return 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?.CanConvertFrom(value.GetType()) == true) + return destinationConverter.ConvertFrom(null, culture, value); + + var sourceConverter = TypeDescriptor.GetConverter(sourceType); + if (sourceConverter?.CanConvertTo(destinationType) == true) + 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 (!string.Equals(frame.GetMethod().Module.Name, "sqlsugar.dll", StringComparison.OrdinalIgnoreCase) && 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) + { + return (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]; + 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) + { + return (T)Convert.ChangeType(obj, type); + } + + internal static T ChangeType(T obj) + { + return (T)Convert.ChangeType(obj, typeof(T)); + } + + internal static DateTimeOffset GetDateTimeOffsetByDateTime(DateTime date) + { + date = DateTime.SpecifyKind(date, DateTimeKind.Utc); + DateTimeOffset utcTime2 = date; + return utcTime2; + } + + //internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + //{ + // if (appendSql.HasValue() && parameters.HasValue()) + // { + // foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + // { + // //Compatible with.NET CORE parameters case + // var name = parameter.ParameterName; + // string newName = name + append + addIndex; + // appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + // parameter.ParameterName = newName; + // } + // } + //} + + internal static string GetPackTable(string sql, string shortName) + { + return string.Format(" ({0}) {1} ", sql, shortName); + } + + public static Func GetTypeConvert(object value) + { + if (value is int || value is uint || value is int? || value is uint?) + { + return x => Convert.ToInt32(x); + } + else if (value is short || value is ushort || value is short? || value is ushort?) + { + return x => Convert.ToInt16(x); + } + else if (value is long || value is long? || value is ulong? || value is long?) + { + return x => Convert.ToInt64(x); + } + else if (value is DateTime || value is DateTime?) + { + return x => Convert.ToDateTime(x); + } + else if (value is bool || value is bool?) + { + return x => Convert.ToBoolean(x); + } + return null; + } + + internal static string GetTypeName(object value) + { + if (value == null) + { + return null; + } + else + { + return value.GetType().Name; + } + } + + internal static string GetParenthesesValue(string dbTypeName) + { + if (Regex.IsMatch(dbTypeName, @"\(.+\)")) + { + dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", ""); + } + dbTypeName = dbTypeName.Trim(); + return dbTypeName; + } + + internal static T GetOldValue(T value, Action action) + { + action(); + return value; + } + + internal static object DefaultForType(Type targetType) + { + return targetType.IsValueType ? Activator.CreateInstance(targetType) : null; + } + + internal static Int64 GetLong(byte[] bytes) + { + return Convert.ToInt64(string.Join("", bytes).PadRight(20, '0')); + } + public static object GetPropertyValue(T t, string PropertyName) + { + return t.GetType().GetProperty(PropertyName).GetValue(t, null); + } + + private static readonly char[] separator = new char[] { '9' }; + + //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(separator, 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/Admin/ThingsGateway.SqlSugar/TDengine/Tools/ValidateExtensions.cs b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/ValidateExtensions.cs new file mode 100644 index 000000000..ffe9325bf --- /dev/null +++ b/src/Admin/ThingsGateway.SqlSugar/TDengine/Tools/ValidateExtensions.cs @@ -0,0 +1,166 @@ +using System.Text.RegularExpressions; +namespace SqlSugar.TDengine +{ + internal static class ValidateExtensions + { + public static bool IsInRange(this int thisValue, int begin, int end) + { + return thisValue >= begin && thisValue <= end; + } + + public static bool IsInRange(this DateTime thisValue, DateTime begin, DateTime end) + { + return thisValue >= begin && thisValue <= end; + } + + public static bool IsIn(this T thisValue, params T[] values) + { + return values.Contains(thisValue); + } + + public static bool IsContainsIn(this string thisValue, params string[] inValues) + { + return inValues.Any(it => thisValue.Contains(it)); + } + + public static bool IsNullOrEmpty(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return true; + return string.IsNullOrEmpty(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) + { + return thisValue == Guid.Empty; + } + + public static bool IsNullOrEmpty(this IEnumerable thisValue) + { + if (thisValue?.Any() != true) return true; + return false; + } + + public static bool HasValue(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return false; + return !string.IsNullOrEmpty(thisValue.ToString()); + } + + public static bool HasValue(this IEnumerable thisValue) + { + if (thisValue?.Any() != true) return false; + return true; + } + + public static bool IsValuable(this IEnumerable> thisValue) + { + if (thisValue?.Any() != true) return false; + return true; + } + + public static bool IsZero(this object thisValue) + { + return (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) + { + return (thisValue + "").IsMatch(@"System\.[a-z,A-Z,0-9]+?\[\]"); + } + public static bool IsEnumerable(this string thisValue) + { + return (thisValue + "").StartsWith("System.Linq.Enumerable"); + } + + public static Type StringType = typeof(string); + + public static bool IsClass(this Type thisValue) + { + return thisValue != StringType && thisValue.IsEntity() && thisValue != UtilConstants.ByteArrayType; + } + } +} diff --git a/src/Admin/ThingsGateway.SqlSugar/ThingsGateway.SqlSugar.csproj b/src/Admin/ThingsGateway.SqlSugar/ThingsGateway.SqlSugar.csproj index 6383e3c34..5a4fc76cd 100644 --- a/src/Admin/ThingsGateway.SqlSugar/ThingsGateway.SqlSugar.csproj +++ b/src/Admin/ThingsGateway.SqlSugar/ThingsGateway.SqlSugar.csproj @@ -9,11 +9,6 @@ net8.0;net9.0; - - - - - @@ -23,7 +18,23 @@ - + + + + + + + + + + + + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ac0cc0b4b..b80a19e2e 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,9 +1,9 @@ - 10.7.21 - 10.7.21 - 2.4.0 + 10.7.22 + 10.7.22 + 2.5.0 @@ -20,8 +20,10 @@ All None None - - CS8603;CS8618;CS1591;CS8625;CS8602;CS8604;CS8600;CS8601;CS8714;CS8619;CS8629;CS8765;CS8634;CS8621;CS8767;CS8633;CS8620;CS8610;CS8631;CS8605;CS8622;CS8613;NU5100;NU5104;NU1903;NU1902;CA1813; + + + CS8603;CS8618;CS1591;CS8625;CS8602;CS8604;CS8600;CS8601;CS8714;CS8619;CS8629;CS8765;CS8634;CS8621;CS8767;CS8633;CS8620;CS8610;CS8631;CS8605;CS8622;CS8613;NU5100;NU5104;NU1903;NU1902;CA1813;CA1852;CA1822;CA2100;CA2008;CA1812;CA1508;CA1512;CA1513;CA1810;CA1814;CA1815;CA1835;CA1819;CA1823;CA2002;CA5350;CA5351;CA5358;CA5384;CA5392;CA1805;CA1851;CA1510;CA5401;CA2022;CA1848;CA2000;CA5394;CA3003;CA1515;CA1849 + net8.0; 13.0 enable @@ -44,5 +46,10 @@ Embedded True - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/src/Foundation/ThingsGateway.Foundation/Attributes/UriValidationAttribute.cs b/src/Foundation/ThingsGateway.Foundation/Attributes/UriValidationAttribute.cs index a2ae3f1e5..0888db7eb 100644 --- a/src/Foundation/ThingsGateway.Foundation/Attributes/UriValidationAttribute.cs +++ b/src/Foundation/ThingsGateway.Foundation/Attributes/UriValidationAttribute.cs @@ -15,6 +15,7 @@ using System.Text.RegularExpressions; using ThingsGateway.Foundation; namespace ThingsGateway; +[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class UriValidationAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) diff --git a/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPTcpSessionClientChannel.cs b/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPTcpSessionClientChannel.cs index f402378ab..b28adaa43 100644 --- a/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPTcpSessionClientChannel.cs +++ b/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPTcpSessionClientChannel.cs @@ -99,7 +99,29 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel { bool log = false; if (id != Id) log = true; + //注册ID + if (Service is ITcpService tcpService && tcpService.TryGetClient(id, out var oldClient) && oldClient != this) + { + try + { + await oldClient.ShutdownAsync(System.Net.Sockets.SocketShutdown.Both).ConfigureAwait(false); + await oldClient.CloseAsync().ConfigureAwait(false); + oldClient.Dispose(); + } + catch + { + } + try + { + oldClient.Dispose(); + } + catch + { + + } + } + await ResetIdAsync(id).ConfigureAwait(false); //发送成功 @@ -132,7 +154,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ThrowIfCannotSendRequestInfo() { - if (DataHandlingAdapter == null || !DataHandlingAdapter.CanSendRequestInfo) + if (DataHandlingAdapter?.CanSendRequestInfo != true) { throw new NotSupportedException(TouchSocketResource.CannotSendRequestInfo); } diff --git a/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPUdpSessionChannel.cs b/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPUdpSessionChannel.cs index cc521b6b9..f8780ec93 100644 --- a/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPUdpSessionChannel.cs +++ b/src/Foundation/ThingsGateway.Foundation/Channel/DDP/DDPUdpSessionChannel.cs @@ -160,7 +160,7 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe //发送成功 await DDPAdapter.SendInputAsync(endPoint, new DDPSend(ReadOnlyMemory.Empty, id, false, 0x81)).ConfigureAwait(false); - if(log) + if (log) Logger?.Info(DefaultResource.Localizer["DtuConnected", id]); } else if (message.Type == 0x02) @@ -185,7 +185,7 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ThrowIfCannotSendRequestInfo() { - if (DataHandlingAdapter == null || !DataHandlingAdapter.CanSendRequestInfo) + if (DataHandlingAdapter?.CanSendRequestInfo != true) { throw new NotSupportedException(TouchSocketResource.CannotSendRequestInfo); } diff --git a/src/Foundation/ThingsGateway.Foundation/Channel/OtherChannel.cs b/src/Foundation/ThingsGateway.Foundation/Channel/OtherChannel.cs index b7a17031e..4a77572db 100644 --- a/src/Foundation/ThingsGateway.Foundation/Channel/OtherChannel.cs +++ b/src/Foundation/ThingsGateway.Foundation/Channel/OtherChannel.cs @@ -149,7 +149,7 @@ public class OtherChannel : SetupConfigObject, IClientChannel public async Task SendAsync(IList> transferBytes) { // 检查数据处理适配器是否存在且支持拼接发送 - if (m_dataHandlingAdapter == null || !m_dataHandlingAdapter.CanSplicingSend) + if (m_dataHandlingAdapter?.CanSplicingSend != true) { // 如果不支持拼接发送,则计算所有字节片段的总长度 var length = 0; @@ -208,7 +208,7 @@ public class OtherChannel : SetupConfigObject, IClientChannel } private void ThrowIfCannotSendRequestInfo() { - if (m_dataHandlingAdapter == null || !m_dataHandlingAdapter.CanSendRequestInfo) + if (m_dataHandlingAdapter?.CanSendRequestInfo != true) { throw new NotSupportedException($"当前适配器为空或者不支持对象发送。"); } diff --git a/src/Foundation/ThingsGateway.Foundation/Device/DeviceBase.cs b/src/Foundation/ThingsGateway.Foundation/Device/DeviceBase.cs index 75d3ecffe..bff7430b4 100644 --- a/src/Foundation/ThingsGateway.Foundation/Device/DeviceBase.cs +++ b/src/Foundation/ThingsGateway.Foundation/Device/DeviceBase.cs @@ -375,10 +375,10 @@ public abstract class DeviceBase : DisposableObject, IDevice if (AutoConnect && !Channel.Online) await Channel.ConnectAsync(Channel.ChannelOptions.ConnectTimeout, token).ConfigureAwait(false); } - catch (Exception ex) + catch (Exception) { await Task.Delay(1000, token).ConfigureAwait(false); - throw ex; + throw; } if (token.IsCancellationRequested) diff --git a/src/Foundation/ThingsGateway.Foundation/Extensions/StringExtensions.cs b/src/Foundation/ThingsGateway.Foundation/Extensions/StringExtensions.cs index f806332e6..fae72e15b 100644 --- a/src/Foundation/ThingsGateway.Foundation/Extensions/StringExtensions.cs +++ b/src/Foundation/ThingsGateway.Foundation/Extensions/StringExtensions.cs @@ -180,7 +180,11 @@ public static class StringExtensions return true; } - /// + /// + /// + /// + /// + /// public static byte[] HexStringToBytes(this string str) => DataTransUtil.HexStringToBytes(str); private static readonly char[] DotSeparator = new char[] { '.' }; private static readonly char[] SlashSeparator = new char[] { '/' }; diff --git a/src/Foundation/ThingsGateway.Foundation/Extensions/TypeExtensions.cs b/src/Foundation/ThingsGateway.Foundation/Extensions/TypeExtensions.cs index 70d199a0f..d5c52e7a0 100644 --- a/src/Foundation/ThingsGateway.Foundation/Extensions/TypeExtensions.cs +++ b/src/Foundation/ThingsGateway.Foundation/Extensions/TypeExtensions.cs @@ -62,7 +62,7 @@ public static class TypeExtensions var nullable = customAttributes .FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); - if (nullable != null && nullable.ConstructorArguments.Count == 1) + if (nullable?.ConstructorArguments.Count == 1) { var attributeArgument = nullable.ConstructorArguments[0]; if (attributeArgument.ArgumentType == typeof(byte[])) @@ -83,8 +83,7 @@ public static class TypeExtensions { var context = type.CustomAttributes .FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute"); - if (context != null && - context.ConstructorArguments.Count == 1 && + if (context?.ConstructorArguments.Count == 1 && context.ConstructorArguments[0].ArgumentType == typeof(byte)) { return (byte)context.ConstructorArguments[0].Value! == 2; diff --git a/src/Foundation/ThingsGateway.Foundation/Logger/TextFileReader.cs b/src/Foundation/ThingsGateway.Foundation/Logger/TextFileReader.cs index 3548c7521..3ad25e668 100644 --- a/src/Foundation/ThingsGateway.Foundation/Logger/TextFileReader.cs +++ b/src/Foundation/ThingsGateway.Foundation/Logger/TextFileReader.cs @@ -51,7 +51,7 @@ public class LogDataCache } /// 高性能日志文件读取器(支持倒序读取) -public class TextFileReader +public static class TextFileReader { private static readonly MemoryCache _cache = new() { Expire = 30 }; private static readonly MemoryCache _fileLocks = new(); diff --git a/src/Foundation/ThingsGateway.Foundation/Utils/CRC16Utils.cs b/src/Foundation/ThingsGateway.Foundation/Utils/CRC16Utils.cs index fa018d6e7..48d32be61 100644 --- a/src/Foundation/ThingsGateway.Foundation/Utils/CRC16Utils.cs +++ b/src/Foundation/ThingsGateway.Foundation/Utils/CRC16Utils.cs @@ -13,7 +13,7 @@ namespace ThingsGateway.Foundation; /// /// CRC16验证 /// -public class CRC16Utils +public static class CRC16Utils { /// /// 通过指定多项式码来获取对应的数据的CRC校验码 diff --git a/src/Foundation/ThingsGateway.Foundation/Utils/DataTransUtil.cs b/src/Foundation/ThingsGateway.Foundation/Utils/DataTransUtil.cs index 274b1b355..4313944c6 100644 --- a/src/Foundation/ThingsGateway.Foundation/Utils/DataTransUtil.cs +++ b/src/Foundation/ThingsGateway.Foundation/Utils/DataTransUtil.cs @@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation; /// /// 常用转换 /// -public class DataTransUtil +public static class DataTransUtil { /// /// 字节数据转化成16进制表示的字符串 diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/BlazorDiagramsException.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/BlazorDiagramsException.cs index 657a83c69..ce68438e0 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/BlazorDiagramsException.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/BlazorDiagramsException.cs @@ -5,4 +5,12 @@ public class BlazorDiagramsException : Exception public BlazorDiagramsException(string? message) : base(message) { } + + public BlazorDiagramsException() : base() + { + } + + public BlazorDiagramsException(string? message, Exception? innerException) : base(message, innerException) + { + } } \ No newline at end of file diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/GroupRenderer.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/GroupRenderer.cs index 014b5f673..5de2d99d1 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/GroupRenderer.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/GroupRenderer.cs @@ -59,7 +59,7 @@ public class GroupRenderer : ComponentBase, IDisposable // Update the port positions (and links) when the size of the group changes // This will save us some JS trips as well as useless rerenders - if (_lastSize == null || !_lastSize.Equals(Group.Size)) + if (_lastSize?.Equals(Group.Size) != true) { Group.ReinitializePorts(); Group.RefreshLinks(); diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/NodeRenderer.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/NodeRenderer.cs index dddb97f68..9a69aaef3 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/NodeRenderer.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/Components/Renderers/NodeRenderer.cs @@ -48,7 +48,7 @@ public class NodeRenderer : ComponentBase, IDisposable return; size = new Size(size.Width / BlazorDiagram.Zoom, size.Height / BlazorDiagram.Zoom); - if (Node.Size != null && Node.Size.Width.AlmostEqualTo(size.Width) && + if (Node.Size?.Width.AlmostEqualTo(size.Width) == true && Node.Size.Height.AlmostEqualTo(size.Height)) { return; diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragMovablesBehavior.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragMovablesBehavior.cs index 3f43161a6..4c70ea72f 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragMovablesBehavior.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragMovablesBehavior.cs @@ -32,7 +32,7 @@ public class DragMovablesBehavior : Behavior continue; // Special case: groups without auto size on - if (sm is NodeModel node && node.Group != null && !node.Group.AutoSize) + if (sm is NodeModel node && node.Group?.AutoSize == false) continue; var position = movable.Position; diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragNewLinkBehavior.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragNewLinkBehavior.cs index d04c35e4f..60ea252fd 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragNewLinkBehavior.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/Core/Behaviors/DragNewLinkBehavior.cs @@ -99,7 +99,7 @@ public class DragNewLinkBehavior : Behavior return; } - if (model is ILinkable linkable && (OngoingLink.Source.Model == null || OngoingLink.Source.Model.CanAttachTo(linkable))) + if (model is ILinkable linkable && (OngoingLink.Source.Model?.CanAttachTo(linkable) != false)) { var targetAnchor = Diagram.Options.Links.TargetAnchorFactory(Diagram, OngoingLink, linkable); if (targetAnchor is SinglePortAnchor singlePortAnchor && singlePortAnchor.Model is PortModel portModel && portModel.Alignment == PortAlignment.Top) diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/Parser.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/Parser.cs index 94b80ea5a..4c7e11abb 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/Parser.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/Parser.cs @@ -41,7 +41,7 @@ namespace SvgPathProperties command = command == 'm' ? 'l' : 'L'; } - while (args.Count >= 0) + while (true) { if (args.Count == _length[type]) { diff --git a/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/SvgPath.cs b/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/SvgPath.cs index 1200dca93..8e3b828a5 100644 --- a/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/SvgPath.cs +++ b/src/Gateway/ThingsGateway.Blazor.Diagrams/SvgPathProperties/SvgPath.cs @@ -336,7 +336,7 @@ namespace SvgPathProperties if (abs) { - if (_lastCurve != null && _lastCurve.IsQuadratic == false) + if (_lastCurve?.IsQuadratic == false) { var c = _lastCurve.Cp2OrEnd; _lastCurve = new BezierCommand( @@ -374,7 +374,7 @@ namespace SvgPathProperties } else { - if (_lastCurve != null && _lastCurve.IsQuadratic == false) + if (_lastCurve?.IsQuadratic == false) { var c = _lastCurve.Cp2OrEnd; var d = _lastCurve.End; diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Const/ThingsGatewayCacheConst.cs b/src/Gateway/ThingsGateway.Gateway.Application/Const/ThingsGatewayCacheConst.cs index bc72cde41..c25975778 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Const/ThingsGatewayCacheConst.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Const/ThingsGatewayCacheConst.cs @@ -14,7 +14,7 @@ namespace ThingsGateway.Gateway.Application; /// Cache常量 /// [ThingsGateway.DependencyInjection.SuppressSniffer] -public class ThingsGatewayCacheConst +public static class ThingsGatewayCacheConst { /// /// 通道 diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Driver/CacheDB/CacheDBUtil.cs b/src/Gateway/ThingsGateway.Gateway.Application/Driver/CacheDB/CacheDBUtil.cs index 70d682677..bca1a0981 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Driver/CacheDB/CacheDBUtil.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Driver/CacheDB/CacheDBUtil.cs @@ -14,7 +14,7 @@ using ThingsGateway.NewLife; namespace ThingsGateway.Gateway.Application; -public class CacheDBUtil +public static class CacheDBUtil { public const string EX = ".db"; diff --git a/src/Gateway/ThingsGateway.Gateway.Application/GlobalData/GlobalData.cs b/src/Gateway/ThingsGateway.Gateway.Application/GlobalData/GlobalData.cs index 62388487a..9d6423f29 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/GlobalData/GlobalData.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/GlobalData/GlobalData.cs @@ -480,11 +480,11 @@ public static class GlobalData /// 报警变量 internal static void AlarmChange(AlarmVariable alarmVariable) { - if (AlarmChangedEvent != null) - { - // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 - AlarmChangedEvent.Invoke(alarmVariable); - } + + + // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 + AlarmChangedEvent?.Invoke(alarmVariable); + } /// @@ -495,11 +495,11 @@ public static class GlobalData { deviceRuntime.Driver?.LogMessage?.LogInformation($"Status changed: {deviceRuntime.DeviceStatus}"); - if (DeviceStatusChangeEvent != null) - { - // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 - DeviceStatusChangeEvent.Invoke(deviceRuntime, deviceRuntime.Adapt()); - } + + + // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 + DeviceStatusChangeEvent?.Invoke(deviceRuntime, deviceRuntime.Adapt()); + } /// @@ -508,11 +508,11 @@ public static class GlobalData /// 变量运行时对象 internal static void VariableValueChange(VariableRuntime variableRuntime) { - if (VariableValueChangeEvent != null) - { - // 触发变量值变化事件,并将变量运行时对象转换为变量数据对象进行传递 - VariableValueChangeEvent.Invoke(variableRuntime, variableRuntime.Adapt()); - } + + + // 触发变量值变化事件,并将变量运行时对象转换为变量数据对象进行传递 + VariableValueChangeEvent?.Invoke(variableRuntime, variableRuntime.Adapt()); + } /// /// 变量采集处理方法,用于处理变量进行采集时的逻辑 @@ -520,11 +520,11 @@ public static class GlobalData /// 变量运行时对象 internal static void VariableCollectChange(VariableRuntime variableRuntime) { - if (VariableCollectChangeEvent != null) - { - // 触发变量采集事件,并将变量运行时对象转换为变量数据对象进行传递 - VariableCollectChangeEvent.Invoke(variableRuntime); - } + + + // 触发变量采集事件,并将变量运行时对象转换为变量数据对象进行传递 + VariableCollectChangeEvent?.Invoke(variableRuntime); + } #endregion diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Model/DeviceRunTime.cs b/src/Gateway/ThingsGateway.Gateway.Application/Model/DeviceRunTime.cs index 8dd57620f..514949cd7 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Model/DeviceRunTime.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Model/DeviceRunTime.cs @@ -81,7 +81,7 @@ public class DeviceRuntime : Device, IDisposable } set { - lock (this) + lock (_lockObject) { if (_deviceStatus != value) { @@ -191,6 +191,7 @@ public class DeviceRuntime : Device, IDisposable public volatile bool CheckEnable; + private readonly object _lockObject = new object(); #endregion 采集 diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Services/Device/DeviceServiceHelpers.cs b/src/Gateway/ThingsGateway.Gateway.Application/Services/Device/DeviceServiceHelpers.cs index d50ae62fe..e6adaeb37 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Services/Device/DeviceServiceHelpers.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Services/Device/DeviceServiceHelpers.cs @@ -30,7 +30,7 @@ public static class DeviceServiceHelpers public static async Task> ExportCoreAsync(IEnumerable? data, string channelName = null, string plugin = null) { - if (data == null || !data.Any()) + if (data?.Any() != true) { data = new List(); } @@ -112,7 +112,7 @@ public static class DeviceServiceHelpers propertysDict.TryAdd(channel?.PluginName ?? plugin, propertys); } - catch (Exception) + catch { } diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Services/Plugin/PluginServiceUtil.cs b/src/Gateway/ThingsGateway.Gateway.Application/Services/Plugin/PluginServiceUtil.cs index 63c1a4ace..e32637097 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Services/Plugin/PluginServiceUtil.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Services/Plugin/PluginServiceUtil.cs @@ -166,7 +166,7 @@ public static class PluginServiceUtil if (classAttribute == null) continue; string propertyName = property.Name; // 如果属性存在且可写 - if (property != null && property.CanWrite) + if (property?.CanWrite == true) { // 进行类型转换 var value = ThingsGatewayStringConverter.Default.Serialize(null, property.GetValue(model)); @@ -194,7 +194,7 @@ public static class PluginServiceUtil string propertyName = property.Name; // 如果属性存在且可写 - if (property != null && property.CanWrite) + if (property?.CanWrite == true) { if (dict.TryGetValue(propertyName, out var dictValue)) { diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableService.cs b/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableService.cs index 15910a6ed..a688fab99 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableService.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableService.cs @@ -715,7 +715,7 @@ internal sealed class VariableService : BaseService, IVariableService propertys.Item3 = properties; propertysDict.TryAdd(driverPluginType.FullName, propertys); } - catch (Exception) + catch { } diff --git a/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableServiceHelpers.cs b/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableServiceHelpers.cs index 65e62d347..ee3b37b9e 100644 --- a/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableServiceHelpers.cs +++ b/src/Gateway/ThingsGateway.Gateway.Application/Services/Variable/VariableServiceHelpers.cs @@ -30,7 +30,7 @@ public static class VariableServiceHelpers public static async Task> ExportCoreAsync(IEnumerable data, string deviceName = null) { - if (data == null || !data.Any()) + if (data?.Any() != true) { data = new List(); } diff --git a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Channel/ChannelRuntimeInfo1.razor.cs b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Channel/ChannelRuntimeInfo1.razor.cs index d386be46a..4393ec61a 100644 --- a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Channel/ChannelRuntimeInfo1.razor.cs +++ b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Channel/ChannelRuntimeInfo1.razor.cs @@ -24,7 +24,7 @@ public partial class ChannelRuntimeInfo1 : IDisposable private async Task RestartChannelAsync() { if (ChannelRuntime.DeviceThreadManage?.ChannelThreadManage != null) - await Task.Run(() => ChannelRuntime.DeviceThreadManage?.ChannelThreadManage.RestartChannelAsync(ChannelRuntime)); + await Task.Run(() => ChannelRuntime.DeviceThreadManage.ChannelThreadManage.RestartChannelAsync(ChannelRuntime)); else await Task.Run(() => GlobalData.ChannelThreadManage.RestartChannelAsync(ChannelRuntime)); } diff --git a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Device/DeviceRuntimeInfo1.razor.cs b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Device/DeviceRuntimeInfo1.razor.cs index eee9f1ddc..5f76d5769 100644 --- a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Device/DeviceRuntimeInfo1.razor.cs +++ b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Device/DeviceRuntimeInfo1.razor.cs @@ -71,8 +71,7 @@ public partial class DeviceRuntimeInfo1 : IDisposable } private void PauseThread() { - if (DeviceRuntime.Driver != null) - DeviceRuntime.Driver.PauseThread(!DeviceRuntime.Pause); + DeviceRuntime.Driver?.PauseThread(!DeviceRuntime.Pause); } protected override void OnInitialized() diff --git a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/PluginPage/PluginDebugPage.razor.cs b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/PluginPage/PluginDebugPage.razor.cs index c09e6f858..36a38f1fe 100644 --- a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/PluginPage/PluginDebugPage.razor.cs +++ b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/PluginPage/PluginDebugPage.razor.cs @@ -10,8 +10,6 @@ using Mapster; -using Newtonsoft.Json.Linq; - using ThingsGateway.Gateway.Application; using ThingsGateway.NewLife.Extension; diff --git a/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/ModbusHelper.cs b/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/ModbusHelper.cs index 19ab0afff..b9e581de9 100644 --- a/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/ModbusHelper.cs +++ b/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/ModbusHelper.cs @@ -10,7 +10,7 @@ namespace ThingsGateway.Foundation.Modbus; -public class ModbusHelper +public static class ModbusHelper { #region 解析 diff --git a/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/PackHelper.cs b/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/PackHelper.cs index 5e4652a55..5fa815a13 100644 --- a/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/PackHelper.cs +++ b/src/Plugin/ThingsGateway.Foundation.Modbus/Helper/PackHelper.cs @@ -16,7 +16,7 @@ namespace ThingsGateway.Foundation.Modbus; /// /// PackHelper /// -public class PackHelper +public static class PackHelper { /// /// 打包变量,添加到 diff --git a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Comn/ComInterop.cs b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Comn/ComInterop.cs index e6cb595e4..af6af78a4 100644 --- a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Comn/ComInterop.cs +++ b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Comn/ComInterop.cs @@ -176,7 +176,7 @@ internal sealed class ComInterop // 检查是否在本地或远程连接。 uint clsctx = 0x01 | 0x04; - if (hostName != null && hostName.Length > 0 && !hostName.Equals("localhost", StringComparison.OrdinalIgnoreCase) && !hostName.Equals("127.0.0.1", StringComparison.OrdinalIgnoreCase)) + if (hostName?.Length > 0 && !hostName.Equals("localhost", StringComparison.OrdinalIgnoreCase) && !hostName.Equals("127.0.0.1", StringComparison.OrdinalIgnoreCase)) { clsctx = 0x04 | 0x10; } @@ -365,7 +365,7 @@ internal sealed class ComInterop /// internal static void RealseComServer(object m_server) { - if (m_server != null && m_server.GetType().IsCOMObject) + if (m_server?.GetType().IsCOMObject == true) { Marshal.ReleaseComObject(m_server); } diff --git a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Da/OpcServer.cs b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Da/OpcServer.cs index 36d3d5542..0d2bb35e4 100644 --- a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Da/OpcServer.cs +++ b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Da/OpcServer.cs @@ -51,7 +51,6 @@ internal sealed class OpcServer : IDisposable return AddGroup(groupName, true, 1000, 0); } - /// internal OpcGroup AddGroup(string groupName, bool active, int reqUpdateRate, float deadBand) { if (null == m_OpcServer || IsConnected == false) diff --git a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/Interop.cs b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/Interop.cs index e3fde0a20..36531a7e2 100644 --- a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/Interop.cs +++ b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/Interop.cs @@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.OpcDa.Rcw; #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释 #pragma warning disable CS8605 // 取消装箱可能为 null 的值。 -public class Interop +public static class Interop { public static PropertyID GetPropertyID(int input) { @@ -523,7 +523,7 @@ public class Interop internal static int GetResultID(ResultID input) { - if (input.Name != null && input.Name.Namespace == "http://opcfoundation.org/DataAccess/") + if (input.Name?.Namespace == "http://opcfoundation.org/DataAccess/") { if (input == ResultID.S_OK) return 0; @@ -568,7 +568,7 @@ public class Interop if (input == ResultID.Da.S_DATAQUEUEOVERFLOW) return 263172; } - else if (input.Name != null && input.Name.Namespace == "http://opcfoundation.org/ComplexData/") + else if (input.Name?.Namespace == "http://opcfoundation.org/ComplexData/") { if (input == ResultID.Cpx.E_TYPE_CHANGED) return -1073478649; @@ -581,7 +581,7 @@ public class Interop if (input == ResultID.Cpx.S_FILTER_NO_DATA) return 263179; } - else if (input.Name != null && input.Name.Namespace == "http://opcfoundation.org/HistoricalDataAccess/") + else if (input.Name?.Namespace == "http://opcfoundation.org/HistoricalDataAccess/") { if (input == ResultID.Hda.E_MAXEXCEEDED) return -1073475583; @@ -612,7 +612,7 @@ public class Interop if (input == ResultID.Hda.S_REPLACED) return 1074008079; } - if (input.Name != null && input.Name.Namespace == "http://opcfoundation.org/DataExchange/") + if (input.Name?.Namespace == "http://opcfoundation.org/DataExchange/") { if (input == ResultID.Dx.E_PERSISTING) return -1073477888; diff --git a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/ItemProperty.cs b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/ItemProperty.cs index 3218945bd..a229a3a26 100644 --- a/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/ItemProperty.cs +++ b/src/Plugin/ThingsGateway.Foundation.OpcDa/COM/Rcw/ItemProperty.cs @@ -499,7 +499,7 @@ public struct ResultID : ISerializable return string.Format("0x{0,0:X}", Code); } - public class Ae + public static class Ae { public static readonly ResultID E_BUSY = new ResultID("E_BUSY", "http://opcfoundation.org/AlarmAndEvents/"); public static readonly ResultID E_INVALIDBRANCHNAME = new ResultID("E_INVALIDBRANCHNAME", "http://opcfoundation.org/AlarmAndEvents/"); @@ -513,7 +513,7 @@ public struct ResultID : ISerializable public static readonly ResultID S_INVALIDMAXSIZE = new ResultID("S_INVALIDMAXSIZE", "http://opcfoundation.org/AlarmAndEvents/"); } - public class Cpx + public static class Cpx { public static readonly ResultID E_FILTER_DUPLICATE = new ResultID("E_FILTER_DUPLICATE", "http://opcfoundation.org/ComplexData/"); public static readonly ResultID E_FILTER_ERROR = new ResultID("E_FILTER_ERROR", "http://opcfoundation.org/ComplexData/"); @@ -522,7 +522,7 @@ public struct ResultID : ISerializable public static readonly ResultID S_FILTER_NO_DATA = new ResultID("S_FILTER_NO_DATA", "http://opcfoundation.org/ComplexData/"); } - public class Da + public static class Da { public static readonly ResultID E_BADTYPE = new ResultID("E_BADTYPE", "http://opcfoundation.org/DataAccess/"); public static readonly ResultID E_INVALID_FILTER = new ResultID("E_INVALID_FILTER", "http://opcfoundation.org/DataAccess/"); @@ -546,7 +546,7 @@ public struct ResultID : ISerializable public static readonly ResultID S_UNSUPPORTEDRATE = new ResultID("S_UNSUPPORTEDRATE", "http://opcfoundation.org/DataAccess/"); } - public class Dx + public static class Dx { public static readonly ResultID E_CONNECTIONS_EXIST = new ResultID("E_CONNECTIONS_EXIST", "http://opcfoundation.org/DataExchange/"); public static readonly ResultID E_DUPLICATE_NAME = new ResultID("E_DUPLICATE_NAME", "http://opcfoundation.org/DataExchange/"); @@ -599,7 +599,7 @@ public struct ResultID : ISerializable public static readonly ResultID S_TARGET_SUBSTITUTED = new ResultID("S_TARGET_SUBSTITUTED", "http://opcfoundation.org/DataExchange/"); } - public class Hda + public static class Hda { public static readonly ResultID E_DATAEXISTS = new ResultID("E_DATAEXISTS", "http://opcfoundation.org/HistoricalDataAccess/"); public static readonly ResultID E_INVALIDAGGREGATE = new ResultID("E_INVALIDAGGREGATE", "http://opcfoundation.org/HistoricalDataAccess/"); @@ -745,7 +745,7 @@ public class ItemProperty : ICloneable, IResult } } -public class Property +public static class Property { public static readonly PropertyID ACCESSRIGHTS = new PropertyID("accessRights", 5, "http://opcfoundation.org/DataAccess/"); public static readonly PropertyID ALARM_AREA_LIST = new PropertyID("alarmAreaList", 302, "http://opcfoundation.org/DataAccess/"); diff --git a/src/Plugin/ThingsGateway.Foundation.OpcUa/Utils/OpcUaUtils.cs b/src/Plugin/ThingsGateway.Foundation.OpcUa/Utils/OpcUaUtils.cs index 3de03384a..aaee07030 100644 --- a/src/Plugin/ThingsGateway.Foundation.OpcUa/Utils/OpcUaUtils.cs +++ b/src/Plugin/ThingsGateway.Foundation.OpcUa/Utils/OpcUaUtils.cs @@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.OpcUa; /// /// 辅助类 /// -public class OpcUaUtils +public static class OpcUaUtils { /// @@ -407,7 +407,7 @@ public class OpcUaUtils ReferenceDescriptionCollection references = await BrowseAsync(session, nodeToBrowse, throwOnError).ConfigureAwait(false); - while (references != null && references.Count > 0) + while (references?.Count > 0) { // should never be more than one supertype. supertypes.Add(references[0]); diff --git a/src/Plugin/ThingsGateway.Plugin.DB/QuestDB/QuestDBProducer.cs b/src/Plugin/ThingsGateway.Plugin.DB/QuestDB/QuestDBProducer.cs index 4744239b3..334536a08 100644 --- a/src/Plugin/ThingsGateway.Plugin.DB/QuestDB/QuestDBProducer.cs +++ b/src/Plugin/ThingsGateway.Plugin.DB/QuestDB/QuestDBProducer.cs @@ -56,8 +56,9 @@ public partial class QuestDBProducer : BusinessBaseWithCacheIntervalVariableMode public async Task> GetDBHistoryValuesAsync(DBHistoryValuePageInput input) { var data = await Query(input).ToListAsync().ConfigureAwait(false); - return data.Cast().ToList(); ; + return data.Cast().ToList(); } + protected override async Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken) { diff --git a/src/Plugin/ThingsGateway.Plugin.DB/ThingsGateway.Plugin.DB.csproj b/src/Plugin/ThingsGateway.Plugin.DB/ThingsGateway.Plugin.DB.csproj index 38c16b30e..5a9e3741f 100644 --- a/src/Plugin/ThingsGateway.Plugin.DB/ThingsGateway.Plugin.DB.csproj +++ b/src/Plugin/ThingsGateway.Plugin.DB/ThingsGateway.Plugin.DB.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007AddressComponent.razor.cs b/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007AddressComponent.razor.cs index 6355fb9cb..9367cef54 100644 --- a/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007AddressComponent.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007AddressComponent.razor.cs @@ -52,8 +52,7 @@ public partial class Dlt645_2007AddressComponent : ComponentBase, IAddressUIBase Model = $"{ConverterConfig.ToString()}{Value?.ToString()}"; - if (ModelChanged != null) - ModelChanged.Invoke(Model); + ModelChanged?.Invoke(Model); if (OnCloseAsync != null) await OnCloseAsync(); } diff --git a/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007Master.razor.cs b/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007Master.razor.cs index c7ea6df94..926ea4b8e 100644 --- a/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007Master.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.Dlt645/Pages/Dlt645_2007Master.razor.cs @@ -61,10 +61,7 @@ public partial class Dlt645_2007Master : ComponentBase, IDisposable { {nameof(Dlt645_2007AddressComponent.ModelChanged), (string a) => { - if(DeviceComponent!=null) - { - DeviceComponent.SetRegisterAddress(a); - } + DeviceComponent?.SetRegisterAddress(a); }}, {nameof(Dlt645_2007AddressComponent.Model),address }, }); diff --git a/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusAddressComponent.razor.cs b/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusAddressComponent.razor.cs index 551ca4681..ceabbf2ab 100644 --- a/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusAddressComponent.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusAddressComponent.razor.cs @@ -52,8 +52,7 @@ public partial class ModbusAddressComponent : ComponentBase, IAddressUIBase Model = $"{ConverterConfig.ToString()}{Value?.ToString()}"; - if (ModelChanged != null) - ModelChanged.Invoke(Model); + ModelChanged?.Invoke(Model); if (OnCloseAsync != null) await OnCloseAsync(); } diff --git a/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusMaster.razor.cs b/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusMaster.razor.cs index e7e2dfae5..497ec9c3b 100644 --- a/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusMaster.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusMaster.razor.cs @@ -61,10 +61,7 @@ public partial class ModbusMaster : ComponentBase, IDisposable { {nameof(ModbusAddressComponent.ModelChanged), (string a) => { - if(DeviceComponent!=null) - { - DeviceComponent.SetRegisterAddress(a); - } + DeviceComponent?.SetRegisterAddress(a); }}, {nameof(ModbusAddressComponent.Model),address }, }); diff --git a/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusSlave.razor.cs b/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusSlave.razor.cs index a5cf6fd99..5de8a4d24 100644 --- a/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusSlave.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.Modbus/Pages/ModbusSlave.razor.cs @@ -54,10 +54,7 @@ public partial class ModbusSlave : ComponentBase, IDisposable { {nameof(ModbusAddressComponent.ModelChanged), (string a) => { - if(DeviceComponent!=null) - { - DeviceComponent.SetRegisterAddress(a); - } + DeviceComponent?.SetRegisterAddress(a); }}, {nameof(ModbusAddressComponent.Model),address }, }); diff --git a/src/Plugin/ThingsGateway.Plugin.Mqtt/MqttServer/MqttServer.cs b/src/Plugin/ThingsGateway.Plugin.Mqtt/MqttServer/MqttServer.cs index 93d8e3cc7..e7ea0b75b 100644 --- a/src/Plugin/ThingsGateway.Plugin.Mqtt/MqttServer/MqttServer.cs +++ b/src/Plugin/ThingsGateway.Plugin.Mqtt/MqttServer/MqttServer.cs @@ -79,10 +79,7 @@ public partial class MqttServer : BusinessBaseWithCacheIntervalScript 0) + if (data?.Count > 0) { if (isAll) child.Children = await PopulateBranchAsync((NodeId)target.NodeId); diff --git a/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7AddressComponent.razor.cs b/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7AddressComponent.razor.cs index 0c5c541db..66f3c1473 100644 --- a/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7AddressComponent.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7AddressComponent.razor.cs @@ -52,8 +52,7 @@ public partial class SiemensS7AddressComponent : ComponentBase, IAddressUIBase Model = $"{ConverterConfig.ToString()}{Value?.ToString()}"; - if (ModelChanged != null) - ModelChanged.Invoke(Model); + ModelChanged?.Invoke(Model); if (OnCloseAsync != null) await OnCloseAsync(); } diff --git a/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7Master.razor.cs b/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7Master.razor.cs index aa31b8980..291e0b144 100644 --- a/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7Master.razor.cs +++ b/src/Plugin/ThingsGateway.Plugin.SiemensS7/Pages/SiemensS7Master.razor.cs @@ -61,10 +61,7 @@ public partial class SiemensS7Master : ComponentBase, IDisposable { {nameof(SiemensS7AddressComponent.ModelChanged), (string a) => { - if(DeviceComponent!=null) - { - DeviceComponent.SetRegisterAddress(a); - } + DeviceComponent?.SetRegisterAddress(a); }}, {nameof(SiemensS7AddressComponent.Model),address }, }); diff --git a/src/Upgrade/ThingsGateway.Upgrade/Services/FileConst.cs b/src/Upgrade/ThingsGateway.Upgrade/Services/FileConst.cs index ae69cf94c..4ba15a29a 100644 --- a/src/Upgrade/ThingsGateway.Upgrade/Services/FileConst.cs +++ b/src/Upgrade/ThingsGateway.Upgrade/Services/FileConst.cs @@ -1,6 +1,6 @@ namespace ThingsGateway.Upgrade; -public class FileConst +public static class FileConst { public const string FilePathKey = "Path"; public static string UpgradePath = Path.Combine(AppContext.BaseDirectory, "Upgrade.zip"); diff --git a/src/Upgrade/ThingsGateway.UpgradeServer/GlobalUsings.cs b/src/Upgrade/ThingsGateway.UpgradeServer/GlobalUsings.cs index 4df1dc079..57835fe8b 100644 --- a/src/Upgrade/ThingsGateway.UpgradeServer/GlobalUsings.cs +++ b/src/Upgrade/ThingsGateway.UpgradeServer/GlobalUsings.cs @@ -1,15 +1,4 @@ -// ------------------------------------------------------------------------ -// 版权信息 -// 版权归百小僧及百签科技(广东)有限公司所有。 -// 所有权利保留。 -// 官方网站:https://baiqian.com -// -// 许可证信息 -// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 -// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 -// ------------------------------------------------------------------------ - -global using Mapster; +global using Mapster; global using ThingsGateway.Admin.Application; global using ThingsGateway.Admin.Razor; diff --git a/src/Version.props b/src/Version.props index 15b7aa980..6bc06afe3 100644 --- a/src/Version.props +++ b/src/Version.props @@ -1,6 +1,6 @@ - 10.7.21 + 10.7.22