From f73c02d8d16559b9203b3fece3aa107eef5d1345 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 8 Apr 2022 21:19:51 +0800 Subject: [PATCH 01/16] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20[Table(AsTable?= =?UTF-8?q?=20=3D=20xx)]=20=E5=88=86=E8=A1=A8=E7=89=B9=E6=80=A7=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=88=86=E8=A1=A8=E6=8F=92=E5=85=A5/?= =?UTF-8?q?=E5=88=A0=E9=99=A4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 26 ++ FreeSql/DataAnnotations/TableAttribute.cs | 316 +++++++++++++++++- FreeSql/FreeSql.xml | 30 ++ .../CommonProvider/CodeFirstProvider.cs | 4 +- .../Internal/CommonProvider/DeleteProvider.cs | 117 +++++-- .../CommonProvider/DeleteProviderAsync.cs | 44 +-- .../Internal/CommonProvider/InsertProvider.cs | 73 +++- FreeSql/Internal/CommonUtils.cs | 6 +- FreeSql/Internal/Model/TableInfo.cs | 2 + FreeSql/Internal/UtilsExpressionTree.cs | 1 + .../Curd/ClickHouseDelete.cs | 14 +- .../Curd/DamengDelete.cs | 10 +- .../Curd/FirebirdDelete.cs | 141 ++++---- .../Curd/GBaseDelete.cs | 10 +- .../Curd/KingbaseESDelete.cs | 141 ++++---- .../Curd/MsAccessDelete.cs | 10 +- .../Curd/MySqlDelete.cs | 141 ++++---- .../Dameng/Curd/OdbcDamengDelete.cs | 10 +- .../KingbaseES/Curd/OdbcKingbaseESDelete.cs | 141 ++++---- .../MySql/Curd/OdbcMySqlDelete.cs | 141 ++++---- .../Oracle/Curd/OdbcOracleDelete.cs | 10 +- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 141 ++++---- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 163 +++++---- .../Curd/OracleDelete.cs | 10 +- .../Curd/PostgreSQLDelete.cs | 141 ++++---- .../Curd/ShenTongDelete.cs | 141 ++++---- .../Curd/SqlServerDelete.cs | 163 +++++---- .../Curd/SqliteDelete.cs | 10 +- 28 files changed, 1413 insertions(+), 744 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5a71b8ea..ad1146e7 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -99,6 +99,14 @@ namespace base_entity public B B { get; set; } } + [Table(Name = "as_table_log_{yyyyMMdd}", AsTable = "createtime=2022-1-1(1 month)")] + class AsTableLog + { + public Guid id { get; set; } + public string msg { get; set; } + public DateTime createtime { get; set; } + } + static void Main(string[] args) { #region 初始化 IFreeSql @@ -141,6 +149,24 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var sqlatb = fsql.Insert(new[] + { + new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, + new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, + new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, + new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, + new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, + new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") } + }).NoneParameter(); + var sqlat = sqlatb.ToSql(); + var sqlatr = sqlatb.ExecuteAffrows(); + + var sqlatc = fsql.Delete().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); + var sqlatca = sqlatc.ToSql(); + var sqlatcr = sqlatc.ExecuteAffrows(); + + fsql.Aop.AuditValue += new EventHandler((_, e) => { diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index b08b5c4f..a099f9e4 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -1,6 +1,11 @@ -using System; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; using System.Collections.Concurrent; -using System.Linq.Expressions; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text.RegularExpressions; namespace FreeSql.DataAnnotations { @@ -26,5 +31,312 @@ namespace FreeSql.DataAnnotations internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); internal ConcurrentDictionary _navigates { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); internal ConcurrentDictionary _indexs { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + + /// + /// 格式:属性名=开始时间(递增) + /// 按年分表:[Table(Name = "log_{yyyy}", AsTable = "create_time=2022-1-1(1 year)")] + /// 按月分表:[Table(Name = "log_{yyyyMM}", AsTable = "create_time=2022-5-1(1 month)")] + /// 按日分表:[Table(Name = "log_{yyyyMMdd}", AsTable = "create_time=2022-5-1(5 day)")] + /// 按时分表:[Table(Name = "log_{yyyyMMddHH}", AsTable = "create_time=2022-5-1(6 hour)")] + /// + public string AsTable { get; set; } + + internal void ParseAsTable(TableInfo tb) + { + if (string.IsNullOrEmpty(AsTable) == false) + { + var atm = Regex.Match(AsTable, @"([\w_\d]+)\s*=\s*(\d\d\d\d)\s*\-\s*(\d\d?)\s*\-\s*(\d\d?)\s*\((\d+)\s*(year|month|day|hour)\)", RegexOptions.IgnoreCase); + if (atm.Success == false) + throw new Exception($"[Table(AsTable = \"{AsTable}\")] 特性值格式错误"); + + tb.AsTableColumn = tb.Columns.TryGetValue(atm.Groups[1].Value, out var trycol) ? trycol : + tb.ColumnsByCs.TryGetValue(atm.Groups[1].Value, out trycol) ? trycol : throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不存在"); + int.TryParse(atm.Groups[5].Value, out var atm5); + string atm6 = atm.Groups[6].Value.ToLower(); + tb.AsTableImpl = new DateTimeAsTableImpl(Name, DateTime.Parse($"{atm.Groups[2].Value}-{atm.Groups[3].Value}-{atm.Groups[4].Value}"), dt => + { + switch (atm6) + { + case "year": return dt.AddYears(atm5); + case "month": return dt.AddMonths(atm5); + case "day": return dt.AddDays(atm5); + case "hour": return dt.AddHours(atm5); + } + throw new NotImplementedException($"AsTable 未实现的功能 {AsTable}"); + }); + } + } + } + + public interface IAsTable + { + /// + /// 所有分表名 + /// + ICollection AllTables { get; } + string GetTableNameByColumnValue(object columnValue, bool autoExpand = false); + ICollection GetTableNamesByColumnValueRange(object columnValue1, object columnValue2); + ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, TableInfo table, CommonUtils commonUtils); + } + class DateTimeAsTableImpl : IAsTable + { + readonly List _allTables = new List(); + readonly List _allTablesTime = new List(); + readonly DateTime _beginTime; + DateTime _lastTime; + Func _nextTimeFunc; + string _tableName; + Match _tableNameFormat; + static Regex _regTableNameFormat = new Regex(@"\{([^\\}]+)\}"); + + public DateTimeAsTableImpl(string tableName, DateTime beginTime, Func nextTimeFunc) + { + if (nextTimeFunc == null) throw new ArgumentException($"nextTimeFunc 不可以为 null"); + beginTime = beginTime.Date; //日期部分作为开始 + _beginTime = beginTime; + _nextTimeFunc = nextTimeFunc; + _tableName = tableName; + _tableNameFormat = _regTableNameFormat.Match(tableName); + if (string.IsNullOrEmpty(_tableNameFormat.Groups[1].Value)) throw new ArgumentException("tableName 格式错误,示例:“log_{yyyyMMdd}”"); + ExpandTable(beginTime, DateTime.Now); + } + + int GetTimestamp(DateTime dt) => (int)dt.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + void ExpandTable(DateTime beginTime, DateTime endTime) + { + if (beginTime > endTime) endTime = _nextTimeFunc(beginTime); + while (beginTime < endTime) + { + var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value); + var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr); + if (_allTables.Contains(name)) throw new ArgumentException($"tableName:{_tableName} 生成了相同的分表名"); + _allTables.Insert(0, name); + _allTablesTime.Insert(0, beginTime); + _lastTime = beginTime; + beginTime = _nextTimeFunc(beginTime); + } + } + DateTime ParseColumnValue(object columnValue) + { + if (columnValue == null) throw new Exception($"分表字段值不能为 null"); + DateTime dt; + if (columnValue is DateTime || columnValue is DateTime?) + dt = (DateTime)columnValue; + else if (columnValue is string) + { + if (DateTime.TryParse(string.Concat(columnValue), out dt) == false) throw new Exception($"分表字段值 \"{columnValue}\" 不能转化成 DateTime"); + } + else if (columnValue is int || columnValue is long) + { + dt = new DateTime(1970, 1, 1).AddSeconds((double)columnValue); + } + else throw new Exception($"分表字段值 \"{columnValue}\" 不能转化成 DateTime"); + return dt; + } + + public string GetTableNameByColumnValue(object columnValue, bool autoExpand = false) + { + var dt = ParseColumnValue(columnValue); + if (dt < _allTablesTime.Last()) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \""); + var tmpTime = _nextTimeFunc(_lastTime); + if (dt > tmpTime && autoExpand) + { + // 自动建表 + ExpandTable(tmpTime, _nextTimeFunc(dt)); + } + for (var a = 0; a < _allTables.Count; a++) + if (dt >= _allTablesTime[a]) + return _allTables[a]; + throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 未匹配到分表名"); + } + public ICollection GetTableNamesByColumnValueRange(object columnValue1, object columnValue2) + { + var dt1 = ParseColumnValue(columnValue1); + var dt2 = ParseColumnValue(columnValue2); + if (dt1 > dt2) return new string[0]; + + int dt1idx = 0, dt2idx = 0; + if (dt1 < _allTablesTime.Last()) dt1idx = _allTablesTime.Count - 1; + else + { + for (var a = _allTablesTime.Count - 2; a > -1; a--) + { + if (dt1 < _allTablesTime[a]) + { + dt1idx = a + 1; + break; + } + } + } + if (dt2 > _allTablesTime.First()) dt2idx = 0; + else + { + for (var a = 0; a < _allTablesTime.Count; a++) + { + if (dt2 >= _allTablesTime[a]) + { + dt2idx = a; + break; + } + } + } + if (dt2idx == -1) return new string[0]; + + if (dt1idx == _allTables.Count - 1 && dt2idx == 0) return _allTables; + var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1); + return names; + } + + static readonly ConcurrentDictionary _dicRegSqlWhereDateTimes = new ConcurrentDictionary(); + static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterName) + { + return _dicRegSqlWhereDateTimes.GetOrAdd($"{columnName},{quoteParameterName}", cn => + { + cn = columnName.Replace(@"\[", @"\\[").Replace(@"\]", @"\\]"); + return new[] + { + new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), + + new Regex($@"({cn}\s*(<|<=|>|>=|=)\s*)(datetime|cdate|to_date)\(({quoteParameterName}[\w_]+)\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(<|<=|>|>=|=)(\s*))to_timestamp\(({quoteParameterName}[\w_]+)\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(<|<=|>|>=|=)(\s*))cast\(({quoteParameterName}[^w_]+) as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(<|<=|>|>=|=)(\s*))({quoteParameterName}[^w_]+)::(datetime|timestamp)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and\s+)(datetime|cdate|to_date)\(({quoteParameterName}[\w_]+)\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and(\s+))to_timestamp\(({quoteParameterName}[\w_]+)\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and(\s+))cast\(({quoteParameterName}[^w_]+) as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and(\s+))({quoteParameterName}[^w_]+)::(datetime|timestamp)", RegexOptions.IgnoreCase), + + + new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*between\s*{quoteParameterName}([\w_]+)\s*and\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), + + new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)\s*and\s*{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), + + new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), + }; + }); + } + /// + /// 可以匹配以下条件(支持参数化): + /// `field` BETWEEN '2022-01-01 00:00:00' AND '2022-03-01 00:00:00' + /// `field` > '2022-01-01 00:00:00' AND `field` < '2022-03-01 00:00:00' + /// `field` > '2022-01-01 00:00:00' AND `field` <= '2022-03-01 00:00:00' + /// `field` >= '2022-01-01 00:00:00' AND `field` < '2022-03-01 00:00:00' + /// `field` >= '2022-01-01 00:00:00' AND `field` <= '2022-03-01 00:00:00' + /// `field` > '2022-01-01 00:00:00' + /// `field` >= '2022-01-01 00:00:00' + /// `field` < '2022-01-01 00:00:00' + /// `field` <= '2022-01-01 00:00:00' + /// + /// + /// + public ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, TableInfo table, CommonUtils commonUtils) + { + var quoteParameterName = commonUtils.QuoteParamterName(""); + var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); + var regs = GetRegSqlWhereDateTimes(commonUtils.QuoteSqlName(table.AsTableColumn.Attribute.Name), quoteParameterName); + for (var a = 0; a < 16; a++) sqlWhere = regs[a].Replace(sqlWhere, "$1$4"); + + var m = regs[16].Match(sqlWhere); + if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value); + m = m = regs[17].Match(sqlWhere); + if (m.Success) + { + var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); + var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault(); + if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); + return GetTableNamesByColumnValueRange(val1, val2); + } + m = m = regs[18].Match(sqlWhere); + if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); + m = regs[19].Match(sqlWhere); + if (m.Success) + { + var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); + var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault(); + if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); + return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(val1), ParseColumnValue(val2)); + } + m = regs[20].Match(sqlWhere); + if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); + m = regs[21].Match(sqlWhere); + if (m.Success) + { + var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); + if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); + return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1)); + } + return _allTables; + + ICollection LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2) + { + switch (opt1) + { + case "<": + case "<=": + if (opt1 == "<") val1 = val1.AddSeconds(-1); + switch (opt2) + { + case "<": + val2 = val2.AddSeconds(-1); + return GetTableNamesByColumnValueRange(_beginTime, val1 > val2 ? val2 : val1); + case "<=": + return GetTableNamesByColumnValueRange(_beginTime, val1 > val2 ? val2 : val1); + case ">": + val2 = val2.AddSeconds(1); + return GetTableNamesByColumnValueRange(val2, val1); + case ">=": + return GetTableNamesByColumnValueRange(val2, val1); + } + break; + case ">": + case ">=": + if (opt1 == ">") val1 = val1.AddSeconds(1); + switch (opt2) + { + case "<": + val2 = val2.AddSeconds(-1); + return GetTableNamesByColumnValueRange(val1, val2); + case "<=": + return GetTableNamesByColumnValueRange(val1, val2); + case ">": + val2 = val2.AddSeconds(1); + return GetTableNamesByColumnValueRange(val1 > val2 ? val1 : val2, _lastTime); + case ">=": + return GetTableNamesByColumnValueRange(val1 > val2 ? val1 : val2, _lastTime); + } + break; + } + return _allTables; + } + ICollection LocalGetTables2(string opt, DateTime val1) + { + switch (m.Groups[1].Value) + { + case "<": + val1 = val1.AddSeconds(-1); + return GetTableNamesByColumnValueRange(_beginTime, val1); + case "<=": + return GetTableNamesByColumnValueRange(_beginTime, val1); + case ">": + val1 = val1.AddSeconds(1); + return GetTableNamesByColumnValueRange(val1, _lastTime); + case ">=": + return GetTableNamesByColumnValueRange(val1, _lastTime); + } + return _allTables; + } + } + + public ICollection AllTables => _allTables; } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 55a8f429..751cf507 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -397,6 +397,36 @@ 禁用 CodeFirst 同步结构迁移 + + + 格式:属性名=开始时间(递增) + 按年分表:[Table(Name = "log_{yyyy}", AsTable = "create_time=2022-1-1(1 year)")] + 按月分表:[Table(Name = "log_{yyyyMM}", AsTable = "create_time=2022-5-1(1 month)")] + 按日分表:[Table(Name = "log_{yyyyMMdd}", AsTable = "create_time=2022-5-1(5 day)")] + 按时分表:[Table(Name = "log_{yyyyMMddHH}", AsTable = "create_time=2022-5-1(6 hour)")] + + + + + 所有分表名 + + + + + 可以匹配以下条件(支持参数化): + `field` BETWEEN '2022-01-01 00:00:00' AND '2022-03-01 00:00:00' + `field` > '2022-01-01 00:00:00' AND `field` < '2022-03-01 00:00:00' + `field` > '2022-01-01 00:00:00' AND `field` <= '2022-03-01 00:00:00' + `field` >= '2022-01-01 00:00:00' AND `field` < '2022-03-01 00:00:00' + `field` >= '2022-01-01 00:00:00' AND `field` <= '2022-03-01 00:00:00' + `field` > '2022-01-01 00:00:00' + `field` >= '2022-01-01 00:00:00' + `field` < '2022-01-01 00:00:00' + `field` <= '2022-01-01 00:00:00' + + + + 数据库表名 diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index b0fe1e4b..03439075 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -95,7 +95,9 @@ namespace FreeSql.Internal.CommonProvider { if (objects == null) return; var syncObjects = objects.Where(a => a.entityType != null && a.entityType != typeof(object) && _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) - .Select(a => new TypeAndName(a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); + .Select(a => new TypeAndName(a.entityType, GetTableNameLowerOrUpper(a.tableName))) + .Where(a => !(string.IsNullOrEmpty(a.tableName) == true && GetTableByEntity(a.entityType)?.AsTableImpl != null)) + .ToArray(); if (syncObjects.Any() == false) return; var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray()); _orm.Aop.SyncStructureBeforeHandler?.Invoke(this, before); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 1e84d341..b8ee0cc1 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -10,8 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - - public abstract partial class DeleteProvider : IDelete + public abstract partial class DeleteProvider { public IFreeSql _orm; public CommonUtils _commonUtils; @@ -26,7 +25,10 @@ namespace FreeSql.Internal.CommonProvider public DbConnection _connection; public int _commandTimeout = 0; public Action _interceptSql; + } + public abstract partial class DeleteProvider : DeleteProvider, IDelete + { public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { _orm = orm; @@ -66,28 +68,32 @@ namespace FreeSql.Internal.CommonProvider public int ExecuteAffrows() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; - Exception exception = null; - try + DbParameter[] dbParms = null; + ToSqlFetch(sb => { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); + if (dbParms == null) dbParms = _params.ToArray(); + var sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + affrows += _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) this.ClearData(); return affrows; } public abstract List ExecuteDeleted(); @@ -165,16 +171,77 @@ namespace FreeSql.Internal.CommonProvider public virtual string ToSql() { if (_whereTimes <= 0) return null; - var sb = new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" WHERE ").Append(_where); + var sb = new StringBuilder(); + ToSqlFetch(sql => + { + sb.Append(sql).Append("\r\n\r\n;\r\n\r\n"); + }); + if (sb.Length > 0) sb.Remove(sb.Length - 9, 9); + return sb.ToString(); + } + + public void ToSqlFetch(Action fetch) + { + if (_whereTimes <= 0) return; + var newwhere = new StringBuilder().Append(" WHERE ").Append(_where); if (_whereGlobalFilter.Any()) { var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false); if (string.IsNullOrEmpty(globalFilterCondi) == false) - sb.Append(" AND ").Append(globalFilterCondi); + newwhere.Append(" AND ").Append(globalFilterCondi); } + + var sb = new StringBuilder(); + if (_table.AsTableImpl != null) + { + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + foreach (var name in names) + { + _tableRule = old => name; + sb.Clear().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere); + _interceptSql?.Invoke(sb); + fetch(sb); + } + return; + } + + sb.Insert(0, _commonUtils.QuoteSqlName(TableRuleInvoke())).Insert(0, "DELETE FROM "); _interceptSql?.Invoke(sb); - return sb.ToString(); + fetch(sb); } +#if net40 +#else + async public Task ToSqlFetchAsync(Func fetchAsync) + { + if (_whereTimes <= 0) return; + var newwhere = new StringBuilder().Append(" WHERE ").Append(_where); + + if (_whereGlobalFilter.Any()) + { + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false); + if (string.IsNullOrEmpty(globalFilterCondi) == false) + newwhere.Append(" AND ").Append(globalFilterCondi); + } + + var sb = new StringBuilder(); + if (_table.AsTableImpl != null) + { + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + foreach (var name in names) + { + _tableRule = old => name; + sb.Clear().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere); + _interceptSql?.Invoke(sb); + await fetchAsync(sb); + } + return; + } + + sb.Insert(0, _commonUtils.QuoteSqlName(TableRuleInvoke())).Insert(0, "DELETE FROM "); + _interceptSql?.Invoke(sb); + await fetchAsync(sb); + } +#endif } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs index 85073150..d2115b5f 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs @@ -16,28 +16,32 @@ namespace FreeSql.Internal.CommonProvider #else async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; - Exception exception = null; - try + DbParameter[] dbParms = null; + await ToSqlFetchAsync(async sb => { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); + if (dbParms == null) dbParms = _params.ToArray(); + var sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + affrows += await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) this.ClearData(); return affrows; } public abstract Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 36450189..e4eb1a42 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -14,12 +14,11 @@ using System.Collections; namespace FreeSql.Internal.CommonProvider { - public abstract partial class InsertProvider : IInsert where T1 : class + public abstract partial class InsertProvider { public IFreeSql _orm; public CommonUtils _commonUtils; public CommonExpression _commonExpression; - public List _source = new List(); public Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public TableInfo _table; @@ -28,11 +27,17 @@ namespace FreeSql.Internal.CommonProvider public bool _noneParameter, _insertIdentity; public int _batchValuesLimit, _batchParameterLimit; public bool _batchAutoTransaction = true; - public Action> _batchProgress; public DbParameter[] _params; public DbTransaction _transaction; public DbConnection _connection; public int _commandTimeout = 0; + } + + public abstract partial class InsertProvider : InsertProvider, IInsert where T1 : class + { + public List _source = new List(); + internal List _sourceOld; + public Action> _batchProgress; public InsertProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { @@ -43,6 +48,7 @@ namespace FreeSql.Internal.CommonProvider _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); IgnoreCanInsert(); + _sourceOld = _source; } /// @@ -62,6 +68,7 @@ namespace FreeSql.Internal.CommonProvider _batchProgress = null; _insertIdentity = false; _source.Clear(); + _sourceOld = _source; _ignore.Clear(); _auditValueChangedDict.Clear(); _params = null; @@ -189,7 +196,7 @@ namespace FreeSql.Internal.CommonProvider } #region 参数化数据限制,或values数量限制 - protected List[] SplitSource(int valuesLimit, int parameterLimit) + protected List[] SplitSource(int valuesLimit, int parameterLimit, bool isAsTableSplited = false) { valuesLimit = valuesLimit - 1; parameterLimit = parameterLimit - 1; @@ -198,6 +205,28 @@ namespace FreeSql.Internal.CommonProvider if (_source == null || _source.Any() == false) return new List[0]; if (_source.Count == 1) return new[] { _source }; + if (_table.AsTableImpl != null && isAsTableSplited == false) + { + var atarr = _source.Select(a => new + { + item = a, + splitKey = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(a), true) + }).GroupBy(a => a.splitKey, a => a.item).ToArray(); + if (atarr.Length > 1) + { + var oldSource = _source; + var arrret = new List>(); + foreach (var item in atarr) + { + _source = item.ToList(); + var itemret = SplitSource(valuesLimit + 1, parameterLimit + 1, true); + arrret.AddRange(itemret); + } + _source = oldSource; + return arrret.ToArray(); + } + } + var takeMax = valuesLimit; if (_noneParameter == false) { @@ -510,8 +539,8 @@ namespace FreeSql.Internal.CommonProvider protected string TableRuleInvoke() { var tbname = _table?.DbName ?? ""; - if (_tableRule == null) return tbname; - var newname = _tableRule(tbname); + if (_tableRule == null && _table.AsTableImpl == null) return tbname; + var newname = _table.AsTableImpl?.GetTableNameByColumnValue(_source.Any() ? _table.AsTableColumn.GetValue(_source.FirstOrDefault()) : DateTime.Now) ?? _tableRule(tbname); if (newname == tbname) return tbname; if (string.IsNullOrEmpty(newname)) return tbname; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); @@ -540,14 +569,38 @@ namespace FreeSql.Internal.CommonProvider return this; } - public virtual string ToSql() => ToSqlValuesOrSelectUnionAllExtension102(true, null, null); + public virtual string ToSql() => ToSqlValuesOrSelectUnionAllExtension103(true, null, null, false); - public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension102(isValues, null, null); - public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) => ToSqlValuesOrSelectUnionAllExtension102(isValues, null, onrow); - public string ToSqlValuesOrSelectUnionAllExtension102(bool isValues, Action onrowPre, Action onrow) + public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension103(isValues, null, null, false); + public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) => ToSqlValuesOrSelectUnionAllExtension103(isValues, null, onrow, false); + public string ToSqlValuesOrSelectUnionAllExtension102(bool isValues, Action onrowPre, Action onrow) => ToSqlValuesOrSelectUnionAllExtension103(isValues, null, onrow, false); + string ToSqlValuesOrSelectUnionAllExtension103(bool isValues, Action onrowPre, Action onrow, bool isAsTableSplited) { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); + + if (_table.AsTableImpl != null && isAsTableSplited == false && _source == _sourceOld) + { + var atarr = _source.Select(a => new + { + item = a, + splitKey = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(a), true) + }).GroupBy(a => a.splitKey, a => a.item).ToArray(); + if (atarr.Length > 1) + { + var oldSource = _source; + var arrret = new List>(); + foreach (var item in atarr) + { + _source = item.ToList(); + sb.Append(ToSqlValuesOrSelectUnionAllExtension103(isValues, onrowPre, onrow, true)).Append("\r\n\r\n;\r\n\r\n"); + } + _source = oldSource; + if (sb.Length > 0) sb.Remove(sb.Length - 9, 9); + return sb.ToString(); + } + } + sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append('('); var colidx = 0; foreach (var col in _table.Columns.Values) diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 93be8c72..315eca86 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -125,7 +125,9 @@ namespace FreeSql.Internal { if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; - if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; + if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; + if (!string.IsNullOrEmpty(trytb.AsTable)) attr.AsTable = trytb.AsTable; + } var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); foreach (var tryattrobj in attrs) @@ -135,10 +137,12 @@ namespace FreeSql.Internal if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; + if (!string.IsNullOrEmpty(tryattr.AsTable)) attr.AsTable = tryattr.AsTable; } if (!string.IsNullOrEmpty(attr.Name)) return attr; if (!string.IsNullOrEmpty(attr.OldName)) return attr; if (attr._DisableSyncStructure != null) return attr; + if (!string.IsNullOrEmpty(attr.AsTable)) return attr; return null; } public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 4058a626..c09484ef 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -27,6 +27,8 @@ namespace FreeSql.Internal.Model public bool IsRereadSql { get; internal set; } public bool IsDictionaryType { get; internal set; } + public IAsTable AsTableImpl { get; internal set; } + public ColumnInfo AsTableColumn { get; internal set; } public ColumnInfo VersionColumn { get; set; } ConcurrentDictionary _refs { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6108c130..c8b513b2 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -393,6 +393,7 @@ namespace FreeSql.Internal if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false && trytb.VersionColumn.Attribute.MapType != typeof(byte[])) throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型 或者 byte[],并且不可为 Nullable"); } + tbattr?.ParseAsTable(trytb); var indexesDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); //从数据库查找主键、自增、索引 diff --git a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseDelete.cs b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseDelete.cs index c950f12b..9439b5bf 100644 --- a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseDelete.cs +++ b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseDelete.cs @@ -16,20 +16,16 @@ namespace FreeSql.ClickHouse.Curd { } - public override List ExecuteDeleted() - { - throw new NotImplementedException("FreeSql.ClickHouse.Curd 暂未实现"); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Provider.ClickHouse 未实现该功能"); + public override string ToSql() { - return base.ToSql().Replace("DELETE FROM", "ALTER TABLE").Replace("WHERE", "DELETE WHERE"); + return base.ToSql().Replace("DELETE FROM ", "ALTER TABLE ").Replace(" WHERE ", " DELETE WHERE "); } + #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException("FreeSql.ClickHouse.Curd 暂未实现"); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.ClickHouse 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs index 800b2a10..59f31b49 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.Dameng.Curd { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Provider.Dameng 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Dameng 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs index 84afe01b..7a100a0d 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.Firebird.Curd public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.TypeLazy ?? _table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.Firebird.Curd #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.TypeLazy ?? _table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs index 7e9f7b90..27b4948e 100644 --- a/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.GBase.Curd { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Provider.GBase 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.GBase 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs index cd91741b..0ca3dd5b 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.KingbaseES public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.KingbaseES #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs index 3c5fd1fd..814bf6f1 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.MsAccess.Curd { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Provider.MsAccess 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.MsAccess 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 74031933..5f5431a4 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.MySql.Curd public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.MySql.Curd #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs index a57a8a84..8ee23ec8 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.Odbc.Dameng { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Odbc.Dameng 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Dameng 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs index edb6d6aa..e4a381b9 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.Odbc.KingbaseES public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.Odbc.KingbaseES #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index 144e880f..fdf91e47 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.Odbc.MySql public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.Odbc.MySql #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs index a5e87939..b5ceafe7 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.Odbc.Oracle { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Odbc.Oracle 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Oracle 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index 72267df3..b83cc626 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.Odbc.PostgreSQL public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.Odbc.PostgreSQL #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index f7238b32..ab0bc595 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,45 +19,56 @@ namespace FreeSql.Odbc.SqlServer public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -64,45 +76,56 @@ namespace FreeSql.Odbc.SqlServer #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs index 618819b8..c3f7203d 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.Oracle.Curd { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Provider.Oracle 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Oracle 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index c4c60837..2ed402c9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.PostgreSQL.Curd public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.PostgreSQL.Curd #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs index 5b30f6c0..dcaf61fa 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,40 +19,50 @@ namespace FreeSql.ShenTong.Curd public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -59,40 +70,50 @@ namespace FreeSql.ShenTong.Curd #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw ex; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 61e386ab..ff20a9a3 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,45 +19,56 @@ namespace FreeSql.SqlServer.Curd public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } @@ -64,45 +76,56 @@ namespace FreeSql.SqlServer.Curd #else async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) { - exception = ex; - throw; + this.ClearData(); + sbret.Clear(); } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - this.ClearData(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs index 3a108707..0e46d437 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs @@ -16,17 +16,11 @@ namespace FreeSql.Sqlite.Curd { } - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); #endif } } From d051a27d4e14c6ceb3578ddfcb7af45c76935ee1 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 9 Apr 2022 11:55:13 +0800 Subject: [PATCH 02/16] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20[Table(AsTable?= =?UTF-8?q?=20=3D=20xx)]=20=E5=88=86=E8=A1=A8=E7=89=B9=E6=80=A7=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=88=86=E8=A1=A8=E6=9B=B4=E6=96=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 32 +- FreeSql/FreeSql.xml | 402 ++++++++++-------- .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../Internal/CommonProvider/InsertProvider.cs | 13 +- .../Internal/CommonProvider/UpdateProvider.cs | 222 ++++++++-- .../CommonProvider/UpdateProviderAsync.cs | 45 +- .../Curd/ClickHouseInsert.cs | 44 +- .../Curd/ClickHouseUpdate.cs | 64 ++- .../Curd/CustomUpdate.cs | 4 +- .../Curd/DamengUpdate.cs | 11 +- .../Curd/FirebirdUpdate.cs | 145 ++++--- .../Curd/GBaseUpdate.cs | 10 +- .../Curd/KingbaseESUpdate.cs | 145 ++++--- .../Curd/MsAccessUpdate.cs | 10 +- .../Curd/MySqlUpdate.cs | 145 ++++--- .../Dameng/Curd/OdbcDamengUpdate.cs | 11 +- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 145 ++++--- .../MySql/Curd/OdbcMySqlUpdate.cs | 145 ++++--- .../Oracle/Curd/OdbcOracleUpdate.cs | 11 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 145 ++++--- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 167 ++++---- .../Curd/OracleUpdate.cs | 11 +- .../Curd/PostgreSQLUpdate.cs | 145 ++++--- .../Curd/ShenTongUpdate.cs | 145 ++++--- .../Curd/SqlServerUpdate.cs | 167 ++++---- .../Curd/SqliteUpdate.cs | 11 +- 26 files changed, 1359 insertions(+), 1040 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index ad1146e7..60e38a9e 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -149,7 +149,7 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion - var sqlatb = fsql.Insert(new[] + var testitems = new[] { new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, @@ -158,7 +158,8 @@ namespace base_entity new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") } - }).NoneParameter(); + }; + var sqlatb = fsql.Insert(testitems).NoneParameter(); var sqlat = sqlatb.ToSql(); var sqlatr = sqlatb.ExecuteAffrows(); @@ -166,6 +167,33 @@ namespace base_entity var sqlatca = sqlatc.ToSql(); var sqlatcr = sqlatc.ExecuteAffrows(); + var sqlatd1 = fsql.Update().SetSource(testitems[0]); + var sqlatd101 = sqlatd1.ToSql(); + var sqlatd102 = sqlatd1.ExecuteAffrows(); + + var sqlatd2 = fsql.Update().SetSource(testitems[5]); + var sqlatd201 = sqlatd2.ToSql(); + var sqlatd202 = sqlatd2.ExecuteAffrows(); + + var sqlatd3 = fsql.Update().SetSource(testitems); + var sqlatd301 = sqlatd3.ToSql(); + var sqlatd302 = sqlatd3.ExecuteAffrows(); + + var sqlatd4 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg"); + var sqlatd401 = sqlatd4.ToSql(); + var sqlatd402 = sqlatd4.ExecuteAffrows(); + + var sqlatd5 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); + var sqlatd501 = sqlatd5.ToSql(); + var sqlatd502 = sqlatd5.ExecuteAffrows(); + + var sqlatd6 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime > DateTime.Parse("2022-3-1")); + var sqlatd601 = sqlatd6.ToSql(); + var sqlatd602 = sqlatd6.ExecuteAffrows(); + + var sqlatd7 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime < DateTime.Parse("2022-5-1")); + var sqlatd701 = sqlatd7.ToSql(); + var sqlatd702 = sqlatd7.ExecuteAffrows(); fsql.Aop.AuditValue += new EventHandler((_, e) => { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 751cf507..4c8d9624 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3254,177 +3254,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 可自定义解析表达式 @@ -4319,12 +4148,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4400,12 +4223,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -5087,3 +4904,222 @@ +ystem.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index b8ee0cc1..639fa6bc 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -206,9 +206,10 @@ namespace FreeSql.Internal.CommonProvider return; } - sb.Insert(0, _commonUtils.QuoteSqlName(TableRuleInvoke())).Insert(0, "DELETE FROM "); + sb.Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere); _interceptSql?.Invoke(sb); fetch(sb); + sb.Clear(); } #if net40 #else @@ -241,6 +242,7 @@ namespace FreeSql.Internal.CommonProvider sb.Insert(0, _commonUtils.QuoteSqlName(TableRuleInvoke())).Insert(0, "DELETE FROM "); _interceptSql?.Invoke(sb); await fetchAsync(sb); + sb.Clear(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index e4eb1a42..de45338f 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -540,7 +540,18 @@ namespace FreeSql.Internal.CommonProvider { var tbname = _table?.DbName ?? ""; if (_tableRule == null && _table.AsTableImpl == null) return tbname; - var newname = _table.AsTableImpl?.GetTableNameByColumnValue(_source.Any() ? _table.AsTableColumn.GetValue(_source.FirstOrDefault()) : DateTime.Now) ?? _tableRule(tbname); + string newname = null; + if (_table.AsTableImpl != null) + { + if (_source.Any()) + newname = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(_source.FirstOrDefault())); + else if (_tableRule == null) + newname = _table.AsTableImpl.GetTableNameByColumnValue(DateTime.Now); + else + newname = _tableRule(_table.DbName); + } + else + newname = _tableRule(_table.DbName); if (newname == tbname) return tbname; if (string.IsNullOrEmpty(newname)) return tbname; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index ea98dc63..306036d3 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -12,13 +12,11 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - - public abstract partial class UpdateProvider : IUpdate + public abstract partial class UpdateProvider { public IFreeSql _orm; public CommonUtils _commonUtils; public CommonExpression _commonExpression; - public List _source = new List(); public Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public TableInfo _table; @@ -33,12 +31,18 @@ namespace FreeSql.Internal.CommonProvider public bool _noneParameter; public int _batchRowsLimit, _batchParameterLimit; public bool _batchAutoTransaction = true; - public Action> _batchProgress; public DbTransaction _transaction; public DbConnection _connection; public int _commandTimeout = 0; public Action _interceptSql; public byte[] _updateVersionValue; + } + + public abstract partial class UpdateProvider : UpdateProvider, IUpdate + { + public List _source = new List(); + public List _sourceOld; + public Action> _batchProgress; public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { @@ -52,6 +56,7 @@ namespace FreeSql.Internal.CommonProvider if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); IgnoreCanUpdate(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); + _sourceOld = _source; } /// @@ -69,6 +74,7 @@ namespace FreeSql.Internal.CommonProvider _batchRowsLimit = _batchParameterLimit = 0; _batchAutoTransaction = true; _source.Clear(); + _sourceOld = _source; _ignore.Clear(); _auditValueChangedDict.Clear(); _where.Clear(); @@ -138,7 +144,7 @@ namespace FreeSql.Internal.CommonProvider } #region 参数化数据限制,或values数量限制 - protected internal List[] SplitSource(int valuesLimit, int parameterLimit) + protected internal List[] SplitSource(int valuesLimit, int parameterLimit, bool isAsTableSplited = false) { valuesLimit = valuesLimit - 1; parameterLimit = parameterLimit - 1; @@ -147,6 +153,28 @@ namespace FreeSql.Internal.CommonProvider if (_source == null || _source.Any() == false) return new List[0]; if (_source.Count == 1) return new[] { _source }; + if (_table.AsTableImpl != null && isAsTableSplited == false) + { + var atarr = _source.Select(a => new + { + item = a, + splitKey = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(a), true) + }).GroupBy(a => a.splitKey, a => a.item).ToArray(); + if (atarr.Length > 1) + { + var oldSource = _source; + var arrret = new List>(); + foreach (var item in atarr) + { + _source = item.ToList(); + var itemret = SplitSource(valuesLimit + 1, parameterLimit + 1, true); + arrret.AddRange(itemret); + } + _source = oldSource; + return arrret.ToArray(); + } + } + var takeMax = valuesLimit; if (_noneParameter == false) { @@ -314,28 +342,33 @@ namespace FreeSql.Internal.CommonProvider protected int RawExecuteAffrows() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; - Exception exception = null; - try + DbParameter[] dbParms = null; + ToSqlFetch(sb => { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(affrows, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) dbParms = _params.Concat(_paramsSource).ToArray(); + var sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var affrowstmp = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(affrowstmp, sql, dbParms); + affrows += affrowstmp; + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); return affrows; } @@ -692,8 +725,19 @@ namespace FreeSql.Internal.CommonProvider protected string TableRuleInvoke() { - if (_tableRule == null) return _table.DbName; - var newname = _tableRule(_table.DbName); + if (_tableRule == null && _table.AsTableImpl == null) return _table.DbName; + string newname = null; + if (_table.AsTableImpl != null) + { + if (_source.Any()) + newname = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(_source.FirstOrDefault())); + else if (_tableRule == null) + newname = _table.AsTableImpl.GetTableNameByColumnValue(DateTime.Now); + else + newname = _tableRule(_table.DbName); + } + else + newname = _tableRule(_table.DbName); if (newname == _table.DbName) return _table.DbName; if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); @@ -725,9 +769,114 @@ namespace FreeSql.Internal.CommonProvider public virtual string ToSql() { - if (_where.Length == 0 && _source.Any() == false) return null; + if (_source.Any()) + { + var sb1 = new StringBuilder(); + ToSqlExtension110(sb1, false); + return sb1.ToString(); + } + + if (_where.Length == 0) return null; + + var sb2 = new StringBuilder(); + ToSqlFetch(sql => + { + sb2.Append(sql).Append("\r\n\r\n;\r\n\r\n"); + }); + if (sb2.Length > 0) sb2.Remove(sb2.Length - 9, 9); + return sb2.ToString(); + } + + public void ToSqlFetch(Action fetch) + { + if (_source.Any()) + { + var sb1 = new StringBuilder(); + ToSqlExtension110(sb1, false); + fetch(sb1); + return; + } + if (_where.Length == 0) return; + var newwhere = new StringBuilder(); + ToSqlWhere(newwhere); var sb = new StringBuilder(); + if (_table.AsTableImpl != null) + { + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + foreach (var name in names) + { + _tableRule = old => name; + ToSqlExtension110(sb.Clear(), true); + fetch(sb); + } + return; + } + + ToSqlExtension110(sb, true); + fetch(sb); + } +#if net40 +#else + async public Task ToSqlFetchAsync(Func fetchAsync) + { + if (_source.Any()) + { + var sb1 = new StringBuilder(); + ToSqlExtension110(sb1, false); + await fetchAsync(sb1); + sb1.Clear(); + return; + } + if (_where.Length == 0) return; + var newwhere = new StringBuilder(); + ToSqlWhere(newwhere); + + var sb = new StringBuilder(); + if (_table.AsTableImpl != null) + { + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + foreach (var name in names) + { + _tableRule = old => name; + ToSqlExtension110(sb.Clear(), true); + await fetchAsync(sb); + } + return; + } + + ToSqlExtension110(sb, true); + await fetchAsync(sb); + sb.Clear(); + } +#endif + public virtual void ToSqlExtension110(StringBuilder sb, bool isAsTableSplited) + { + if (_where.Length == 0 && _source.Any() == false) return; + + if (_table.AsTableImpl != null && isAsTableSplited == false && _source == _sourceOld && _source.Any()) + { + var atarr = _source.Select(a => new + { + item = a, + splitKey = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(a)) + }).GroupBy(a => a.splitKey, a => a.item).ToArray(); + if (atarr.Length > 1) + { + var oldSource = _source; + var arrret = new List>(); + foreach (var item in atarr) + { + _source = item.ToList(); + ToSqlExtension110(sb, true); + sb.Append("\r\n\r\n;\r\n\r\n"); + } + _source = oldSource; + if (sb.Length > 0) sb.Remove(sb.Length - 9, 9); + return; + } + } + sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" SET "); if (_set.Length > 0) @@ -763,12 +912,12 @@ namespace FreeSql.Internal.CommonProvider ++colidx; } } - if (colidx == 0) return null; + if (colidx == 0) return; } else if (_source.Count > 1) { //批量保存 Source - if (_tempPrimarys.Any() == false) return null; + if (_tempPrimarys.Any() == false) return; var caseWhen = new StringBuilder(); caseWhen.Append("CASE "); @@ -818,10 +967,10 @@ namespace FreeSql.Internal.CommonProvider ++colidx; } } - if (colidx == 0) return null; + if (colidx == 0) return; } else if (_setIncr.Length == 0) - return null; + return; if (_setIncr.Length > 0) sb.Append(_set.Length > 0 ? _setIncr.ToString() : _setIncr.ToString().Substring(2)); @@ -844,7 +993,13 @@ namespace FreeSql.Internal.CommonProvider else sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1"); } + ToSqlWhere(sb); + _interceptSql?.Invoke(sb); + return; + } + public virtual void ToSqlWhere(StringBuilder sb) + { sb.Append(" \r\nWHERE "); if (_source.Any()) { @@ -868,9 +1023,6 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(versionCondi) == false) sb.Append(" AND ").Append(versionCondi); } - - _interceptSql?.Invoke(sb); - return sb.ToString(); } } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 9f8aa53a..8a2127fe 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -167,28 +167,33 @@ namespace FreeSql.Internal.CommonProvider async protected Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; - Exception exception = null; - try + DbParameter[] dbParms = null; + await ToSqlFetchAsync(async sb => { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(affrows, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) dbParms = _params.Concat(_paramsSource).ToArray(); + var sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var affrowstmp = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(affrowstmp, sql, dbParms); + affrows += affrowstmp; + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); return affrows; } protected abstract Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default); diff --git a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs index db63dad4..5853eff0 100644 --- a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs +++ b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs @@ -80,27 +80,7 @@ namespace FreeSql.ClickHouse.Curd _orm.Aop.CurdAfterHandler?.Invoke(this, after); } } - else - { - var sql = this.ToSql(); - before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - try - { - affrows = _orm.Ado.ExecuteNonQuery(_connection, null, CommandType.Text, sql, _commandTimeout, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return affrows; - } + return base.RawExecuteAffrows(); } private IDictionary GetValue(T u, System.Reflection.PropertyInfo[] columns) @@ -210,27 +190,7 @@ namespace FreeSql.ClickHouse.Curd _orm.Aop.CurdAfterHandler?.Invoke(this, after); } } - else - { - var sql = this.ToSql(); - before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - try - { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, null, CommandType.Text, sql, _commandTimeout, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return affrows; - } + return await base.RawExecuteAffrowsAsync(cancellationToken); } async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) diff --git a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs index 9e69b3c9..c941af96 100644 --- a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs +++ b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs @@ -65,11 +65,33 @@ namespace FreeSql.ClickHouse.Curd sb.Append(")"); } - public override string ToSql() + public override void ToSqlExtension110(StringBuilder sb, bool isAsTableSplited) { - if (_where.Length == 0 && _source.Any() == false) return null; + if (_where.Length == 0 && _source.Any() == false) return; + + if (_table.AsTableImpl != null && isAsTableSplited == false && _source == _sourceOld && _source.Any()) + { + var atarr = _source.Select(a => new + { + item = a, + splitKey = _table.AsTableImpl.GetTableNameByColumnValue(_table.AsTableColumn.GetValue(a)) + }).GroupBy(a => a.splitKey, a => a.item).ToArray(); + if (atarr.Length > 1) + { + var oldSource = _source; + var arrret = new List>(); + foreach (var item in atarr) + { + _source = item.ToList(); + ToSqlExtension110(sb, true); + sb.Append("\r\n\r\n;\r\n\r\n"); + } + _source = oldSource; + if (sb.Length > 0) sb.Remove(sb.Length - 9, 9); + return; + } + } - var sb = new StringBuilder(); sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" UPDATE "); if (_set.Length > 0) @@ -105,12 +127,12 @@ namespace FreeSql.ClickHouse.Curd ++colidx; } } - if (colidx == 0) return null; + if (colidx == 0) return; } else if (_source.Count > 1) { //批量保存 Source - if (_tempPrimarys.Any() == false) return null; + if (_tempPrimarys.Any() == false) return; var caseWhen = new StringBuilder(); ToSqlCase(caseWhen, _tempPrimarys); @@ -160,10 +182,10 @@ namespace FreeSql.ClickHouse.Curd ++colidx; } } - if (colidx == 0) return null; + if (colidx == 0) return; } else if (_setIncr.Length == 0) - return null; + return; if (_setIncr.Length > 0) sb.Append(_set.Length > 0 ? _setIncr.ToString() : _setIncr.ToString().Substring(2)); @@ -186,33 +208,9 @@ namespace FreeSql.ClickHouse.Curd else sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1"); } - - sb.Append(" \r\nWHERE "); - if (_source.Any()) - { - if (_tempPrimarys.Any() == false) throw new ArgumentException($"{_table.Type.DisplayCsharp()} 没有定义主键,无法使用 SetSource,请尝试 SetDto"); - sb.Append('(').Append(_commonUtils.WhereItems(_tempPrimarys, "", _source)).Append(')'); - } - - if (_where.Length > 0) - sb.Append(_source.Any() ? _where.ToString() : _where.ToString().Substring(5)); - - if (_whereGlobalFilter.Any()) - { - var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false); - if (string.IsNullOrEmpty(globalFilterCondi) == false) - sb.Append(" AND ").Append(globalFilterCondi); - } - - if (_table.VersionColumn != null) - { - var versionCondi = WhereCaseSource(_table.VersionColumn.CsName, sqlval => sqlval); - if (string.IsNullOrEmpty(versionCondi) == false) - sb.Append(" AND ").Append(versionCondi); - } - + ToSqlWhere(sb); _interceptSql?.Invoke(sb); - return sb.ToString(); + return; } protected override int SplitExecuteAffrows(int valuesLimit, int parameterLimit) diff --git a/Providers/FreeSql.Provider.Custom/Curd/CustomUpdate.cs b/Providers/FreeSql.Provider.Custom/Curd/CustomUpdate.cs index 338d2d29..c67d5f5c 100644 --- a/Providers/FreeSql.Provider.Custom/Curd/CustomUpdate.cs +++ b/Providers/FreeSql.Provider.Custom/Curd/CustomUpdate.cs @@ -23,7 +23,7 @@ namespace FreeSql.Custom public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); - protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.Custom 未实现该功能 未实现该功能"); + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.Custom 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -65,7 +65,7 @@ namespace FreeSql.Custom public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Custom 未实现该功能 未实现该功能"); + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Custom 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs index 96eb38b8..7bd489d4 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs @@ -21,11 +21,7 @@ namespace FreeSql.Dameng.Curd public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.Dameng 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -69,10 +65,7 @@ namespace FreeSql.Dameng.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Dameng 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs index 464bf9dd..1ea75626 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -24,40 +25,48 @@ namespace FreeSql.Firebird.Curd protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"new.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"new.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -105,40 +114,48 @@ namespace FreeSql.Firebird.Curd async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"new.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"new.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs index 20eb39b4..8d10fcc3 100644 --- a/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs @@ -22,10 +22,7 @@ namespace FreeSql.GBase.Curd public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.GBase 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -69,10 +66,7 @@ namespace FreeSql.GBase.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.GBase 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs index ac3927b4..8201153a 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -32,40 +33,48 @@ namespace FreeSql.KingbaseES protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -129,40 +138,48 @@ namespace FreeSql.KingbaseES async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index 65bfa99e..e24525e9 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -27,10 +27,7 @@ namespace FreeSql.MsAccess.Curd public override IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true) => throw new NotImplementedException("蛋疼的 access 插入只能一条一条执行,不支持 values(..),(..) 也不支持 select .. UNION ALL select .."); - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.MsAccess 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -72,10 +69,7 @@ namespace FreeSql.MsAccess.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(1, 1000, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(1, 1000, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.MsAccess 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 9611e331..e4ae587a 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -31,40 +32,48 @@ namespace FreeSql.MySql.Curd protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -112,40 +121,48 @@ namespace FreeSql.MySql.Curd async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 6454901d..f454c2bd 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -22,11 +22,7 @@ namespace FreeSql.Odbc.Dameng public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Odbc.Dameng 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -70,10 +66,7 @@ namespace FreeSql.Odbc.Dameng public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Dameng 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index 3a54ecea..14265fd5 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -32,40 +33,48 @@ namespace FreeSql.Odbc.KingbaseES protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -129,40 +138,48 @@ namespace FreeSql.Odbc.KingbaseES async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index dbfaa014..1b8f4adb 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -31,40 +32,48 @@ namespace FreeSql.Odbc.MySql protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -112,40 +121,48 @@ namespace FreeSql.Odbc.MySql async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index dfe73589..b758277b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -22,11 +22,7 @@ namespace FreeSql.Odbc.Oracle public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Odbc.Oracle 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -72,10 +68,7 @@ namespace FreeSql.Odbc.Oracle public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Oracle 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index e9f402d2..3900e6ad 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -32,40 +33,48 @@ namespace FreeSql.Odbc.PostgreSQL protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -129,40 +138,48 @@ namespace FreeSql.Odbc.PostgreSQL async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index a7baf1ca..546f118d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -24,45 +25,54 @@ namespace FreeSql.Odbc.SqlServer protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" \r\nWHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -108,45 +118,54 @@ namespace FreeSql.Odbc.SqlServer async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" \r\nWHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 0aaa87f6..f180ded1 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -22,11 +22,7 @@ namespace FreeSql.Oracle.Curd public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.Oracle 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -72,10 +68,7 @@ namespace FreeSql.Oracle.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Oracle 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 0d7ad243..03b9dcd2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -32,40 +33,48 @@ namespace FreeSql.PostgreSQL.Curd protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -129,40 +138,48 @@ namespace FreeSql.PostgreSQL.Curd async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 11bddb24..72a36649 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -4,6 +4,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -33,40 +34,48 @@ namespace FreeSql.ShenTong.Curd protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -130,40 +139,48 @@ namespace FreeSql.ShenTong.Curd async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index c63178cd..acd6331e 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading; @@ -25,45 +26,54 @@ namespace FreeSql.SqlServer.Curd protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" \r\nWHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } @@ -109,45 +119,54 @@ namespace FreeSql.SqlServer.Curd async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" \r\nWHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - Exception exception = null; - try + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(ret.Count, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 6bde5519..e88cf832 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -22,11 +22,7 @@ namespace FreeSql.Sqlite.Curd public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -70,10 +66,7 @@ namespace FreeSql.Sqlite.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); #endif } } From abaeb7efd5a64057d8bde73aaf01898c9c26fc72 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 9 Apr 2022 12:31:21 +0800 Subject: [PATCH 03/16] - fix: AsTable --- Examples/base_entity/Program.cs | 13 +- FreeSql/DataAnnotations/TableAttribute.cs | 6 +- FreeSql/FreeSql.xml | 402 ++++++++++------------ 3 files changed, 195 insertions(+), 226 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 60e38a9e..576e8378 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -99,7 +99,7 @@ namespace base_entity public B B { get; set; } } - [Table(Name = "as_table_log_{yyyyMMdd}", AsTable = "createtime=2022-1-1(1 month)")] + [Table(Name = "as_table_log_{yyyyMM}", AsTable = "createtime=2022-1-1(1 month)")] class AsTableLog { public Guid id { get; set; } @@ -157,7 +157,8 @@ namespace base_entity new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") } + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } }; var sqlatb = fsql.Insert(testitems).NoneParameter(); var sqlat = sqlatb.ToSql(); @@ -187,14 +188,18 @@ namespace base_entity var sqlatd501 = sqlatd5.ToSql(); var sqlatd502 = sqlatd5.ExecuteAffrows(); - var sqlatd6 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime > DateTime.Parse("2022-3-1")); + var sqlatd6 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime > DateTime.Parse("2022-3-1") && a.createtime < DateTime.Parse("2022-5-1")); var sqlatd601 = sqlatd6.ToSql(); var sqlatd602 = sqlatd6.ExecuteAffrows(); - var sqlatd7 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime < DateTime.Parse("2022-5-1")); + var sqlatd7 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime > DateTime.Parse("2022-3-1")); var sqlatd701 = sqlatd7.ToSql(); var sqlatd702 = sqlatd7.ExecuteAffrows(); + var sqlatd8 = fsql.Update(Guid.NewGuid()).Set(a => a.msg == "newmsg").Where(a => a.createtime < DateTime.Parse("2022-5-1")); + var sqlatd801 = sqlatd8.ToSql(); + var sqlatd802 = sqlatd8.ExecuteAffrows(); + fsql.Aop.AuditValue += new EventHandler((_, e) => { diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index a099f9e4..67e0c85b 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -105,7 +105,7 @@ namespace FreeSql.DataAnnotations void ExpandTable(DateTime beginTime, DateTime endTime) { if (beginTime > endTime) endTime = _nextTimeFunc(beginTime); - while (beginTime < endTime) + while (beginTime <= endTime) { var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value); var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr); @@ -139,10 +139,10 @@ namespace FreeSql.DataAnnotations var dt = ParseColumnValue(columnValue); if (dt < _allTablesTime.Last()) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \""); var tmpTime = _nextTimeFunc(_lastTime); - if (dt > tmpTime && autoExpand) + if (dt >= tmpTime && autoExpand) { // 自动建表 - ExpandTable(tmpTime, _nextTimeFunc(dt)); + ExpandTable(tmpTime, dt); } for (var a = 0; a < _allTables.Count; a++) if (dt >= _allTablesTime[a]) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4c8d9624..751cf507 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3254,6 +3254,177 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询 + + + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询 + + + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询 + + + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 在【主库】执行 + + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 在【主库】执行 + + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 可自定义解析表达式 @@ -4148,6 +4319,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -4223,6 +4400,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4904,222 +5087,3 @@ -ystem.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - - From 980ee1e8935f7f9405ebda52038dcaa3495c7a4e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 9 Apr 2022 15:40:17 +0800 Subject: [PATCH 04/16] =?UTF-8?q?-=20=E5=AE=8C=E6=88=90=20[Table(AsTable?= =?UTF-8?q?=20=3D=20xx)]=20=E5=88=86=E8=A1=A8=E7=89=B9=E6=80=A7=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 24 ++++++++- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ---- FreeSql/DataAnnotations/TableAttribute.cs | 19 ++++--- FreeSql/FreeSql.xml | 2 +- FreeSql/Internal/CommonExpression.cs | 1 + .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../SelectProvider/Select0Provider.cs | 49 ++++++++++++++++++- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- .../ClickHouseExpression.cs | 10 ++-- .../FirebirdExpression.cs | 10 ++-- .../KingbaseESExpression.cs | 10 ++-- .../FreeSql.Provider.MySql/MySqlExpression.cs | 10 ++-- .../KingbaseES/OdbcKingbaseESExpression.cs | 10 ++-- .../MySql/OdbcMySqlExpression.cs | 10 ++-- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 10 ++-- .../SqlServer/OdbcSqlServerExpression.cs | 10 ++-- .../PostgreSQLExpression.cs | 10 ++-- .../ShenTongExpression.cs | 10 ++-- .../SqlServerExpression.cs | 10 ++-- .../SqliteExpression.cs | 10 ++-- 20 files changed, 147 insertions(+), 85 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 576e8378..5b9294b5 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -115,8 +115,8 @@ namespace base_entity .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test1.db;max pool size=5") - .UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db") - .UseSlaveWeight(10, 1, 1, 5) + //.UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db") + //.UseSlaveWeight(10, 1, 1, 5) //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=2") @@ -200,6 +200,26 @@ namespace base_entity var sqlatd801 = sqlatd8.ToSql(); var sqlatd802 = sqlatd8.ExecuteAffrows(); + var sqls1 = fsql.Select(); + var sqls101 = sqls1.ToSql(); + var sqls102 = sqls1.ToList(); + + var sqls2 = fsql.Select().Where(a => a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); + var sqls201 = sqls2.ToSql(); + var sqls202 = sqls2.ToList(); + + var sqls3 = fsql.Select().Where(a => a.createtime > DateTime.Parse("2022-3-1") && a.createtime < DateTime.Parse("2022-5-1")); + var sqls301 = sqls3.ToSql(); + var sqls302 = sqls3.ToList(); + + var sqls4 = fsql.Select().Where(a => a.createtime > DateTime.Parse("2022-3-1")); + var sqls401 = sqls4.ToSql(); + var sqls402 = sqls4.ToList(); + + var sqls5 = fsql.Select().Where(a => a.createtime < DateTime.Parse("2022-5-1")); + var sqls501 = sqls5.ToSql(); + var sqls502 = sqls5.ToList(); + fsql.Aop.AuditValue += new EventHandler((_, e) => { diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index bdd16ff9..da7ace6b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -538,14 +538,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 67e0c85b..0f3d679d 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -76,7 +76,7 @@ namespace FreeSql.DataAnnotations ICollection AllTables { get; } string GetTableNameByColumnValue(object columnValue, bool autoExpand = false); ICollection GetTableNamesByColumnValueRange(object columnValue1, object columnValue2); - ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, TableInfo table, CommonUtils commonUtils); + ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils); } class DateTimeAsTableImpl : IAsTable { @@ -192,7 +192,7 @@ namespace FreeSql.DataAnnotations { return _dicRegSqlWhereDateTimes.GetOrAdd($"{columnName},{quoteParameterName}", cn => { - cn = columnName.Replace(@"\[", @"\\[").Replace(@"\]", @"\\]"); + cn = columnName.Replace("[", "\\[").Replace("]", "\\]").Replace(".", "\\."); return new[] { new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), @@ -239,15 +239,22 @@ namespace FreeSql.DataAnnotations /// /// /// - public ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, TableInfo table, CommonUtils commonUtils) + public ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) { + if (string.IsNullOrWhiteSpace(sqlWhere)) return _allTables; var quoteParameterName = commonUtils.QuoteParamterName(""); var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); - var regs = GetRegSqlWhereDateTimes(commonUtils.QuoteSqlName(table.AsTableColumn.Attribute.Name), quoteParameterName); + var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name); + var regs = GetRegSqlWhereDateTimes($"{(string.IsNullOrWhiteSpace(tb.Alias) ? "" : $"{tb.Alias}.")}{commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name)}", quoteParameterName); for (var a = 0; a < 16; a++) sqlWhere = regs[a].Replace(sqlWhere, "$1$4"); var m = regs[16].Match(sqlWhere); if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value); + m = m = regs[18].Match(sqlWhere); + if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); + m = regs[20].Match(sqlWhere); + if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); + m = m = regs[17].Match(sqlWhere); if (m.Success) { @@ -256,8 +263,6 @@ namespace FreeSql.DataAnnotations if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return GetTableNamesByColumnValueRange(val1, val2); } - m = m = regs[18].Match(sqlWhere); - if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); m = regs[19].Match(sqlWhere); if (m.Success) { @@ -266,8 +271,6 @@ namespace FreeSql.DataAnnotations if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(val1), ParseColumnValue(val2)); } - m = regs[20].Match(sqlWhere); - if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); m = regs[21].Match(sqlWhere); if (m.Success) { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 751cf507..3b06701e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -411,7 +411,7 @@ 所有分表名 - + 可以匹配以下条件(支持参数化): `field` BETWEEN '2022-01-01 00:00:00' AND '2022-03-01 00:00:00' diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 1e52e23c..01278f96 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1690,6 +1690,7 @@ namespace FreeSql.Internal public abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc); public abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc); public abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc); + public string ExpressionConstDateTime(Expression exp) => exp is ConstantExpression operandExpConst ? formatSql(Utils.GetDataReaderValue(typeof(DateTime), operandExpConst.Value), null, null, null) : null; public enum ExpressionStyle { diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 639fa6bc..e3f2348e 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -195,7 +195,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); if (_table.AsTableImpl != null) { - var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); foreach (var name in names) { _tableRule = old => name; @@ -228,7 +228,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); if (_table.AsTableImpl != null) { - var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); foreach (var name in names) { _tableRule = old => name; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 58326a91..16cb5b6b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -460,7 +460,54 @@ namespace FreeSql.Internal.CommonProvider protected List> GetTableRuleUnions() { var unions = new List>(); - var trs = _tableRules.Any() ? _tableRules : new List>(new[] { new Func((type, oldname) => null) }); + var trs = _tableRules.Any() ? _tableRules : new List>(); + + if (trs.Any() == false) + { + string[] LocalGetTableNames(SelectTableInfo tb) + { + if (tb.Table.AsTableImpl != null) + { + string[] aret = null; + if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables.ToArray(); + else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils).ToArray(); + if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray(); + + for (var a = 0; a < aret.Length; a++) + { + if (_orm.CodeFirst.IsSyncStructureToLower) aret[a] = aret[a].ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) aret[a] = aret[a].ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, aret[a]); + } + return aret; + } + return new string[] { tb.Table.DbName }; + } + var tbnames = _tables.GroupBy(a => a.Table.Type).Select(g => _tables.Where(a => a.Table.Type == g.Key).FirstOrDefault()).Select(a => new { Tb = a, Names = LocalGetTableNames(a) }).ToList(); + var dict = new Dictionary(); + tbnames.ForEach(a => + { + dict.Add(a.Tb.Table.Type, a.Names[0]); + }); + unions.Add(dict); + for (var a = 0; a < tbnames.Count; a++) + { + if (tbnames[a].Names.Length <= 1) continue; + var unionsCount = unions.Count; + for (var b = 1; b < tbnames[a].Names.Length; b++) + { + for (var d = 0; d < unionsCount; d++) + { + dict = new Dictionary(); + foreach (var uit in unions[d]) + dict.Add(uit.Key, uit.Key == tbnames[a].Tb.Table.Type ? tbnames[a].Names[b] : uit.Value); + unions.Add(dict); + } + } + } + return unions; + } + if (trs.Any() == false) trs.Add(new Func((type, oldname) => null)); foreach (var tr in trs) { var dict = new Dictionary(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 306036d3..71af0381 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -803,7 +803,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); if (_table.AsTableImpl != null) { - var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); foreach (var name in names) { _tableRule = old => name; @@ -835,7 +835,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); if (_table.AsTableImpl != null) { - var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils); + var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); foreach (var name in names) { _tableRule = old => name; diff --git a/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs b/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs index 4d8f1c3f..77a6dfea 100644 --- a/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs +++ b/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs @@ -34,7 +34,7 @@ namespace FreeSql.ClickHouse case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as Int8)"; case "System.Char": return $"substr(cast({getExp(operandExp)} as String), 1, 1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as DateTime)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as DateTime)"; case "System.Decimal": return $"cast({getExp(operandExp)} as Decimal128(19))"; case "System.Double": return $"cast({getExp(operandExp)} as Float64)"; case "System.Int16": return $"cast({getExp(operandExp)} as Int16)"; @@ -62,7 +62,7 @@ namespace FreeSql.ClickHouse case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as Int8)"; case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as String), 1, 1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as DateTime)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as DateTime)"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as Decimal128(19))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as Float64)"; case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as Int16)"; @@ -419,10 +419,10 @@ namespace FreeSql.ClickHouse var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as DateTime)"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as DateTime)"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as DateTime)"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as DateTime)"; } } else @@ -555,7 +555,7 @@ namespace FreeSql.ClickHouse case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as Int8)"; case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as String), 1, 1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as DateTime)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as DateTime)"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as Decimal128(19))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as Float64)"; case "ToInt16": diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs index fea3bbae..f5c55353 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs @@ -32,7 +32,7 @@ namespace FreeSql.Firebird case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as smallint)"; case "System.Char": return $"substring(cast({getExp(operandExp)} as varchar(10)) from 1 for 1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as timestamp)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as timestamp)"; case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(18,6))"; case "System.Double": return $"cast({getExp(operandExp)} as decimal(18,10))"; case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; @@ -60,7 +60,7 @@ namespace FreeSql.Firebird case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as varchar(10)) from 1 for 1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as timestamp)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as timestamp)"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,6))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,10))"; case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; @@ -389,10 +389,10 @@ namespace FreeSql.Firebird var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as timestamp)"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as timestamp)"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as timestamp)"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as timestamp)"; } } else @@ -504,7 +504,7 @@ namespace FreeSql.Firebird case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as varchar(10)) from 1 for 1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as timestamp)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as timestamp)"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(18,6))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(18,10))"; case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs index 4acc5c81..a35cc007 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs @@ -35,7 +35,7 @@ namespace FreeSql.KingbaseES case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(operandExp)})::int2"; case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp"; case "System.Decimal": return $"({getExp(operandExp)})::numeric"; case "System.Double": return $"({getExp(operandExp)})::float8"; case "System.Int16": return $"({getExp(operandExp)})::int2"; @@ -63,7 +63,7 @@ namespace FreeSql.KingbaseES case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp"; case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; @@ -468,10 +468,10 @@ namespace FreeSql.KingbaseES var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; } } else @@ -605,7 +605,7 @@ namespace FreeSql.KingbaseES case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 6e27d68d..57aee99b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -34,7 +34,7 @@ namespace FreeSql.MySql case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)"; case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)"; case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; case "System.Int16": @@ -62,7 +62,7 @@ namespace FreeSql.MySql case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; case "System.Int16": @@ -401,10 +401,10 @@ namespace FreeSql.MySql var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; } } else @@ -537,7 +537,7 @@ namespace FreeSql.MySql case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; case "ToInt16": diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 12901b30..cb33402c 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -35,7 +35,7 @@ namespace FreeSql.Odbc.KingbaseES case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(operandExp)})::int2"; case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp"; case "System.Decimal": return $"({getExp(operandExp)})::numeric"; case "System.Double": return $"({getExp(operandExp)})::float8"; case "System.Int16": return $"({getExp(operandExp)})::int2"; @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.KingbaseES case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp"; case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; @@ -468,10 +468,10 @@ namespace FreeSql.Odbc.KingbaseES var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; } } else @@ -605,7 +605,7 @@ namespace FreeSql.Odbc.KingbaseES case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index e9b5e4a9..a0734a6d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.MySql case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)"; case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)"; case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; case "System.Int16": @@ -60,7 +60,7 @@ namespace FreeSql.Odbc.MySql case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; case "System.Int16": @@ -399,10 +399,10 @@ namespace FreeSql.Odbc.MySql var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; } } else @@ -535,7 +535,7 @@ namespace FreeSql.Odbc.MySql case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; case "ToInt16": diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 4a20a567..d9dedb29 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -35,7 +35,7 @@ namespace FreeSql.Odbc.PostgreSQL case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(operandExp)})::int2"; case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp"; case "System.Decimal": return $"({getExp(operandExp)})::numeric"; case "System.Double": return $"({getExp(operandExp)})::float8"; case "System.Int16": return $"({getExp(operandExp)})::int2"; @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.PostgreSQL case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp"; case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; @@ -493,10 +493,10 @@ namespace FreeSql.Odbc.PostgreSQL var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; } } else @@ -630,7 +630,7 @@ namespace FreeSql.Odbc.PostgreSQL case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index e19d4fa5..ebafc373 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.SqlServer case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)"; case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)"; case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.SqlServer case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; @@ -400,10 +400,10 @@ namespace FreeSql.Odbc.SqlServer var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; } } else @@ -526,7 +526,7 @@ namespace FreeSql.Odbc.SqlServer case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as nvarchar),1,1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 2cd6d007..dedd5ef3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -36,7 +36,7 @@ namespace FreeSql.PostgreSQL case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(operandExp)})::int2"; case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp"; case "System.Decimal": return $"({getExp(operandExp)})::numeric"; case "System.Double": return $"({getExp(operandExp)})::float8"; case "System.Int16": return $"({getExp(operandExp)})::int2"; @@ -64,7 +64,7 @@ namespace FreeSql.PostgreSQL case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp"; case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; @@ -524,10 +524,10 @@ namespace FreeSql.PostgreSQL var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; } } else @@ -661,7 +661,7 @@ namespace FreeSql.PostgreSQL case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index d1bd1916..70d9c334 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -35,7 +35,7 @@ namespace FreeSql.ShenTong case "System.Boolean": return $"(({getExp(operandExp)})::text not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(operandExp)})::int2"; case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp"; case "System.Decimal": return $"({getExp(operandExp)})::numeric"; case "System.Double": return $"({getExp(operandExp)})::float8"; case "System.Int16": return $"({getExp(operandExp)})::int2"; @@ -63,7 +63,7 @@ namespace FreeSql.ShenTong case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::text not in ('0','false','f','no'))"; case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp"; case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; @@ -448,10 +448,10 @@ namespace FreeSql.ShenTong var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; } } else @@ -585,7 +585,7 @@ namespace FreeSql.ShenTong case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::text not in ('0','false','f','no'))"; case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 790d2edd..a0b80ab8 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -32,7 +32,7 @@ namespace FreeSql.SqlServer case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)"; case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)"; case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; @@ -62,7 +62,7 @@ namespace FreeSql.SqlServer case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; @@ -400,10 +400,10 @@ namespace FreeSql.SqlServer var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; } } else @@ -524,7 +524,7 @@ namespace FreeSql.SqlServer case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as nvarchar),1,1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 7561a490..8a101d98 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -32,7 +32,7 @@ namespace FreeSql.Sqlite case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(operandExp)} as int2)"; case "System.Char": return $"substr(cast({getExp(operandExp)} as character), 1, 1)"; - case "System.DateTime": return $"datetime({getExp(operandExp)})"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"datetime({getExp(operandExp)})"; case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; case "System.Double": return $"cast({getExp(operandExp)} as double)"; case "System.Int16": @@ -60,7 +60,7 @@ namespace FreeSql.Sqlite case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as int2)"; case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 1)"; - case "System.DateTime": return $"datetime({getExp(callExp.Arguments[0])})"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"datetime({getExp(callExp.Arguments[0])})"; case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as double)"; case "System.Int16": @@ -415,10 +415,10 @@ namespace FreeSql.Sqlite var isLeapYearArgs1 = getExp(exp.Arguments[0]); return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"datetime({getExp(exp.Arguments[0])})"; + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"datetime({getExp(exp.Arguments[0])})"; case "ParseExact": case "TryParse": - case "TryParseExact": return $"datetime({getExp(exp.Arguments[0])})"; + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"datetime({getExp(exp.Arguments[0])})"; } } else @@ -551,7 +551,7 @@ namespace FreeSql.Sqlite case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; case "ToByte": return $"cast({getExp(exp.Arguments[0])} as int2)"; case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as character), 1, 1)"; - case "ToDateTime": return $"datetime({getExp(exp.Arguments[0])})"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"datetime({getExp(exp.Arguments[0])})"; case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as double)"; case "ToInt16": From 932b8fde58ce3e5b81cac4a3b860b349a8d212e3 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 9 Apr 2022 18:26:11 +0800 Subject: [PATCH 05/16] - fix: AsTable SafeThread --- Examples/base_entity/Program.cs | 28 ++--- FreeSql/DataAnnotations/TableAttribute.cs | 114 +++++++++++------- .../SelectProvider/Select0Provider.cs | 4 +- 3 files changed, 86 insertions(+), 60 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5b9294b5..8a322d57 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -149,20 +149,20 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion - var testitems = new[] - { - new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, - new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, - new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, - new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, - new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, - new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } - }; - var sqlatb = fsql.Insert(testitems).NoneParameter(); - var sqlat = sqlatb.ToSql(); - var sqlatr = sqlatb.ExecuteAffrows(); +var testitems = new[] +{ + new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, + new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, + new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, + new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, + new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, + new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } +}; +var sqlatb = fsql.Insert(testitems).NoneParameter(); +var sqlat = sqlatb.ToSql(); +var sqlatr = sqlatb.ExecuteAffrows(); var sqlatc = fsql.Delete().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); var sqlatca = sqlatc.ToSql(); diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 0f3d679d..e6dbe57c 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -51,6 +51,11 @@ namespace FreeSql.DataAnnotations tb.AsTableColumn = tb.Columns.TryGetValue(atm.Groups[1].Value, out var trycol) ? trycol : tb.ColumnsByCs.TryGetValue(atm.Groups[1].Value, out trycol) ? trycol : throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不存在"); + if (tb.AsTableColumn.Attribute.MapType.NullableTypeOrThis() != typeof(DateTime)) + { + tb.AsTableColumn = null; + throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不是 DateTime 类型"); + } int.TryParse(atm.Groups[5].Value, out var atm5); string atm6 = atm.Groups[6].Value.ToLower(); tb.AsTableImpl = new DateTimeAsTableImpl(Name, DateTime.Parse($"{atm.Groups[2].Value}-{atm.Groups[3].Value}-{atm.Groups[4].Value}"), dt => @@ -73,13 +78,14 @@ namespace FreeSql.DataAnnotations /// /// 所有分表名 /// - ICollection AllTables { get; } + string[] AllTables { get; } string GetTableNameByColumnValue(object columnValue, bool autoExpand = false); - ICollection GetTableNamesByColumnValueRange(object columnValue1, object columnValue2); - ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils); + string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2); + string[] GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils); } class DateTimeAsTableImpl : IAsTable { + readonly object _lock = new object(); readonly List _allTables = new List(); readonly List _allTablesTime = new List(); readonly DateTime _beginTime; @@ -105,15 +111,18 @@ namespace FreeSql.DataAnnotations void ExpandTable(DateTime beginTime, DateTime endTime) { if (beginTime > endTime) endTime = _nextTimeFunc(beginTime); - while (beginTime <= endTime) + lock (_lock) { - var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value); - var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr); - if (_allTables.Contains(name)) throw new ArgumentException($"tableName:{_tableName} 生成了相同的分表名"); - _allTables.Insert(0, name); - _allTablesTime.Insert(0, beginTime); - _lastTime = beginTime; - beginTime = _nextTimeFunc(beginTime); + while (beginTime <= endTime) + { + var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value); + var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr); + if (_allTables.Contains(name)) throw new ArgumentException($"tableName:{_tableName} 生成了相同的分表名"); + _allTables.Insert(0, name); + _allTablesTime.Insert(0, beginTime); + _lastTime = beginTime; + beginTime = _nextTimeFunc(beginTime); + } } } DateTime ParseColumnValue(object columnValue) @@ -137,54 +146,62 @@ namespace FreeSql.DataAnnotations public string GetTableNameByColumnValue(object columnValue, bool autoExpand = false) { var dt = ParseColumnValue(columnValue); - if (dt < _allTablesTime.Last()) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \""); + if (dt < _beginTime) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \""); var tmpTime = _nextTimeFunc(_lastTime); if (dt >= tmpTime && autoExpand) { // 自动建表 ExpandTable(tmpTime, dt); } - for (var a = 0; a < _allTables.Count; a++) - if (dt >= _allTablesTime[a]) - return _allTables[a]; + lock (_lock) + { + var allTablesCount = _allTablesTime.Count; + for (var a = 0; a < allTablesCount; a++) + if (dt >= _allTablesTime[a]) + return _allTables[a]; + } throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 未匹配到分表名"); } - public ICollection GetTableNamesByColumnValueRange(object columnValue1, object columnValue2) + public string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2) { var dt1 = ParseColumnValue(columnValue1); var dt2 = ParseColumnValue(columnValue2); if (dt1 > dt2) return new string[0]; - int dt1idx = 0, dt2idx = 0; - if (dt1 < _allTablesTime.Last()) dt1idx = _allTablesTime.Count - 1; - else + lock (_lock) { - for (var a = _allTablesTime.Count - 2; a > -1; a--) + int dt1idx = 0, dt2idx = 0; + var allTablesCount = _allTablesTime.Count; + if (dt1 < _beginTime) dt1idx = allTablesCount - 1; + else { - if (dt1 < _allTablesTime[a]) + for (var a = allTablesCount - 2; a > -1; a--) { - dt1idx = a + 1; - break; + if (dt1 < _allTablesTime[a]) + { + dt1idx = a + 1; + break; + } } } - } - if (dt2 > _allTablesTime.First()) dt2idx = 0; - else - { - for (var a = 0; a < _allTablesTime.Count; a++) + if (dt2 > _allTablesTime.First()) dt2idx = 0; + else { - if (dt2 >= _allTablesTime[a]) + for (var a = 0; a < allTablesCount; a++) { - dt2idx = a; - break; + if (dt2 >= _allTablesTime[a]) + { + dt2idx = a; + break; + } } } - } - if (dt2idx == -1) return new string[0]; + if (dt2idx == -1) return new string[0]; - if (dt1idx == _allTables.Count - 1 && dt2idx == 0) return _allTables; - var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1); - return names; + if (dt1idx == allTablesCount - 1 && dt2idx == 0) return _allTables.ToArray(); + var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1).ToArray(); + return names; + } } static readonly ConcurrentDictionary _dicRegSqlWhereDateTimes = new ConcurrentDictionary(); @@ -239,9 +256,9 @@ namespace FreeSql.DataAnnotations /// /// /// - public ICollection GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) + public string[] GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) { - if (string.IsNullOrWhiteSpace(sqlWhere)) return _allTables; + if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables; var quoteParameterName = commonUtils.QuoteParamterName(""); var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name); @@ -278,9 +295,9 @@ namespace FreeSql.DataAnnotations if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1)); } - return _allTables; + return AllTables; - ICollection LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2) + string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2) { switch (opt1) { @@ -319,9 +336,9 @@ namespace FreeSql.DataAnnotations } break; } - return _allTables; + return AllTables; } - ICollection LocalGetTables2(string opt, DateTime val1) + string[] LocalGetTables2(string opt, DateTime val1) { switch (m.Groups[1].Value) { @@ -336,10 +353,19 @@ namespace FreeSql.DataAnnotations case ">=": return GetTableNamesByColumnValueRange(val1, _lastTime); } - return _allTables; + return AllTables; } } - public ICollection AllTables => _allTables; + public string[] AllTables + { + get + { + lock (_lock) + { + return _allTables.ToArray(); + } + } + } } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 16cb5b6b..60e7e4c9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -469,8 +469,8 @@ namespace FreeSql.Internal.CommonProvider if (tb.Table.AsTableImpl != null) { string[] aret = null; - if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables.ToArray(); - else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils).ToArray(); + if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables; + else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils); if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray(); for (var a = 0; a < aret.Length; a++) From b9a21f6c112fb3df20cbf1c25301126bf999931e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 9 Apr 2022 20:54:48 +0800 Subject: [PATCH 06/16] - fix: AsTable for Select --- FreeSql/DataAnnotations/TableAttribute.cs | 3 --- .../SelectProvider/Select0Provider.cs | 19 ++++++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index e6dbe57c..2c27feca 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -75,9 +75,6 @@ namespace FreeSql.DataAnnotations public interface IAsTable { - /// - /// 所有分表名 - /// string[] AllTables { get; } string GetTableNameByColumnValue(object columnValue, bool autoExpand = false); string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 60e7e4c9..d3d13dea 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -460,13 +460,14 @@ namespace FreeSql.Internal.CommonProvider protected List> GetTableRuleUnions() { var unions = new List>(); - var trs = _tableRules.Any() ? _tableRules : new List>(); + var trs = _tableRules.Any() ? _tableRules : new List>(new [] { new Func((type, oldname) => null) }); - if (trs.Any() == false) + if (trs.Count == 1 && _tables.Any(a => a.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trs[0](a.Table.Type, a.Table.DbName)) == true)) { string[] LocalGetTableNames(SelectTableInfo tb) { - if (tb.Table.AsTableImpl != null) + var trname = trs[0](tb.Table.Type, tb.Table.DbName); + if (tb.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trname) == true) { string[] aret = null; if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables; @@ -481,6 +482,18 @@ namespace FreeSql.Internal.CommonProvider } return aret; } + if (string.IsNullOrWhiteSpace(trname) == false) + { + if (trname.IndexOf(' ') == -1) //还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() + { + if (_orm.CodeFirst.IsSyncStructureToLower) trname = trname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) trname = trname.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, trname); + } + else + trname = trname.Replace(" \r\n", " \r\n "); + return new string[] { trname }; + } return new string[] { tb.Table.DbName }; } var tbnames = _tables.GroupBy(a => a.Table.Type).Select(g => _tables.Where(a => a.Table.Type == g.Key).FirstOrDefault()).Select(a => new { Tb = a, Names = LocalGetTableNames(a) }).ToList(); From ecd27fb3ae08c4f872dc8633242f4cb5aaf7e23e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 9 Apr 2022 22:40:52 +0800 Subject: [PATCH 07/16] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20InsertDict=20?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=96=B0=E5=8A=9F=E8=83=BD=E9=81=97=E7=95=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98(=E7=89=B9=E5=88=AB=E6=98=AF=20Oracle)?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GBase/Curd/GBaseSelectTest.cs | 6 +++--- .../ConvertTest.cs | 0 .../DateTimeTest.cs | 0 .../MathTest.cs | 0 .../OtherTest.cs | 0 .../StringTest.cs | 0 .../TimeSpanTest.cs | 0 FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs | 2 ++ FreeSql.Tests/FreeSql.Tests/Issues/804.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest5.cs | 2 +- FreeSql/FreeSql.xml | 5 ----- FreeSql/Internal/CommonProvider/InsertProvider.cs | 2 +- .../FreeSql.Provider.ClickHouse/ClickHouseUtils.cs | 4 +++- Providers/FreeSql.Provider.Dameng/DamengUtils.cs | 4 +++- Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs | 2 +- Providers/FreeSql.Provider.GBase/GBaseUtils.cs | 2 +- Providers/FreeSql.Provider.MySql/MySqlUtils.cs | 5 ++++- .../MySqlConnectorUtils.cs | 3 ++- .../FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs | 8 ++++++-- Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs | 6 ++++-- .../FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs | 12 ++++++------ .../FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs | 8 ++++++-- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 8 ++++---- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 12 ++++++------ Providers/FreeSql.Provider.Oracle/OracleUtils.cs | 6 ++++-- .../Curd/SqlServerDelete.cs | 8 ++++---- .../Curd/SqlServerUpdate.cs | 12 ++++++------ Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs | 2 +- 28 files changed, 69 insertions(+), 52 deletions(-) rename FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/{FirebirdExpression => GBaseExpression}/ConvertTest.cs (100%) rename FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/{FirebirdExpression => GBaseExpression}/DateTimeTest.cs (100%) rename FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/{FirebirdExpression => GBaseExpression}/MathTest.cs (100%) rename FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/{FirebirdExpression => GBaseExpression}/OtherTest.cs (100%) rename FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/{FirebirdExpression => GBaseExpression}/StringTest.cs (100%) rename FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/{FirebirdExpression => GBaseExpression}/TimeSpanTest.cs (100%) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs index 5fa9883a..b68f9582 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs @@ -95,7 +95,7 @@ WHERE (a__Parent__Parent.Name = '粤语')", t0); var t1 = g.gbase.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); Assert.Equal(@"SELECT a.Id, a.Parent_id, a.Ddd, a.Name FROM Tag a -WHERE (exists(SELECT FIRST 1 1 +WHERE (exists(SELECT 1 FROM Tag t LEFT JOIN Tag t__Parent ON t__Parent.Id = t.Parent_id WHERE (t__Parent.Id = 10) AND (t.Parent_id = a.Id)))", t1); @@ -104,9 +104,9 @@ WHERE (exists(SELECT FIRST 1 1 var t2 = g.gbase.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); Assert.Equal(@"SELECT a.Id, a.Create_time, a.Is_deleted, a.Title, a.Url FROM Song a -WHERE (exists(SELECT FIRST 1 1 +WHERE (exists(SELECT 1 FROM Song_tag Mt_Ms - WHERE (Mt_Ms.Song_id = a.Id) AND (exists(SELECT FIRST 1 1 + WHERE (Mt_Ms.Song_id = a.Id) AND (exists(SELECT 1 FROM Tag t WHERE (t.Name = '国语') AND (t.Id = Mt_Ms.Tag_id)))))", t2); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/ConvertTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/DateTimeTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/MathTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/OtherTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/StringTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs index 8fcee4a4..6328e8f3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs @@ -35,4 +35,6 @@ public class g }); public static IFreeSql gbase => gbaseLazy.Value; + //su - gbasedbt + //oninit -vy } diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/804.cs b/FreeSql.Tests/FreeSql.Tests/Issues/804.cs index 3bab23f5..cf387d81 100644 --- a/FreeSql.Tests/FreeSql.Tests/Issues/804.cs +++ b/FreeSql.Tests/FreeSql.Tests/Issues/804.cs @@ -106,7 +106,7 @@ WHERE (strftime('%Y',a."CreateTime") = 2021) var d1 = fsql.Select().Where(r => r.CreateTime.Month == month).ToList(); var d2 = fsql.Select().Where(r => r.CreateTime.Year == year).ToList(); - var d5 = fsql.Select().Where(r => r.CreateTime.Year == 2021).ToList(); + var d5 = fsql.Select().Where(r => r.CreateTime.Year == 2022).ToList(); Assert.Single(dmonth1); Assert.Single(d1); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest5.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest5.cs index a1db0c8d..19335b53 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest5.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest5.cs @@ -33,7 +33,7 @@ namespace FreeSql.Tests { is_lock = test.ratio < 1 //这里生成的SQL语句有问题 ratio = 0.9 或 1.9 或 2.1 等等都是生成的是1 }).Where(m => test.ratio < 1).ToSql(); - Assert.Equal(@"UPDATE TestDto SET is_lock = 2.1 < 1 + Assert.Equal(@"UPDATE `TestDto` SET `is_lock` = 2.1 < 1 WHERE (2.1 < 1)", sql); } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3b06701e..be8688b0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -406,11 +406,6 @@ 按时分表:[Table(Name = "log_{yyyyMMddHH}", AsTable = "create_time=2022-5-1(6 hour)")] - - - 所有分表名 - - 可以匹配以下条件(支持参数化): diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index de45338f..e12b00d6 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -584,7 +584,7 @@ namespace FreeSql.Internal.CommonProvider public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension103(isValues, null, null, false); public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) => ToSqlValuesOrSelectUnionAllExtension103(isValues, null, onrow, false); - public string ToSqlValuesOrSelectUnionAllExtension102(bool isValues, Action onrowPre, Action onrow) => ToSqlValuesOrSelectUnionAllExtension103(isValues, null, onrow, false); + public string ToSqlValuesOrSelectUnionAllExtension102(bool isValues, Action onrowPre, Action onrow) => ToSqlValuesOrSelectUnionAllExtension103(isValues, onrowPre, onrow, false); string ToSqlValuesOrSelectUnionAllExtension103(bool isValues, Action onrowPre, Action onrow, bool isAsTableSplited) { if (_source == null || _source.Any() == false) return null; diff --git a/Providers/FreeSql.Provider.ClickHouse/ClickHouseUtils.cs b/Providers/FreeSql.Provider.ClickHouse/ClickHouseUtils.cs index 6d81e48b..ecd48033 100644 --- a/Providers/FreeSql.Provider.ClickHouse/ClickHouseUtils.cs +++ b/Providers/FreeSql.Provider.ClickHouse/ClickHouseUtils.cs @@ -21,7 +21,9 @@ namespace FreeSql.ClickHouse { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; var dbtype = (DbType?)_orm.CodeFirst.GetDbInfo(type)?.type; - DbParameter ret = new ClickHouseDbParameter { ParameterName = parameterName, DbType = dbtype ?? default, Value = value };//QuoteParamterName(parameterName) + DbParameter ret = new ClickHouseDbParameter { ParameterName = parameterName };//QuoteParamterName(parameterName) + if (dbtype != null) ret.DbType = dbtype.Value; + ret.Value = value; if (col != null) { var dbtype2 = (DbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs index 5dc1bd37..cfee3da5 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -40,7 +40,9 @@ namespace FreeSql.Dameng } break; } - var ret = new DmParameter { ParameterName = QuoteParamterName(parameterName), DmSqlType = dbtype ?? default, Value = value }; + var ret = new DmParameter { ParameterName = QuoteParamterName(parameterName) }; + if (dbtype != null) ret.DmSqlType = dbtype.Value; + ret.Value = value; _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs b/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs index bb65b3e0..2655e2f0 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs @@ -35,7 +35,7 @@ namespace FreeSql.Firebird break; } } - ret.FbDbType = dbtype ?? default; + if (dbtype != null) ret.FbDbType = dbtype.Value; _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.GBase/GBaseUtils.cs b/Providers/FreeSql.Provider.GBase/GBaseUtils.cs index 79f1e9d7..b2c243ca 100644 --- a/Providers/FreeSql.Provider.GBase/GBaseUtils.cs +++ b/Providers/FreeSql.Provider.GBase/GBaseUtils.cs @@ -35,7 +35,7 @@ namespace FreeSql.GBase break; } } - ret.OdbcType = dbtype ?? default; + if (dbtype != null) ret.OdbcType = dbtype.Value; _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index ed0b68e9..7ca8d271 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -46,7 +46,10 @@ namespace FreeSql.MySql if (value != null) ret.Value = (value as MygisGeometry).AsText(); } else - ret.MySqlDbType = dbtype ?? default; + { + if (dbtype != null) + ret.MySqlDbType = dbtype.Value; + } _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index a242f2d7..7a7b8084 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -44,7 +44,8 @@ namespace FreeSql.MySql } else { - ret.MySqlDbType = dbtype ?? default; + if (dbtype != null) + ret.MySqlDbType = dbtype.Value; if (ret.MySqlDbType == MySqlDbType.Enum && value != null) ret.Value = EnumValueToMySql(value); } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index a1c95f01..9ce96dbb 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -36,7 +36,9 @@ namespace FreeSql.Odbc.Dameng value = string.Concat(value); break; } - var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), OdbcType = dbtype ?? default, Value = value }; + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName) }; + if (dbtype != null) ret.OdbcType = dbtype.Value; + ret.Value = value; _params?.Add(ret); return ret; } @@ -62,7 +64,9 @@ namespace FreeSql.Odbc.Dameng value = string.Concat(value); break; } - var ret = new OdbcParameter { ParameterName = $":{name}", OdbcType = dbtype ?? default, Value = value }; + var ret = new OdbcParameter { ParameterName = $":{name}" }; + if (dbtype != null) ret.OdbcType = dbtype.Value; + ret.Value = value; return ret; }); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index e7c00f5f..d2104316 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -18,9 +18,10 @@ namespace FreeSql.Odbc.Default { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); - var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName) }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + ret.Value = value; _params?.Add(ret); return ret; } @@ -29,9 +30,10 @@ namespace FreeSql.Odbc.Default Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => { if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); - var ret = new OdbcParameter { ParameterName = $"@{name}", Value = value }; + var ret = new OdbcParameter { ParameterName = $"@{name}" }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + ret.Value = value; return ret; }); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 95d80ad4..0ec715b9 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -18,10 +18,10 @@ namespace FreeSql.Odbc.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName) }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) - ret.OdbcType = (OdbcType)tp.Value; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + ret.Value = value; _params?.Add(ret); return ret; } @@ -29,10 +29,10 @@ namespace FreeSql.Odbc.MySql public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => { - var ret = new OdbcParameter { ParameterName = $"?{name}", Value = value }; + var ret = new OdbcParameter { ParameterName = $"?{name}" }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) - ret.OdbcType = (OdbcType)tp.Value; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + ret.Value = value; return ret; }); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index 7ee2273d..d8859e15 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -36,7 +36,9 @@ namespace FreeSql.Odbc.Oracle value = string.Concat(value); break; } - var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), OdbcType = dbtype ?? default, Value = value }; + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName) }; + if (dbtype != null) ret.OdbcType = dbtype.Value; + ret.Value = value; _params?.Add(ret); return ret; } @@ -62,7 +64,9 @@ namespace FreeSql.Odbc.Oracle value = string.Concat(value); break; } - var ret = new OdbcParameter { ParameterName = $":{name}", OdbcType = dbtype ?? default, Value = value }; + var ret = new OdbcParameter { ParameterName = $":{name}" }; + if (dbtype != null) ret.OdbcType = dbtype.Value; + ret.Value = value; return ret; }); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index ab0bc595..e0f184e5 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -41,9 +41,9 @@ namespace FreeSql.Odbc.SqlServer var sql = sb.ToString(); var validx = sql.IndexOf(" WHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -98,9 +98,9 @@ namespace FreeSql.Odbc.SqlServer var sql = sb.ToString(); var validx = sql.IndexOf(" WHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 546f118d..d1a74591 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -45,11 +45,11 @@ namespace FreeSql.Odbc.SqlServer } } var sql = sb.ToString(); - var validx = sql.IndexOf(" WHERE "); + var validx = sql.IndexOf(" \r\nWHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -138,11 +138,11 @@ namespace FreeSql.Odbc.SqlServer } } var sql = sb.ToString(); - var validx = sql.IndexOf(" WHERE "); + var validx = sql.IndexOf(" \r\nWHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 728a6740..3e286782 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -25,8 +25,9 @@ namespace FreeSql.Oracle else value = (bool)value == true ? 1 : 0; dbtype = OracleDbType.Int16; } - var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName) }; if (dbtype != null) ret.OracleDbType = dbtype.Value; + ret.Value = value; if (col != null) { var dbtype2 = (OracleDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeTextFull = col.Attribute.DbType?.Replace("NOT NULL", "").Replace(" NULL", "").Trim(), DbTypeText = col.DbTypeText }); @@ -63,8 +64,9 @@ namespace FreeSql.Oracle else value = (bool)value == true ? 1 : 0; dbtype = OracleDbType.Int16; } - var ret = new OracleParameter { ParameterName = $":{name}", Value = value }; + var ret = new OracleParameter { ParameterName = $":{name}" }; if (dbtype != null) ret.OracleDbType = dbtype.Value; + ret.Value = value; return ret; }); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index ff20a9a3..05ae3498 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -41,9 +41,9 @@ namespace FreeSql.SqlServer.Curd var sql = sb.ToString(); var validx = sql.IndexOf(" WHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -98,9 +98,9 @@ namespace FreeSql.SqlServer.Curd var sql = sb.ToString(); var validx = sql.IndexOf(" WHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index acd6331e..4d6fb211 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -46,11 +46,11 @@ namespace FreeSql.SqlServer.Curd } } var sql = sb.ToString(); - var validx = sql.IndexOf(" WHERE "); + var validx = sql.IndexOf(" \r\nWHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -139,11 +139,11 @@ namespace FreeSql.SqlServer.Curd } } var sql = sb.ToString(); - var validx = sql.IndexOf(" WHERE "); + var validx = sql.IndexOf(" \r\nWHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Clear().Append(sql.Substring(0, validx)) + sql = sb.Clear().Append(sql.Substring(0, validx)) .Append(sbret) - .Append(sql.Substring(validx)); + .Append(sql.Substring(validx)).ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 3cd4c2d9..4e036627 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -43,7 +43,7 @@ namespace FreeSql.Sqlite var ret = new SQLiteParameter(); #endif ret.ParameterName = QuoteParamterName(parameterName); - ret.DbType = dbtype ?? default; + if (dbtype != null) ret.DbType = dbtype.Value; ret.Value = value; _params?.Add(ret); return ret; From 7c2b7ea5efcc774c276dbc8d201425927a7ab789 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 11 Apr 2022 13:23:38 +0800 Subject: [PATCH 08/16] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20InsertOrUpdateDi?= =?UTF-8?q?ct=20=E5=BC=82=E5=B8=B8=EF=BC=9B#1067?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 28 ++-- .../FreeSql.Tests/Internal/UtilsTest.cs | 107 ++++++++++++ FreeSql/DataAnnotations/TableAttribute.cs | 63 ++++--- .../Internal/CommonProvider/InsertProvider.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 157 ++++++++++++++++++ .../Curd/DamengInsertOrUpdate.cs | 1 + .../Curd/FirebirdInsertOrUpdate.cs | 1 + .../Curd/GBaseInsertOrUpdate.cs | 1 + .../Curd/KingbaseESInsertOrUpdate.cs | 1 + .../Curd/MySqlInsertOrUpdate.cs | 1 + .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 1 + .../Curd/OdbcKingbaseESInsertOrUpdate.cs | 1 + .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 1 + .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 1 + .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 1 + .../Curd/OdbcSqlServerInsertOrUpdate.cs | 1 + .../Curd/OracleInsertOrUpdate.cs | 1 + .../Curd/PostgreSQLInsertOrUpdate.cs | 1 + .../Curd/ShenTongInsertOrUpdate.cs | 1 + .../Curd/SqlServerInsertOrUpdate.cs | 1 + .../Curd/SqliteInsertOrUpdate.cs | 1 + 21 files changed, 331 insertions(+), 41 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 8a322d57..5b9294b5 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -149,20 +149,20 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion -var testitems = new[] -{ - new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, - new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, - new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, - new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, - new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, - new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } -}; -var sqlatb = fsql.Insert(testitems).NoneParameter(); -var sqlat = sqlatb.ToSql(); -var sqlatr = sqlatb.ExecuteAffrows(); + var testitems = new[] + { + new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, + new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, + new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, + new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, + new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, + new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } + }; + var sqlatb = fsql.Insert(testitems).NoneParameter(); + var sqlat = sqlatb.ToSql(); + var sqlatr = sqlatb.ExecuteAffrows(); var sqlatc = fsql.Delete().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); var sqlatca = sqlatc.ToSql(); diff --git a/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs b/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs index 250bae5c..f71d7ad5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs @@ -46,5 +46,112 @@ namespace FreeSql.Tests.Internal Assert.Equal("p", ps2[0].ParameterName); Assert.Equal(typeof(SqlParameter), ps2[0].GetType()); } + + [Fact] + public void TestReplaceSqlConstString() + { + var dict = new Dictionary(); + string sql1 = "", sql2 = "", sql3 = ""; + + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202201"" SET ""msg"" = 'msg01', ""createtime"" = '2022-01-01 13:00:11' +WHERE (""id"" = '6252a2e6-5df3-bb10-00c1-bda60c4053fe')", dict); + Assert.Equal(3, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"INSERT INTO ""as_table_log_202201""(""id"", ""msg"", ""createtime"") VALUES('6252a2e6-5df3-bb10-00c1-bda60c4053fe', 'msg01', '2022-01-01 13:00:11'), ('6252a2e6-5df3-bb10-00c1-bda773467785', 'msg02', '2022-01-02 14:00:12')", dict); + Assert.Equal(6, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"DELETE FROM ""as_table_log_202205"" WHERE (""id"" = @exp_0 AND ""createtime"" between '2022-03-01 00:00:00' and '2022-05-01 00:00:00')", dict); + Assert.Equal(2, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202202"" SET ""msg"" = CASE ""id"" +WHEN '6252a2e6-5df3-bb10-00c1-bda818f4b93f' THEN 'msg03' +WHEN '6252a2e6-5df3-bb10-00c1-bda95dbadefd' THEN 'msg04' END, ""createtime"" = CASE ""id"" +WHEN '6252a2e6-5df3-bb10-00c1-bda818f4b93f' THEN '2022-02-02 15:00:13' +WHEN '6252a2e6-5df3-bb10-00c1-bda95dbadefd' THEN '2022-02-08 15:00:13' END +WHERE (""id"" IN ('6252a2e6-5df3-bb10-00c1-bda818f4b93f','6252a2e6-5df3-bb10-00c1-bda95dbadefd'))", dict); + Assert.Equal(6, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202207"" SET ""msg"" = 'msg07', ""createtime"" = '2022-07-01 00:00:00' +WHERE (""id"" = '6252a2e6-5df3-bb10-00c1-bdad01a608fb')", dict); + Assert.Equal(3, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202207"" SET ""msg"" = 'newmsg' +WHERE (""id"" = 'acc5df07-11a5-45b5-8af1-7b1ffac19f68')", dict); + Assert.Equal(2, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202203"" SET ""msg"" = 'newmsg' +WHERE (""id"" = '29bf2df7-3dfc-4005-a2e3-0421e50b2910') AND (""createtime"" between '2022-03-01 00:00:00' and '2022-05-01 00:00:00')", dict); + Assert.Equal(4, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202203"" SET ""msg"" = 'newmsg' +WHERE (""id"" = '4c9b5b32-49b2-44ee-beee-1e399e86b933') AND (""createtime"" > '2022-03-01 00:00:00' AND ""createtime"" < '2022-05-01 00:00:00')", dict); + Assert.Equal(4, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202201"" SET ""msg"" = 'newmsg' +WHERE (""id"" = '15d2a84f-bd72-4d73-8ad1-466ba8beea60') AND (""createtime"" < '2022-05-01 00:00:00')", dict); + Assert.Equal(3, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202204"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb + +UNION ALL + +SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202203"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb + +UNION ALL + +SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202202"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb + +UNION ALL + +SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202201"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb", dict); + Assert.Equal(1, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + } } } diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 2c27feca..3680ec84 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -209,14 +209,14 @@ namespace FreeSql.DataAnnotations cn = columnName.Replace("[", "\\[").Replace("]", "\\]").Replace(".", "\\."); return new[] { - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), new Regex($@"({cn}\s*(<|<=|>|>=|=)\s*)(datetime|cdate|to_date)\(({quoteParameterName}[\w_]+)\)", RegexOptions.IgnoreCase), new Regex($@"({cn}\s*(<|<=|>|>=|=)(\s*))to_timestamp\(({quoteParameterName}[\w_]+)\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), @@ -228,13 +228,13 @@ namespace FreeSql.DataAnnotations new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and(\s+))({quoteParameterName}[^w_]+)::(datetime|timestamp)", RegexOptions.IgnoreCase), - new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用 new Regex($@"{cn}\s*between\s*{quoteParameterName}([\w_]+)\s*and\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), - new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用 new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)\s*and\s*{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), - new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用 new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), }; }); @@ -256,44 +256,53 @@ namespace FreeSql.DataAnnotations public string[] GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) { if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables; + var dictParams = new Dictionary(); + var newSqlWhere = Utils.ReplaceSqlConstString(sqlWhere, dictParams); + var tsqlWhere = Utils.ParseSqlWhereLevel1(sqlWhere); + var quoteParameterName = commonUtils.QuoteParamterName(""); var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name); var regs = GetRegSqlWhereDateTimes($"{(string.IsNullOrWhiteSpace(tb.Alias) ? "" : $"{tb.Alias}.")}{commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name)}", quoteParameterName); - for (var a = 0; a < 16; a++) sqlWhere = regs[a].Replace(sqlWhere, "$1$4"); + for (var a = 0; a < 8; a++) newSqlWhere = regs[a].Replace(newSqlWhere, "$1$4"); - var m = regs[16].Match(sqlWhere); - if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value); - m = m = regs[18].Match(sqlWhere); - if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); - m = regs[20].Match(sqlWhere); - if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); + //var m = regs[8].Match(newSqlWhere); + //if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value); + //m = m = regs[10].Match(newSqlWhere); + //if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); + //m = regs[12].Match(newSqlWhere); + //if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); - m = m = regs[17].Match(sqlWhere); + var m = regs[9].Match(newSqlWhere); if (m.Success) { - var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); - var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault(); + var val1 = LocalGetParamValue(m.Groups[1].Value); + var val2 = LocalGetParamValue(m.Groups[2].Value); if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return GetTableNamesByColumnValueRange(val1, val2); } - m = regs[19].Match(sqlWhere); + m = regs[11].Match(newSqlWhere); if (m.Success) { - var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); - var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault(); + var val1 = LocalGetParamValue(m.Groups[2].Value); + var val2 = LocalGetParamValue(m.Groups[4].Value); if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(val1), ParseColumnValue(val2)); } - m = regs[21].Match(sqlWhere); + m = regs[13].Match(newSqlWhere); if (m.Success) { - var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); + var val1 = LocalGetParamValue(m.Groups[2].Value); if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1)); } return AllTables; + object LocalGetParamValue(string paramName) + { + if (dictParams.TryGetValue(quoteParameterName + paramName, out var trydictVal)) return trydictVal; + return dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault()?.Value; + } string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2) { switch (opt1) @@ -317,7 +326,7 @@ namespace FreeSql.DataAnnotations break; case ">": case ">=": - if (opt1 == ">") val1 = val1.AddSeconds(1); + if (opt1 == ">") val1 = val1.AddSeconds(1); switch (opt2) { case "<": diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index e12b00d6..6cff4587 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -572,6 +572,7 @@ namespace FreeSql.Internal.CommonProvider public IInsert AsType(Type entityType) { if (entityType == typeof(object)) throw new Exception("IInsert.AsType 参数不支持指定为 object"); + if (entityType == typeof(T1)) return this; if (entityType == _table.Type) return this; var newtb = _commonUtils.GetTableByEntity(entityType); _table = newtb ?? throw new Exception("IInsert.AsType 参数错误,请传入正确的实体类型"); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c8b513b2..13cf5235 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -2267,5 +2267,162 @@ namespace FreeSql.Internal name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_"); return char.IsLetter(name, 0) ? name : string.Concat("_", name); } + + public static string ReplaceSqlConstString(string sql, Dictionary parms) + { + var nsb = new StringBuilder(); + var sidx = 0; + var pidx = 0; + while (sidx < sql.Length) + { + var chr = sql[sidx++]; + if (chr != '\'') + { + nsb.Append(chr); + continue; + } + var startIdx = sidx; + var startLength = 0; + while (sidx < sql.Length) + { + var chrb = sql[sidx++]; + if (chrb != '\'') + { + startLength++; + continue; + } + if (sidx < sql.Length && sql[sidx] == '\'') + { + startLength += 2; + continue; + } + break; + } + if (startLength > 0) + { + var pvalue = sql.Substring(startIdx, startLength).Replace("''", "'"); + var pname = parms.Where(a => a.Value == pvalue).Select(a => a.Key).FirstOrDefault(); + if (string.IsNullOrEmpty(pname)) + { + while (true) + { + pidx++; + pname = $"@p{pidx}"; + if (parms.ContainsKey(pname) == false) break; + } + } + nsb.Append(pname); + if (parms.ContainsKey(pname) == false) parms.Add(pname, pvalue); + } + } + return nsb.ToString(); + } + + internal static string ParseSqlWhereLevel1(string sql) + { + var dictParms = new Dictionary(); + var rawsql = ReplaceSqlConstString(sql, dictParms).Trim(); + sql = Regex.Replace(rawsql, @"[\r\n\t]", " "); + var remidx = sql.IndexOf("WHERE "); + if (remidx != -1) sql = sql.Substring(remidx + 6); + + var sidx = 0; + var ltcou = 0; + var ltidxStack = new Stack(); + while (sidx < sql.Length) + { + var chr = sql[sidx++]; + if (chr == '(') + { + ltcou++; + ltidxStack.Push(sidx - 1); + } + if (chr == ')') + { + ltcou--; + var ltidx = ltidxStack.Pop(); + if (ltidx == 0 && sidx == sql.Length - 1) + break; + var sqlLeft = ltidx == 0 ? "" : sql.Remove(ltidx); + var sqlMid = sql.Substring(ltidx, sidx - ltidx); + var sqlMidNew = ""; + var sqlRight = sidx == sql.Length - 1 ? "" : sql.Substring(sidx + 1); + var mLeft = Regex.Match(sqlLeft, @" (and|or|not)\s*$", RegexOptions.IgnoreCase); + if (mLeft.Success) + { + switch (mLeft.Groups[1].Value) + { + case "and": + sqlMidNew = sqlMid.Substring(1, sqlMid.Length - 2); + break; + case "or": + break; + case "not": + break; + } + } + sidx -= sqlMid.Length - sqlMidNew.Length; + sql = $"{sqlLeft}{sqlMidNew}{sqlRight}"; + } + } + return sql; + } + + static string ParseSqlWhereLevel12(string sql) + { + var dictParms = new Dictionary(); + var rawsql = ReplaceSqlConstString(sql, dictParms); + sql = Regex.Replace(rawsql, @"[\r\n\t]", " "); + var remidx = sql.IndexOf("WHERE "); + if (remidx != -1) sql = sql.Substring(remidx + 6); + + Dictionary dicSqlParts = new Dictionary(); + var nsb = new StringBuilder(); + var swliRoot = new SqlWhereLogicInfo(); + var swliCurrent = swliRoot; + + LocalParseSqlWhere(sql); + return nsb.ToString(); + + void LocalParseSqlWhere(string sqlPart) + { + var sidx = 0; + var ltcou = 0; + var ltidxStack = new Stack(); + while (sidx < sqlPart.Length) + { + var chr = sqlPart[sidx++]; + if (chr == '(') + { + ltcou++; + ltidxStack.Push(sidx - 1); + //swliCurrent.Filters.Add() + } + if (chr == ')') + { + ltcou--; + var ltidx = ltidxStack.Pop(); + var pvalue = sqlPart.Substring(ltidx, sidx - ltidx); + break; + //var pname = $"@p_{Guid.NewGuid().ToString("N")}"; + //dicSqlParts.Add(pname, pvalue); + //LocalParseSqlWhere(sqlPart); + //var ltsql = sqlPart.Substring(Math.Max(0, ltidx - 5), ltidx); + //if (Regex.IsMatch(ltsql, @"(and|or|not)$")) + // ltsb.Last().Append("1=1"); + } + } + } + } + + class SqlWhereLogicInfo + { + public string Field { get; set; } + public string Operator { get; set; } + public object Value { get; set; } + + public DynamicFilterLogic Logic { get; set; } + public List Filters { get; set; } + } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index d069b5bf..8eb4d26a 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Dameng.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs index 4d45fb34..10b07f3c 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Firebird.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs index b54366b0..170653d9 100644 --- a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.GBase.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs index 6a4fd4a4..a529cf51 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.KingbaseES .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index 46fc44d6..85769c95 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.MySql.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index abf627c7..0f363b68 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Odbc.Dameng .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index 7eaf2fee..34b6b4ea 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.Odbc.KingbaseES .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 822fb089..6feac813 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -36,6 +36,7 @@ namespace FreeSql.Odbc.MySql .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index 731ad1c7..750ec905 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Odbc.Oracle .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index 8f438e22..e6bdc6a4 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.Odbc.PostgreSQL .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index 0132502c..064eccb4 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -66,6 +66,7 @@ namespace FreeSql.Odbc.SqlServer .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index f569f89a..00c611ea 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Oracle.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index 6d5a6291..4096e713 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.PostgreSQL.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index 47a7f022..e254523f 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.ShenTong.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index f672ded9..159c650b 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -66,6 +66,7 @@ namespace FreeSql.SqlServer.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index b6b4422e..bb2836a2 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.Sqlite.Curd .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._noneParameterFlag = flagInsert ? "c" : "cu"; insert._source = data; + insert._table = _table; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); From f7e22037fe9e875f553377cca9734d3488b0265d Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 11 Apr 2022 13:26:44 +0800 Subject: [PATCH 09/16] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20SqlServer=20Bulk?= =?UTF-8?q?Copy=20=E6=8F=92=E5=85=A5=20DateTime=20=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E5=80=BC=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/InsertProvider.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 6cff4587..fb2e67ea 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -693,6 +693,13 @@ namespace FreeSql.Internal.CommonProvider else val = Utils.GetDataReaderValue(col.Item2, val); } + switch (_orm.Ado.DataType) + { + case DataType.SqlServer: + case DataType.OdbcSqlServer: + if (val?.Equals(DateTime.MinValue) == true) val = new DateTime(1970, 1, 1); + break; + } row[rowIndex++] = val; } dt.Rows.Add(row); From 34011a6b5f41c5e7c12fb36611b97935bc4583c8 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 11 Apr 2022 13:29:42 +0800 Subject: [PATCH 10/16] v3.2.302 #1067 #1064 #951 #1062 #1061 #1059 #481 #1046 #1047 #646 #968 #969 #943 #996 #973 #989 #982 #980 #900 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.ClickHouse.csproj | 2 +- .../FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- .../FreeSql.Provider.SqliteCore.csproj | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 8179a363..5bbdad3f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 54f1468d..193994ce 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c67bbf96..226d469b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index dcaa057d..9980bff9 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1f3e5ce4..80b6b31f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 3.2.301 + 3.2.302 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 48d381aa..6db4046d 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a7e3da9b..c861f856 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d8de14ca..0dbbe2da 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 3.2.301 + 3.2.302 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 25abbdf8..1fe1edca 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.1;netstandard2.0;net451;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj index a5f1583d..72944ced 100644 --- a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj +++ b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj @@ -3,7 +3,7 @@ netstandard2.1 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin;ChenBo FreeSql 数据库实现,基于 ClickHouse.Client Ado.net diff --git a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj index a830fc80..87948095 100644 --- a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj +++ b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库自定义适配,访问所有数据库 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2c598242..4fee4dc1 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index f17a1785..70f5e28a 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj index abb3c2f1..8402de1e 100644 --- a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj +++ b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 3.2.301 + 3.2.302 true FreeSql;GBase FreeSql 数据库实现,基于 南大通用 8.0 diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index ce720076..5cd09f20 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 V008R003 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c59031b5..4fb41d4b 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 983cedfd..3015677e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a782465c..83f31f30 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;netstandard2.1;netcoreapp2.1;netcoreapp3.1; - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 604d78a3..c4ca0f9c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8287e388..6442d48d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 50791ab6..8e30ea14 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index a0a53d57..c97b6f20 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index dac06b77..872b5077 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index e9e77167..ddebbc4c 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4177b66d..77f7dd29 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj b/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj index d2ea2d60..81457822 100644 --- a/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj +++ b/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj @@ -2,7 +2,7 @@ netstandard2.0;net6.0 - 3.2.301 + 3.2.302 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Microsoft.Data.Sqlite.Core、Sqlite 3.0,支持 .netstandard2.0、.net6.0 From a01478b4b488b6e4fcb0eca95c948874cbd866d5 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 12 Apr 2022 17:00:02 +0800 Subject: [PATCH 11/16] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Delete.Where=20i?= =?UTF-8?q?n=20=E6=9F=A5=E8=AF=A2=E4=B8=BA=E7=A9=BA=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E5=80=99=E4=BB=8D=E7=84=B6=E6=89=A7=E8=A1=8C=E5=88=A0=E9=99=A4?= =?UTF-8?q?=EF=BC=9B#1068?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++ FreeSql/DataAnnotations/TableAttribute.cs | 9 +- .../Internal/CommonProvider/DeleteProvider.cs | 6 +- FreeSql/Internal/UtilsExpressionTree.cs | 106 ++++++++++++------ 4 files changed, 87 insertions(+), 43 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index da7ace6b..bdd16ff9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -538,5 +538,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 3680ec84..d6d2a4f3 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -256,13 +256,14 @@ namespace FreeSql.DataAnnotations public string[] GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) { if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables; - var dictParams = new Dictionary(); - var newSqlWhere = Utils.ReplaceSqlConstString(sqlWhere, dictParams); - var tsqlWhere = Utils.ParseSqlWhereLevel1(sqlWhere); - var quoteParameterName = commonUtils.QuoteParamterName(""); var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name); + + var dictParams = new Dictionary(); + var newSqlWhere = Utils.ReplaceSqlConstString(sqlWhere, dictParams, quoteParameterName); + //var tsqlWhere = Utils.ParseSqlWhereLevel1(sqlWhere); + var regs = GetRegSqlWhereDateTimes($"{(string.IsNullOrWhiteSpace(tb.Alias) ? "" : $"{tb.Alias}.")}{commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name)}", quoteParameterName); for (var a = 0; a < 8; a++) newSqlWhere = regs[a].Replace(newSqlWhere, "$1$4"); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index e3f2348e..89554481 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -170,7 +170,7 @@ namespace FreeSql.Internal.CommonProvider public virtual string ToSql() { - if (_whereTimes <= 0) return null; + if (_whereTimes <= 0 || _where.Length == 0) return null; var sb = new StringBuilder(); ToSqlFetch(sql => { @@ -182,7 +182,7 @@ namespace FreeSql.Internal.CommonProvider public void ToSqlFetch(Action fetch) { - if (_whereTimes <= 0) return; + if (_whereTimes <= 0 || _where.Length == 0) return; var newwhere = new StringBuilder().Append(" WHERE ").Append(_where); if (_whereGlobalFilter.Any()) @@ -215,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider #else async public Task ToSqlFetchAsync(Func fetchAsync) { - if (_whereTimes <= 0) return; + if (_whereTimes <= 0 || _where.Length == 0) return; var newwhere = new StringBuilder().Append(" WHERE ").Append(_where); if (_whereGlobalFilter.Any()) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 13cf5235..72a03c23 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -2268,11 +2268,19 @@ namespace FreeSql.Internal return char.IsLetter(name, 0) ? name : string.Concat("_", name); } - public static string ReplaceSqlConstString(string sql, Dictionary parms) + public static string ReplaceSqlConstString(string sql, Dictionary parms, string paramPrefix = "@") { var nsb = new StringBuilder(); var sidx = 0; var pidx = 0; + var ptmpPrefix = ""; + while (true) + { + pidx++; + ptmpPrefix = $"{paramPrefix}p{pidx}"; + if (sql.Contains(ptmpPrefix) == false) break; + } + pidx = 0; while (sidx < sql.Length) { var chr = sql[sidx++]; @@ -2307,7 +2315,7 @@ namespace FreeSql.Internal while (true) { pidx++; - pname = $"@p{pidx}"; + pname = $"{ptmpPrefix}{pidx}"; if (parms.ContainsKey(pname) == false) break; } } @@ -2326,46 +2334,72 @@ namespace FreeSql.Internal var remidx = sql.IndexOf("WHERE "); if (remidx != -1) sql = sql.Substring(remidx + 6); - var sidx = 0; - var ltcou = 0; - var ltidxStack = new Stack(); - while (sidx < sql.Length) + //sql = Regex.Replace(sql, @"\s*([@:\?][\w_]+)\s*(<|<=|>|>=|=)\s*((\w+)\s*\.)?([\w_]+)"); + return LocalProcessBrackets(sql); + + + string LocalProcessBrackets(string locsql) { - var chr = sql[sidx++]; - if (chr == '(') + var sidx = 0; + var ltcou = 0; + var ltidxStack = new Stack(); + while (sidx < locsql.Length) { - ltcou++; - ltidxStack.Push(sidx - 1); - } - if (chr == ')') - { - ltcou--; - var ltidx = ltidxStack.Pop(); - if (ltidx == 0 && sidx == sql.Length - 1) - break; - var sqlLeft = ltidx == 0 ? "" : sql.Remove(ltidx); - var sqlMid = sql.Substring(ltidx, sidx - ltidx); - var sqlMidNew = ""; - var sqlRight = sidx == sql.Length - 1 ? "" : sql.Substring(sidx + 1); - var mLeft = Regex.Match(sqlLeft, @" (and|or|not)\s*$", RegexOptions.IgnoreCase); - if (mLeft.Success) + var chr = locsql[sidx++]; + if (chr == '(') { - switch (mLeft.Groups[1].Value) - { - case "and": - sqlMidNew = sqlMid.Substring(1, sqlMid.Length - 2); - break; - case "or": - break; - case "not": - break; - } + ltcou++; + ltidxStack.Push(sidx - 1); + } + if (chr == ')') + { + ltcou--; + var ltidx = ltidxStack.Pop(); + var ltidx2 = ltidx; + var sidx2 = sidx; + while(sidx < locsql.Length) + { + var chr2 = locsql[sidx]; + if (chr2 == ')') + { + if (ltidxStack.First() == ltidx - 1) + { + ltidx = ltidxStack.Pop(); + sidx++; + } + } + break; + } + if (ltidx == 0 && sidx == locsql.Length) + { + locsql = locsql.Substring(1, sidx - 2); + break; + } + var sqlLeft = ltidx == 0 ? "" : locsql.Remove(ltidx); + var sqlMid = locsql.Substring(ltidx, sidx - ltidx); + var sqlMidNew = sqlMid; + var sqlRight = sidx == locsql.Length ? "" : locsql.Substring(sidx); + var mLeft = Regex.Match(sqlLeft, @" (and|or|not)\s*$", RegexOptions.IgnoreCase); + if (mLeft.Success) + { + switch (mLeft.Groups[1].Value) + { + case "and": + sqlMidNew = sqlMid.Substring(1, sqlMid.Length - 2).Trim(); + break; + case "or": + sqlMidNew = ""; + break; + case "not": + break; + } + } + sidx -= sqlMid.Length - sqlMidNew.Length; + locsql = $"{sqlLeft}{sqlMidNew}{sqlRight}"; } - sidx -= sqlMid.Length - sqlMidNew.Length; - sql = $"{sqlLeft}{sqlMidNew}{sqlRight}"; } + return locsql; } - return sql; } static string ParseSqlWhereLevel12(string sql) From 0387c0a4cf2412b1f8bdfcbc0aa48ba712dccc11 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 12 Apr 2022 18:28:55 +0800 Subject: [PATCH 12/16] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Delete.Where=20i?= =?UTF-8?q?n=20=E6=9F=A5=E8=AF=A2=E4=B8=BA=E7=A9=BA=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E6=93=8D=E4=BD=9C=E4=BB=8D=E7=84=B6=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E5=88=A0=E9=99=A4=EF=BC=9B#1068?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs | 2 ++ FreeSql/Internal/CommonProvider/DeleteProvider.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index c40c4e42..9562a3c6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -77,6 +77,8 @@ namespace FreeSql.Tests.SqliteExpression { IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + var testlinq2list = new string[] { }; + var testlinq2 = g.sqlite.Delete().Where(a => testlinq2list.Contains(a.String)).ToSql(); //in not in var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 89554481..0fe798c0 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -239,7 +239,7 @@ namespace FreeSql.Internal.CommonProvider return; } - sb.Insert(0, _commonUtils.QuoteSqlName(TableRuleInvoke())).Insert(0, "DELETE FROM "); + sb.Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere); _interceptSql?.Invoke(sb); await fetchAsync(sb); sb.Clear(); From 46ad51c7e0656fcbdb0272925d49836e36ec4e76 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 12 Apr 2022 20:01:34 +0800 Subject: [PATCH 13/16] v3.2.303 #1068 #1067 #1064 #951 #1062 #1061 #1059 #481 #1046 #1047 #646 #968 #969 #943 #996 #973 #989 #982 #980 #900 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.ClickHouse.csproj | 2 +- .../FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- .../FreeSql.Provider.SqliteCore.csproj | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5bbdad3f..996c1667 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 193994ce..2651a86d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 226d469b..e6f97088 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 9980bff9..973c7364 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 80b6b31f..578630f3 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 3.2.302 + 3.2.303 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 6db4046d..88391f56 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c861f856..d6c2cbd2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0dbbe2da..4f22e057 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 3.2.302 + 3.2.303 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1fe1edca..8cecf974 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.1;netstandard2.0;net451;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj index 72944ced..6daf8105 100644 --- a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj +++ b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj @@ -3,7 +3,7 @@ netstandard2.1 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin;ChenBo FreeSql 数据库实现,基于 ClickHouse.Client Ado.net diff --git a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj index 87948095..6b95186c 100644 --- a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj +++ b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库自定义适配,访问所有数据库 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 4fee4dc1..54caa053 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 70f5e28a..a8d578ce 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj index 8402de1e..cce76c07 100644 --- a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj +++ b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 3.2.302 + 3.2.303 true FreeSql;GBase FreeSql 数据库实现,基于 南大通用 8.0 diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 5cd09f20..9059e99d 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 V008R003 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 4fb41d4b..b18673ac 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3015677e..901d87bb 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 83f31f30..8b47a975 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;netstandard2.1;netcoreapp2.1;netcoreapp3.1; - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c4ca0f9c..639787a1 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6442d48d..eb8d960f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8e30ea14..f6e4a389 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c97b6f20..80672c9f 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 872b5077..50d07c5c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index ddebbc4c..2298baf9 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 77f7dd29..88a1ce5b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj b/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj index 81457822..f9c9248b 100644 --- a/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj +++ b/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj @@ -2,7 +2,7 @@ netstandard2.0;net6.0 - 3.2.302 + 3.2.303 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Microsoft.Data.Sqlite.Core、Sqlite 3.0,支持 .netstandard2.0、.net6.0 From 91522386b1b000b860bcf9682481b90f62441861 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 12 Apr 2022 21:44:31 +0800 Subject: [PATCH 14/16] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20DbContext/Reposi?= =?UTF-8?q?tory=20Update=20=E5=AE=9E=E4=BD=93=E6=9C=89=20ServerTime=20?= =?UTF-8?q?=E6=97=A2=E4=BD=BF=E6=97=A0=E7=8A=B6=E6=80=81=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E4=B9=9F=E5=BF=85=E7=84=B6=E6=9B=B4=E6=96=B0=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ---- .../RepositoryTests.cs | 49 +++++++++++++++++++ FreeSql/Extensions/EntityUtilExtensions.cs | 10 +++- FreeSql/Internal/Model/TableInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 1 + 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index bdd16ff9..da7ace6b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -538,14 +538,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 71177284..00eba288 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -593,6 +593,55 @@ namespace FreeSql.Tests public Guid Id { get; set; } public string Name { get; set; } } + [Fact] + public void BeginEditIdentity() + { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlite.GetRepository(); + var cts = new[] { + new BeginEdit02 { Name = "1" }, + new BeginEdit02 { Name = "1_1" }, + new BeginEdit02 { Name = "1_2" }, + new BeginEdit02 { Name = "1_3" }, + new BeginEdit02 { Name = "2" }, + new BeginEdit02 { Name = "2_1" }, + new BeginEdit02 { Name = "2_2" } + }.ToList(); + repo.Insert(cts); + + repo.BeginEdit(cts); + + cts.Add(new BeginEdit02 { Name = "2_3" }); + cts[0].Name = "123123"; + cts.RemoveAt(1); + + Assert.Equal(3, repo.EndEdit()); + + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + repo = g.sqlite.GetRepository(); + cts = repo.Select.ToList(); + repo.BeginEdit(cts); + + cts.AddRange(new[] { + new BeginEdit02 { Name = "1" }, + new BeginEdit02 { Name = "1_1" }, + new BeginEdit02 { Name = "1_2" }, + new BeginEdit02 { Name = "1_3" }, + new BeginEdit02 { Name = "2" }, + new BeginEdit02 { Name = "2_1" }, + new BeginEdit02 { Name = "2_2" } + }); + + Assert.Equal(7, repo.EndEdit()); + } + class BeginEdit02 + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + [Column(ServerTime = DateTimeKind.Utc)] + public DateTime UpdateTime { get; set; } + } [Fact] public void OrmScoped() diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 97732054..b19f1316 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -604,7 +604,15 @@ namespace FreeSql.Extensions.EntityUtil exps.Add(Expression.Label(returnTarget, Expression.Constant(new string[0]))); return Expression.Lambda>(Expression.Block(new[] { var1Ret, var1Parm, var2Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); }); - return func(entity1, entity2, isEqual); + var result = func(entity1, entity2, isEqual); + var tmptb = orm.CodeFirst.GetTableByEntity(entityType); + if (tmptb.ColumnsByCanUpdateDbUpdateValue.Length > 0) { + if (isEqual && result.Length + tmptb.ColumnsByCanUpdateDbUpdateValue.Length == tmptb.ColumnsByCs.Count) + return result.Concat(tmptb.ColumnsByCanUpdateDbUpdateValue.Select(a => a.Attribute.Name)).ToArray(); + if (!isEqual && result.Length == tmptb.ColumnsByCanUpdateDbUpdateValue.Length) + return new string[0]; + } + return result; } static ConcurrentDictionary>> _dicSetEntityIncrByWithPropertyName = new ConcurrentDictionary>>(); diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index c09484ef..7de85216 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -17,6 +17,7 @@ namespace FreeSql.Internal.Model public Dictionary ColumnsByCs { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary ColumnsByCsIgnore { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public ColumnInfo[] ColumnsByPosition { get; set; } + public ColumnInfo[] ColumnsByCanUpdateDbUpdateValue { get; set; } public ColumnInfo[] Primarys { get; set; } public IndexInfo[] Indexes { get; set; } public string CsName { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 72a03c23..08fc5aff 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -484,6 +484,7 @@ namespace FreeSql.Internal trytb.ColumnsByPosition = columnsList.Where(a => a.Attribute.Position > 0).OrderBy(a => a.Attribute.Position) .Concat(columnsList.Where(a => a.Attribute.Position == 0)) .Concat(columnsList.Where(a => a.Attribute.Position < 0).OrderBy(a => a.Attribute.Position)).ToArray(); + trytb.ColumnsByCanUpdateDbUpdateValue = columnsList.Where(a => a.Attribute.CanUpdate == true && string.IsNullOrEmpty(a.DbUpdateValue) == false).ToArray(); trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); if (trytb.Primarys.Any() == false) From d6ec48ed4ce5972bad42ae9a25989a57c8259f75 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 12 Apr 2022 21:48:01 +0800 Subject: [PATCH 15/16] v3.2.500 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.ClickHouse.csproj | 2 +- .../FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- .../FreeSql.Provider.SqliteCore.csproj | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 996c1667..58f962ef 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2651a86d..ade05a72 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e6f97088..2430ab50 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 973c7364..2753d22b 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 578630f3..b563d8bf 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 3.2.303 + 3.2.500 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 88391f56..e338f353 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d6c2cbd2..50045f66 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4f22e057..e26309aa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 3.2.303 + 3.2.500 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8cecf974..16576b0e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.1;netstandard2.0;net451;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj index 6daf8105..c495bf58 100644 --- a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj +++ b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj @@ -3,7 +3,7 @@ netstandard2.1 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin;ChenBo FreeSql 数据库实现,基于 ClickHouse.Client Ado.net diff --git a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj index 6b95186c..d8889460 100644 --- a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj +++ b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库自定义适配,访问所有数据库 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 54caa053..d61598e2 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index a8d578ce..5a408391 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj index cce76c07..823a487c 100644 --- a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj +++ b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 3.2.303 + 3.2.500 true FreeSql;GBase FreeSql 数据库实现,基于 南大通用 8.0 diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 9059e99d..2de6eea0 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 V008R003 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index b18673ac..3c7346a2 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 901d87bb..2a24a2ee 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8b47a975..a15df93c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;netstandard2.1;netcoreapp2.1;netcoreapp3.1; - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 639787a1..0e419f84 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index eb8d960f..1637f7fc 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f6e4a389..db59f51f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 80672c9f..4803e309 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 50d07c5c..bf8bfc27 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 2298baf9..748d6f6f 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 88a1ce5b..c8466939 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj b/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj index f9c9248b..e9a158c4 100644 --- a/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj +++ b/Providers/FreeSql.Provider.SqliteCore/FreeSql.Provider.SqliteCore.csproj @@ -2,7 +2,7 @@ netstandard2.0;net6.0 - 3.2.303 + 3.2.500 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Microsoft.Data.Sqlite.Core、Sqlite 3.0,支持 .netstandard2.0、.net6.0 From 703b9aeafa3ef162db34aa64438bcda886048d6b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 14 Apr 2022 11:30:23 +0800 Subject: [PATCH 16/16] update pgsql json POCO test --- Examples/base_entity/Program.cs | 99 ++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5b9294b5..35984858 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -11,7 +11,9 @@ using System.Data.Odbc; using System.Data.SqlClient; using System.Data.SQLite; using System.Diagnostics; +using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Serialization; @@ -107,11 +109,32 @@ namespace base_entity public DateTime createtime { get; set; } } + public class SomeEntity + { + [Column(IsIdentity = true)] + public int Id { get; set; } + [Column(MapType = typeof(JToken))] + public Customer Customer { get; set; } + } + + public class Customer // Mapped to a JSON column in the table + { + public string Name { get; set; } + public int Age { get; set; } + public Order[] Orders { get; set; } + } + + public class Order // Part of the JSON column + { + public decimal Price { get; set; } + public string ShippingAddress { get; set; } + } + static void Main(string[] args) { #region 初始化 IFreeSql var fsql = new FreeSql.FreeSqlBuilder() - .UseAutoSyncStructure(true) + //.UseAutoSyncStructure(true) .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test1.db;max pool size=5") @@ -123,8 +146,8 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") - //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") - //.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) @@ -149,6 +172,76 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + fsql.Aop.ParseExpression += (_, e) => + { + //解析 POCO Jsonb a.Customer.Name + if (e.Expression is MemberExpression memExp) + { + var parentMemExps = new Stack(); + parentMemExps.Push(memExp); + while (true) + { + switch (memExp.Expression.NodeType) + { + case ExpressionType.MemberAccess: + memExp = memExp.Expression as MemberExpression; + if (memExp == null) return; + parentMemExps.Push(memExp); + break; + case ExpressionType.Parameter: + var tb = fsql.CodeFirst.GetTableByEntity(memExp.Expression.Type); + if (tb == null) return; + if (tb.ColumnsByCs.TryGetValue(parentMemExps.Pop().Member.Name, out var trycol) == false) return; + if (new[] { typeof(JToken), typeof(JObject), typeof(JArray) }.Contains(trycol.Attribute.MapType.NullableTypeOrThis()) == false) return; + var tmpcol = tb.ColumnsByPosition.OrderBy(a => a.Attribute.Name.Length).First(); + var result = e.FreeParse(Expression.MakeMemberAccess(memExp.Expression, tb.Properties[tmpcol.CsName])); + result = result.Replace(tmpcol.Attribute.Name, trycol.Attribute.Name); + while (parentMemExps.Any()) + { + memExp = parentMemExps.Pop(); + result = $"{result}->>'{memExp.Member.Name}'"; + } + e.Result = result; + return; + } + } + } + }; + + var methodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); + var methodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); + var jsonConvertSettings = JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings(); + FreeSql.Internal.Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Customer)] = true; + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => + { + return Expression.IfThenElse( + Expression.TypeIs(valueExp, typeof(Customer)), + Expression.Return(returnTarget, Expression.Call(methodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(jsonConvertSettings)), typeof(object)), + elseExp); + }); + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => + { + if (type == typeof(Customer)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(methodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); + return null; + }); + + var seid = fsql.Insert(new SomeEntity + { + Customer = JsonConvert.DeserializeObject(@"{ + ""Age"": 25, + ""Name"": ""Joe"", + ""Orders"": [ + { ""OrderPrice"": 9, ""ShippingAddress"": ""Some address 1"" }, + { ""OrderPrice"": 23, ""ShippingAddress"": ""Some address 2"" } + ] +}") + }).ExecuteIdentity(); + var selist = fsql.Select().ToList(); + + var joes = fsql.Select() + .Where(e => e.Customer.Name == "Joe") + .ToSql(); + var testitems = new[] { new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") },