From e420e15460ddcbe119d2c12140723a6aa4e9fac2 Mon Sep 17 00:00:00 2001 From: 28810 <2881099@qq.com> Date: Thu, 9 Oct 2025 16:44:13 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WithLock(NoLock)=20?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E5=85=BC=E5=AE=B9=20SqlServer=E3=80=81?= =?UTF-8?q?=E8=BE=BE=E6=A2=A6=EF=BC=9B#2058?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 155 ++++++++++++++++++ FreeSql/FreeSql.xml | 149 +++++++++++++++++ .../Curd/DamengSelect.cs | 6 +- .../Curd/SqlServerSelect.cs | 2 +- .../SqlServerExtensions.cs | 146 ----------------- 5 files changed, 310 insertions(+), 148 deletions(-) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 986fd37c6..14f8eb1d5 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -314,6 +314,142 @@ public static partial class FreeSqlGlobalExtensions freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => s); #endregion + #region SqlServer with(nolock)、with(index) 强制索引 + /// + /// SqlServer: with(nolock) + /// 达梦: with ur + /// + /// + /// + /// + /// 多表查询时的锁规则 + /// + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithLock(that, lockType, rule); + + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithLock(that, lockType, rule); + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithLock(that, lockType, rule); + static TReturn LocalWithLock(TReturn query, SqlServerLock lockType, Dictionary rule) + { + var selectProvider = query as Select0Provider; + switch (selectProvider._orm.Ado.DataType) + { + case DataType.SqlServer: + case DataType.OdbcSqlServer: + case DataType.CustomSqlServer: + break; + case DataType.Dameng: + if ((lockType & SqlServerLock.NoLock) == SqlServerLock.NoLock && + !selectProvider._tosqlAppendContent.Contains("with ur") && + rule?.Any(r => r.Value && selectProvider._tables.Any(t => t.Table?.Type == r.Key)) == true) + selectProvider._tosqlAppendContent = $"{selectProvider._tosqlAppendContent} with ur"; + return query; + default: + return query; + } + var oldalias = selectProvider._aliasRule; + selectProvider._aliasRule = (type, old) => + { + if (oldalias != null) old = oldalias(type, old); + if (rule == null) return LocalAppendWithString(old, lockType.ToString()); + return rule.TryGetValue(type, out var trybool) && trybool ? LocalAppendWithString(old, lockType.ToString()) : old; + }; + return query; + } + + /// + /// SqkServer with(index) 强制索引 + /// + /// + /// + /// + public static ISelect WithIndex(this ISelect that, string indexName) => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithIndex(that, indexName, null); + + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithIndex(that, indexName, null); + public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithIndex(that, indexName, null); + + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithIndex(that, indexName, rule); + + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithIndex(that, indexName, rule); + public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithIndex(that, indexName, rule); + + static TReturn LocalWithIndex(TReturn query, string indexName, Dictionary rule) + { + if (string.IsNullOrWhiteSpace(indexName) && rule?.Any() != true) return query; + var selectProvider = query as Select0Provider; + switch (selectProvider._orm.Ado.DataType) + { + case DataType.SqlServer: + case DataType.OdbcSqlServer: + case DataType.CustomSqlServer: + break; + default: + return query; + } + var oldalias = selectProvider._aliasRule; + selectProvider._aliasRule = (type, old) => + { + if (oldalias != null) old = oldalias(type, old); + if (string.IsNullOrWhiteSpace(indexName) == false && type == selectProvider._tables[0].Table.Type) return LocalAppendWithString(old, $"index={indexName}"); + if (rule == null) return old; + return rule.TryGetValue(type, out var tryidxName) && string.IsNullOrWhiteSpace(tryidxName) == false ? LocalAppendWithString(old, $"index={tryidxName}") : old; + }; + return query; + } + static string LocalAppendWithString(string old, string str) => old?.Contains(" With(") == true ? old.Replace(" With(", $" With({str}, ") : $"{old} With({str})"; + + /// + /// 设置全局 SqlServer: with(nolock) + /// 设置全局 达梦: with ur + /// + /// + public static IFreeSql SetGlobalSelectWithLock(this IFreeSql that, SqlServerLock lockType, Dictionary rule) + { + var value = NativeTuple.Create(lockType, rule); + _dicSetGlobalSelectWithLock.AddOrUpdate(that.Ado.Identifier, value, (_, __) => value); + return that; + } + public static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); + #endregion + #region 克隆ISelect /// /// 克隆 ISelect @@ -1543,3 +1679,22 @@ SELECT "); #endregion } + +[Flags] +public enum SqlServerLock +{ + NoLock = 1, + HoldLock = 2, + UpdLock = 4, + RowLock = 8, + ReadCommitted = 16, + ReadPast = 32, + ReadUnCommitted = 64, + RepeaTableRead = 256, + PagLock = 512, + Serializable = 1024, + TabLock = 2048, + TabLockX = 4096, + XLock = 8192, + NoWait = 16384 +} \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 767141eeb..d62771d4c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -5984,6 +5984,32 @@ + + + SqlServer: with(nolock) + 达梦: with ur + + + + + 多表查询时的锁规则 + + + + + SqkServer with(index) 强制索引 + + + + + + + + 设置全局 SqlServer: with(nolock) + 设置全局 达梦: with ur + + + 克隆 ISelect @@ -6484,3 +6510,126 @@ + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + MySql 5.6+: on duplicate key update + PostgreSQL 9.4+: on conflict do update + SqlServer 2008+: merge into + Oracle 11+: merge into + Sqlite: replace into + DuckDB: on conflict do update + 达梦: merge into + 人大金仓:on conflict do update + 神通:merge into + MsAccess:不支持 + 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 查询数据 + + + + + + + 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 删除数据 + + + + + + + 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + 事务体 () => {} + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + + 事务体 () => {} + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs index 5696a13c8..ec2c349df 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -145,7 +145,11 @@ namespace FreeSql.Dameng.Curd return sql; } - public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (FreeSqlGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm.Ado.Identifier, out var tryval)) + this.WithLock(tryval.Item1, tryval.Item2); + } public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 1c2bfe858..3a1baacb1 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -311,7 +311,7 @@ namespace FreeSql.SqlServer.Curd } public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (FreeSqlSqlServerGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm.Ado.Identifier, out var tryval)) + if (FreeSqlGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm.Ado.Identifier, out var tryval)) this.WithLock(tryval.Item1, tryval.Item2); } public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index c51a6a858..7d0ca3643 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -28,133 +28,6 @@ public static partial class FreeSqlSqlServerGlobalExtensions public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo(); - /// - /// SqlServer with(nolock) 查询 - /// - /// - /// - /// - /// 多表查询时的锁规则 - /// - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithLock(that, lockType, rule); - - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithLock(that, lockType, rule); - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithLock(that, lockType, rule); - static TReturn LocalWithLock(TReturn query, SqlServerLock lockType, Dictionary rule) - { - var selectProvider = query as Select0Provider; - switch (selectProvider._orm.Ado.DataType) - { - case DataType.SqlServer: - case DataType.OdbcSqlServer: - case DataType.CustomSqlServer: - break; - default: - return query; - } - var oldalias = selectProvider._aliasRule; - selectProvider._aliasRule = (type, old) => - { - if (oldalias != null) old = oldalias(type, old); - if (rule == null) return LocalAppendWithString(old, lockType.ToString()); - return rule.TryGetValue(type, out var trybool) && trybool ? LocalAppendWithString(old, lockType.ToString()) : old; - }; - return query; - } - /// - /// SqkServer with(index) 强制索引 - /// - /// - /// - /// - /// - public static ISelect WithIndex(this ISelect that, string indexName) => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithIndex(that, indexName, null); - - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithIndex(that, indexName, null); - public static ISelect WithIndex(this ISelect that, string indexName) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithIndex(that, indexName, null); - - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithIndex(that, indexName, rule); - - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithIndex(that, indexName, rule); - public static ISelect WithIndex(this ISelect that, string indexName, Dictionary rule) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithIndex(that, indexName, rule); - - static TReturn LocalWithIndex(TReturn query, string indexName, Dictionary rule) - { - if (string.IsNullOrWhiteSpace(indexName) && rule?.Any() != true) return query; - var selectProvider = query as Select0Provider; - switch (selectProvider._orm.Ado.DataType) - { - case DataType.SqlServer: - case DataType.OdbcSqlServer: - case DataType.CustomSqlServer: - break; - default: - return query; - } - var oldalias = selectProvider._aliasRule; - selectProvider._aliasRule = (type, old) => - { - if (oldalias != null) old = oldalias(type, old); - if (string.IsNullOrWhiteSpace(indexName) == false && type == selectProvider._tables[0].Table.Type) return LocalAppendWithString(old, $"index={indexName}"); - if (rule == null) return old; - return rule.TryGetValue(type, out var tryidxName) && string.IsNullOrWhiteSpace(tryidxName) == false ? LocalAppendWithString(old, $"index={tryidxName}") : old; - }; - return query; - } - static string LocalAppendWithString(string old, string str) => old?.Contains(" With(") == true ? old.Replace(" With(", $" With({str}, ") : $"{old} With({str})"; - - /// - /// 设置全局 SqlServer with(nolock) 查询 - /// - /// - /// - public static IFreeSql SetGlobalSelectWithLock(this IFreeSql that, SqlServerLock lockType, Dictionary rule) - { - var value = NativeTuple.Create(lockType, rule); - _dicSetGlobalSelectWithLock.AddOrUpdate(that.Ado.Identifier, value, (_, __) => value); - return that; - } - internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); - #region ExecuteSqlBulkCopy /// /// 批量插入或更新(操作的字段数量超过 2000 时收益大) @@ -440,22 +313,3 @@ public static partial class FreeSqlSqlServerGlobalExtensions #endif #endregion } - -[Flags] -public enum SqlServerLock -{ - NoLock = 1, - HoldLock = 2, - UpdLock = 4, - RowLock = 8, - ReadCommitted = 16, - ReadPast = 32, - ReadUnCommitted = 64, - RepeaTableRead = 256, - PagLock = 512, - Serializable = 1024, - TabLock = 2048, - TabLockX = 4096, - XLock = 8192, - NoWait = 16384 -} \ No newline at end of file