From a9e34f852aa60bada0b5b5880075b7c55f9b1e66 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Mar 2019 21:54:35 +0800 Subject: [PATCH] ## v0.3.24 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 GroupBy 分页方法; - 修复 Insert 参数化命名 bug,当存在 Id Id2 时发生; - 优化 Insert/Delete/Update 对象执行完后清理数据,以备多次使用; --- .../Controllers/ValuesController.cs | 50 +-- Examples/dbcontext_01/Startup.cs | 7 +- FreeSql.DbContext/DbContext.cs | 95 ------ FreeSql.DbContext/DbContextAsync.cs | 110 +------ FreeSql.DbContext/DbContextSync.cs | 108 +++++++ FreeSql.DbContext/DbSet.cs | 276 ++++++++--------- FreeSql.DbContext/DbSetAsync.cs | 126 +------- FreeSql.DbContext/DbSetSync.cs | 216 +++++++++++++ FreeSql.DbContext/EntityUtil.cs | 107 ++++--- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs | 32 +- FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 2 + FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs | 284 +++++++++--------- FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 2 + .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 32 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 + .../SqlServer/Curd/SqlServerInsertTest.cs | 32 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 + FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs | 32 +- FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 2 + FreeSql/FreeSql.csproj | 2 +- .../Interface/Curd/ISelect/ISelectGrouping.cs | 34 +++ .../Internal/CommonProvider/DeleteProvider.cs | 16 +- .../Internal/CommonProvider/InsertProvider.cs | 22 +- .../SelectProvider/SelectGroupingProvider.cs | 20 ++ .../Internal/CommonProvider/UpdateProvider.cs | 17 +- FreeSql/MySql/Curd/MySqlDelete.cs | 8 +- FreeSql/MySql/Curd/MySqlInsert.cs | 16 +- FreeSql/MySql/Curd/MySqlUpdate.cs | 8 +- FreeSql/Oracle/Curd/OracleInsert.cs | 14 +- FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs | 8 +- FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs | 16 +- FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs | 8 +- FreeSql/SqlServer/Curd/SqlServerDelete.cs | 8 +- FreeSql/SqlServer/Curd/SqlServerInsert.cs | 16 +- FreeSql/SqlServer/Curd/SqlServerInsert2100.cs | 281 ----------------- FreeSql/SqlServer/Curd/SqlServerUpdate.cs | 8 +- FreeSql/Sqlite/Curd/SqliteInsert.cs | 10 +- 39 files changed, 975 insertions(+), 1058 deletions(-) create mode 100644 FreeSql.DbContext/DbContextSync.cs create mode 100644 FreeSql.DbContext/DbSetSync.cs delete mode 100644 FreeSql/SqlServer/Curd/SqlServerInsert2100.cs diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 4762103f..f1c67a4e 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -29,60 +29,74 @@ namespace dbcontext_01.Controllers using (var ctx = new SongContext()) { ctx.Songs.Select.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states var song = new Song { }; + //可插入的 song + ctx.Songs.Add(song); id = song.Id; + //因有自增类型,立即开启事务执行SQL,返回自增值 var adds = Enumerable.Range(0, 100) .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) .ToList(); + //创建一堆无主键值 + ctx.Songs.AddRange(adds); + //立即执行,将自增值赋给 adds 所有元素,因为有自增类型,如果其他类型,指定传入主键值,不会立即执行 for (var a = 0; a < adds.Count; a++) adds[a].Title = "dkdkdkdk" + a; ctx.Songs.UpdateRange(adds); + //批量修改,进入队列 ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + //批量删除,进入队列,完成时 10-20 元素的主键值会被清除 //ctx.Songs.Update(adds.First()); adds.Last().Url = "skldfjlksdjglkjjcccc"; ctx.Songs.Update(adds.Last()); + //单条修改 urls 的值,进入队列 //throw new Exception("回滚"); + //ctx.Songs.Select.First(); + //这里做一个查询,会立即打包【执行队列】,避免没有提交的数据,影响查询结果 + ctx.SaveChanges(); + //打包【执行队列】,提交事务 } - using (var ctx = new SongContext()) { + //using (var ctx = new SongContext()) { - var song = new Song { }; - await ctx.Songs.AddAsync(song); - id = song.Id; + // var song = new Song { }; + // await ctx.Songs.AddAsync(song); + // id = song.Id; - var adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) - .ToList(); - await ctx.Songs.AddRangeAsync(adds); + // var adds = Enumerable.Range(0, 100) + // .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + // .ToList(); + // await ctx.Songs.AddRangeAsync(adds); - for (var a = 0; a < adds.Count; a++) - adds[a].Title = "dkdkdkdk" + a; + // for (var a = 0; a < adds.Count; a++) + // adds[a].Title = "dkdkdkdk" + a; - ctx.Songs.UpdateRange(adds); + // ctx.Songs.UpdateRange(adds); - ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + // ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); - //ctx.Songs.Update(adds.First()); + // //ctx.Songs.Update(adds.First()); - adds.Last().Url = "skldfjlksdjglkjjcccc"; - ctx.Songs.Update(adds.Last()); + // adds.Last().Url = "skldfjlksdjglkjjcccc"; + // ctx.Songs.Update(adds.Last()); - //throw new Exception("回滚"); + // //throw new Exception("回滚"); - await ctx.SaveChangesAsync(); - } + // await ctx.SaveChangesAsync(); + //} } catch { var item = await _orm.Select().Where(a => a.Id == id).FirstAsync(); diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs index a7e3965a..40a88ff0 100644 --- a/Examples/dbcontext_01/Startup.cs +++ b/Examples/dbcontext_01/Startup.cs @@ -20,12 +20,15 @@ namespace dbcontext_01 Configuration = configuration; Fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") .UseLogger(loggerFactory.CreateLogger()) .UseAutoSyncStructure(true) .UseLazyLoading(true) - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), + (cmd, log) => Trace.WriteLine(log) + ) .Build(); } diff --git a/FreeSql.DbContext/DbContext.cs b/FreeSql.DbContext/DbContext.cs index 61b84324..fe768d1b 100644 --- a/FreeSql.DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext.cs @@ -47,12 +47,6 @@ namespace FreeSql { protected Dictionary AllSets { get; } = new Dictionary(); - public long SaveChanges() { - ExecCommand(); - Commit(); - return _affrows; - } - internal class ExecCommandInfo { public ExecCommandInfoType actionType { get; set; } public object dbSet { get; set; } @@ -67,95 +61,6 @@ namespace FreeSql { _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); } - static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); - internal void ExecCommand() { - ExecCommandInfo oldinfo = null; - var states = new List(); - - Func dbContextBetch = methodName => { - if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - - var returnTarget = Expression.Label(typeof(int)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(int))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } - return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Action funcDelete = () => { - _affrows += dbContextBetch("DbContextBetchRemove"); - states.Clear(); - }; - Action funcInsert = () => { - _affrows += dbContextBetch("DbContextBetchAdd"); - states.Clear(); - }; - Action funcUpdate = isLiveUpdate => { - var affrows = 0; - if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); - else affrows = dbContextBetch("DbContextBetchUpdate"); - if (affrows == -999) { //最后一个元素已被删除 - states.RemoveAt(states.Count - 1); - return; - } - if (affrows > 0) { - _affrows += affrows; - var islastNotUpdated = states.Count != affrows; - states.Clear(); - if (islastNotUpdated) states.Add(oldinfo.state); - } - }; - - while (_actions.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; - if (oldinfo == null) oldinfo = info; - var isLiveUpdate = false; - - if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) { - - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { - //最后一个,合起来发送 - states.Add(info.state); - info = null; - } - - switch (oldinfo.actionType) { - case ExecCommandInfoType.Insert: - funcInsert(); - break; - case ExecCommandInfoType.Delete: - funcDelete(); - break; - } - isLiveUpdate = true; - } - - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { - if (states.Any()) - funcUpdate(isLiveUpdate); - } - - if (info != null) { - states.Add(info.state); - oldinfo = info; - } - } - } - void ReturnObject() { _fsql.Ado.MasterPool.Return(_conn); _tran = null; diff --git a/FreeSql.DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContextAsync.cs index 9394eaaa..5f282702 100644 --- a/FreeSql.DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContextAsync.cs @@ -1,109 +1 @@ -using SafeObjectPool; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data.Common; -using System.Linq; -using System.Reflection; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql { - partial class DbContext { - - async public Task SaveChangesAsync() { - await ExecCommandAsync(); - Commit(); - return _affrows; - } - - static Dictionary>>> _dicExecCommandAsyncDbContextBetch = new Dictionary>>>(); - async internal Task ExecCommandAsync() { - ExecCommandInfo oldinfo = null; - var states = new List(); - - Func> dbContextBetch = methodName => { - if (_dicExecCommandAsyncDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - - var returnTarget = Expression.Label(typeof(Task)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(Task))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } - return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Func funcDelete = async () => { - _affrows += await dbContextBetch("DbContextBetchRemoveAsync"); - states.Clear(); - }; - Func funcInsert = async () => { - _affrows += await dbContextBetch("DbContextBetchAddAsync"); - states.Clear(); - }; - Func funcUpdate = async isLiveUpdate => { - var affrows = 0; - if (isLiveUpdate) affrows = await dbContextBetch("DbContextBetchUpdateNowAsync"); - else affrows = await dbContextBetch("DbContextBetchUpdateAsync"); - if (affrows == -999) { //最后一个元素已被删除 - states.RemoveAt(states.Count - 1); - return; - } - if (affrows > 0) { - _affrows += affrows; - var islastNotUpdated = states.Count != affrows; - states.Clear(); - if (islastNotUpdated) states.Add(oldinfo.state); - } - }; - - while (_actions.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; - if (oldinfo == null) oldinfo = info; - var isLiveUpdate = false; - - if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) { - - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { - //最后一个,合起来发送 - states.Add(info.state); - info = null; - } - - switch (oldinfo.actionType) { - case ExecCommandInfoType.Insert: - await funcInsert(); - break; - case ExecCommandInfoType.Delete: - await funcDelete(); - break; - } - isLiveUpdate = true; - } - - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { - if (states.Any()) - await funcUpdate(isLiveUpdate); - } - - if (info != null) { - states.Add(info.state); - oldinfo = info; - } - } - } - } -} + \ No newline at end of file diff --git a/FreeSql.DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContextSync.cs new file mode 100644 index 00000000..ca30bf43 --- /dev/null +++ b/FreeSql.DbContext/DbContextSync.cs @@ -0,0 +1,108 @@ +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Data.Common; +using System.Linq; +using System.Reflection; +using System.Linq.Expressions; + +namespace FreeSql { + partial class DbContext { + + public long SaveChanges() { + ExecCommand(); + Commit(); + return _affrows; + } + + static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); + internal void ExecCommand() { + ExecCommandInfo oldinfo = null; + var states = new List(); + + Func dbContextBetch = methodName => { + if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) + trydic = new Dictionary>(); + if (trydic.TryGetValue(methodName, out var tryfunc) == false) { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + + var returnTarget = Expression.Label(typeof(int)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + tryfunc = Expression.Lambda>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(int))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + trydic.Add(methodName, tryfunc); + } + return tryfunc(oldinfo.dbSet, states.ToArray()); + }; + Action funcDelete = () => { + _affrows += dbContextBetch("DbContextBetchRemove"); + states.Clear(); + }; + Action funcInsert = () => { + _affrows += dbContextBetch("DbContextBetchAdd"); + states.Clear(); + }; + Action funcUpdate = isLiveUpdate => { + var affrows = 0; + if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); + else affrows = dbContextBetch("DbContextBetchUpdate"); + if (affrows == -999) { //最后一个元素已被删除 + states.RemoveAt(states.Count - 1); + return; + } + if (affrows > 0) { + _affrows += affrows; + var islastNotUpdated = states.Count != affrows; + states.Clear(); + if (islastNotUpdated) states.Add(oldinfo.state); + } + }; + + while (_actions.Any() || states.Any()) { + var info = _actions.Any() ? _actions.Dequeue() : null; + if (oldinfo == null) oldinfo = info; + var isLiveUpdate = false; + + if (_actions.Any() == false && states.Any() || + info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.stateType != info.stateType) { + + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { + //最后一个,合起来发送 + states.Add(info.state); + info = null; + } + + switch (oldinfo.actionType) { + case ExecCommandInfoType.Insert: + funcInsert(); + break; + case ExecCommandInfoType.Delete: + funcDelete(); + break; + } + isLiveUpdate = true; + } + + if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { + if (states.Any()) + funcUpdate(isLiveUpdate); + } + + if (info != null) { + states.Add(info.state); + oldinfo = info; + } + } + } + } +} diff --git a/FreeSql.DbContext/DbSet.cs b/FreeSql.DbContext/DbSet.cs index 6b51cb30..fabad558 100644 --- a/FreeSql.DbContext/DbSet.cs +++ b/FreeSql.DbContext/DbSet.cs @@ -24,9 +24,9 @@ namespace FreeSql { } protected IInsert OrmInsert() => _fsql.Insert().WithTransaction(_ctx.GetOrBeginTransaction()); - protected IInsert OrmInsert(TEntity source) => _fsql.Insert(source).WithTransaction(_ctx.GetOrBeginTransaction()); - protected IInsert OrmInsert(TEntity[] source) => _fsql.Insert(source).WithTransaction(_ctx.GetOrBeginTransaction()); - protected IInsert OrmInsert(IEnumerable source) => _fsql.Insert(source).WithTransaction(_ctx.GetOrBeginTransaction()); + protected IInsert OrmInsert(TEntity data) => _fsql.Insert(data).WithTransaction(_ctx.GetOrBeginTransaction()); + protected IInsert OrmInsert(TEntity[] data) => _fsql.Insert(data).WithTransaction(_ctx.GetOrBeginTransaction()); + protected IInsert OrmInsert(IEnumerable data) => _fsql.Insert(data).WithTransaction(_ctx.GetOrBeginTransaction()); protected IUpdate OrmUpdate(object dywhere) => _fsql.Update(dywhere).WithTransaction(_ctx.GetOrBeginTransaction()); protected IDelete OrmDelete(object dywhere) => _fsql.Delete(dywhere).WithTransaction(_ctx.GetOrBeginTransaction()); @@ -35,7 +35,7 @@ namespace FreeSql { public ISelect Where(Expression> exp) => this.OrmSelect(null).Where(exp); public ISelect WhereIf(bool condition, Expression> exp) => this.OrmSelect(null).WhereIf(condition, exp); - protected Dictionary _vals = new Dictionary(); + protected Dictionary _states = new Dictionary(); TableInfo _tablePriv; protected TableInfo _table => _tablePriv ?? (_tablePriv = _fsql.CodeFirst.GetTableByEntity(_entityType)); ColumnInfo[] _tableIdentitysPriv; @@ -43,177 +43,167 @@ namespace FreeSql { protected Type _entityType = typeof(TEntity); public class EntityState { + public EntityState(TEntity value, string key) { + this.Value = value; + this.Key = key; + this.Time = DateTime.Now; + } public TEntity Value { get; set; } public string Key { get; set; } public DateTime Time { get; set; } } - int DbContextBetcAdd(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = this.OrmInsert(dels.Select(a => a.Value)).ExecuteAffrows(); - return affrows; + #region Utils + protected EntityState CreateEntityState(TEntity data) { + if (data == null) throw new ArgumentNullException(nameof(data)); + var key = _fsql.GetEntityKeyString(data); + var state = new EntityState(Activator.CreateInstance(), key); + _fsql.MapEntityValue(data, state.Value); + return state; } - public void Add(TEntity source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - var key = _fsql.GetEntityKeyString(source); - EntityState state = new EntityState(); + protected bool ExistsInStates(TEntity data) { + if (data == null) throw new ArgumentNullException(nameof(data)); + var key = _fsql.GetEntityKeyString(data); + if (string.IsNullOrEmpty(key)) return false; + return _states.ContainsKey(key); + } + protected bool CanAdd(TEntity[] data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + foreach (var s in data) if (CanAdd(s, isThrow) == false) return false; + return true; + } + protected bool CanAdd(IEnumerable data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + foreach (var s in data) if (CanAdd(s, isThrow) == false) return false; + return true; + } + protected bool CanAdd(TEntity data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + var key = _fsql.GetEntityKeyString(data); if (string.IsNullOrEmpty(key)) { - switch(_fsql.Ado.DataType) { + switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - _ctx.ExecCommand(); - var idtval = this.OrmInsert(source).ExecuteIdentity(); - _ctx._affrows++; - _fsql.SetEntityIdentityValue(source, idtval); - } else { - _ctx.ExecCommand(); - state.Value = this.OrmInsert(source).ExecuteInserted().First(); - _ctx._affrows++; - _fsql.CopyEntityValue(source, state.Value); - } - break; + return true; case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - _ctx.ExecCommand(); - var idtval = this.OrmInsert(source).ExecuteIdentity(); - _ctx._affrows++; - _fsql.SetEntityIdentityValue(source, idtval); - } else { - throw new Exception($"DbSet.Add 失败,未设置主键的值,或者没有配置自增,或者自增列数不为1:{_fsql.GetEntityString(source)}"); + return true; } - break; + if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_fsql.GetEntityString(data)}"); + return false; } - - state.Key = key = _fsql.GetEntityKeyString(source); - state.Time = DateTime.Now; } else { - if (_vals.ContainsKey(key)) - throw new Exception($"DbSet.Add 失败,实体数据已存在,请勿重复添加:{_fsql.GetEntityString(source)}"); - _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Insert, this, typeof(EntityState), state); - } - if (state.Value == null) { - state.Value = Activator.CreateInstance(); - _fsql.CopyEntityValue(state.Value, source); //copy, 记录旧值版本 - } - _vals.Add(key, state); - } - public void AddRange(TEntity[] source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - for (var a = 0; a < source.Length; a++) - Add(source[a]); - } - public void AddRange(IEnumerable source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - foreach(var item in source) - Add(item); - } - - int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); - int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); - int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) { - if (ups.Any() == false) return 0; - var uplst1 = ups[ups.Length - 1]; - var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; - - if (_vals.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; - var lstval2 = default(EntityState); - if (uplst2 != null && _vals.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"DbSet.Update 失败,实体应该先查询再修改:{_fsql.GetEntityString(uplst2.Value)}"); - - var cuig1 = _fsql.CompareEntityValueReturnColumns(uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(uplst2.Value, lstval2.Value, true) : null; - if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { - //最后一个不保存 - var source = ups.ToList(); - source.RemoveAt(ups.Length - 1); - var affrows = this.OrmUpdate(null).SetSource(source.Select(a => a.Value)).IgnoreColumns(cuig2).ExecuteAffrows(); - foreach (var newval in source) { - if (_vals.TryGetValue(newval.Key, out var tryold)) - _fsql.CopyEntityValue(tryold.Value, newval.Value); + if (_states.ContainsKey(key)) { + if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_fsql.GetEntityString(data)}"); + return false; } - return affrows; - } else if (isLiveUpdate) { - //立即保存 - var source = ups; - var affrows = this.OrmUpdate(null).SetSource(source.Select(a => a.Value)).IgnoreColumns(cuig1).ExecuteAffrows(); - foreach (var newval in source) { - if (_vals.TryGetValue(newval.Key, out var tryold)) - _fsql.CopyEntityValue(tryold.Value, newval.Value); + var idval = _fsql.GetEntityIdentityValueWithPrimary(data); + if (idval > 0) { + if (isThrow) throw new Exception($"不可添加,自增属性有值:{_fsql.GetEntityString(data)}"); + return false; } - return Math.Min(ups.Length, affrows); } - //等待下次对比再保存 - return 0; - } - public void Update(TEntity source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (_table.Primarys.Any() == false) throw new Exception($"DbSet.Update 失败,实体没有主键:{_fsql.GetEntityString(source)}"); - var key = _fsql.GetEntityKeyString(source); - if (string.IsNullOrEmpty(key)) throw new Exception($"DbSet.Update 失败,未设置主键的值:{_fsql.GetEntityString(source)}"); - if (_vals.TryGetValue(key, out var tryval) == false) throw new Exception($"DbSet.Update 失败,实体未被跟踪,更新前应该先做查询:{_fsql.GetEntityString(source)}"); - - var snap = Activator.CreateInstance(); - _fsql.CopyEntityValue(snap, source); //copy,避免SaveChanges前对象再次被修改 - _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Update, this, typeof(EntityState), new EntityState { Value = snap, Key = key, Time = DateTime.Now }); - } - public void UpdateRange(TEntity[] source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - for (var a = 0; a < source.Length; a++) - Update(source[a]); - } - public void UpdateRange(IEnumerable source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - foreach (var item in source) - Update(item); + return true; } - int DbContextBetchRemove(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); - //foreach (var del in dels) - // _vals.Remove(del.Key); - return affrows; + protected bool CanUpdate(TEntity[] data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + foreach (var s in data) if (CanUpdate(s, isThrow) == false) return false; + return true; } - public void Remove(TEntity source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (_table.Primarys.Any() == false) throw new Exception($"DbSet.Remove 失败,实体没有主键:{_fsql.GetEntityString(source)}"); - var key = _fsql.GetEntityKeyString(source); - if (string.IsNullOrEmpty(key)) throw new Exception($"DbSet.Remove 失败,未设置主键的值:{_fsql.GetEntityString(source)}"); - if (_vals.TryGetValue(key, out var tryval) == false) throw new Exception($"DbSet.Remove 失败,实体未被跟踪,删除前应该先做查询:{_fsql.GetEntityString(source)}"); - - var snap = Activator.CreateInstance(); - _fsql.CopyEntityValue(snap, source); //copy,避免SaveChanges前对象再次被修改 - _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Delete, this, typeof(EntityState), new EntityState { Value = snap, Key = key, Time = DateTime.Now }); - - _vals.Remove(key); - _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(source); + protected bool CanUpdate(IEnumerable data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + foreach (var s in data) if (CanUpdate(s, isThrow) == false) return false; + return true; } - public void RemoveRange(TEntity[] source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - for (var a = 0; a < source.Length; a++) - Remove(source[a]); - } - public void RemoveRange(IEnumerable source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - foreach (var item in source) - Remove(item); + protected bool CanUpdate(TEntity data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) { + if (isThrow) throw new Exception($"不可更新,实体没有主键:{_fsql.GetEntityString(data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(data); + if (string.IsNullOrEmpty(key)) { + if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(data)}"); + return false; + } + if (_states.TryGetValue(key, out var tryval) == false) { + if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询:{_fsql.GetEntityString(data)}"); + return false; + } + return true; } + protected bool CanRemove(TEntity[] data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + foreach (var s in data) if (CanRemove(s, isThrow) == false) return false; + return true; + } + protected bool CanRemove(IEnumerable data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + foreach (var s in data) if (CanRemove(s, isThrow) == false) return false; + return true; + } + protected bool CanRemove(TEntity data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) { + if (isThrow) throw new Exception($"不可删除,实体没有主键:{_fsql.GetEntityString(data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(data); + if (string.IsNullOrEmpty(key)) { + if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(data)}"); + return false; + } + if (_states.TryGetValue(key, out var tryval) == false) { + if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询:{_fsql.GetEntityString(data)}"); + return false; + } + return true; + } + #endregion + void TrackToList(object list) { if (list == null) return; var ls = list as IList; + if (ls == null) return; foreach (var item in ls) { var key = _fsql.GetEntityKeyString(item); - if (_vals.ContainsKey(key)) { - _fsql.CopyEntityValue(_vals[key].Value, item); - _vals[key].Time = DateTime.Now; + if (_states.ContainsKey(key)) { + _fsql.MapEntityValue(item, _states[key].Value); + _states[key].Time = DateTime.Now; } else { - var snap = Activator.CreateInstance(); - _fsql.CopyEntityValue(snap, item); - _vals.Add(key, new EntityState { Value = snap, Key = key, Time = DateTime.Now }); + _states.Add(key, CreateEntityState(item)); } } } diff --git a/FreeSql.DbContext/DbSetAsync.cs b/FreeSql.DbContext/DbSetAsync.cs index cb2b6f7c..5f282702 100644 --- a/FreeSql.DbContext/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSetAsync.cs @@ -1,125 +1 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data; -using System.Data.Common; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; -using System.Reflection; -using FreeSql.Extensions; - -namespace FreeSql { - abstract partial class DbSet { - - async Task DbContextBetcAddAsync(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = await this.OrmInsert(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); - return affrows; - } - async public Task AddAsync(TEntity source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - var key = _fsql.GetEntityKeyString(source); - EntityState state = new EntityState(); - if (string.IsNullOrEmpty(key)) { - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - _ctx.ExecCommand(); - var idtval = await this.OrmInsert(source).ExecuteIdentityAsync(); - _ctx._affrows++; - _fsql.SetEntityIdentityValue(source, idtval); - } else { - _ctx.ExecCommand(); - state.Value = (await this.OrmInsert(source).ExecuteInsertedAsync()).First(); - _ctx._affrows++; - _fsql.CopyEntityValue(source, state.Value); - } - break; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - _ctx.ExecCommand(); - var idtval = await this.OrmInsert(source).ExecuteIdentityAsync(); - _ctx._affrows++; - _fsql.SetEntityIdentityValue(source, idtval); - } else { - throw new Exception($"DbSet.Add 失败,未设置主键的值,或者没有配置自增,或者自增列数不为1:{_fsql.GetEntityString(source)}"); - } - break; - } - - state.Key = key = _fsql.GetEntityKeyString(source); - state.Time = DateTime.Now; - } else { - if (_vals.ContainsKey(key)) - throw new Exception($"DbSet.Add 失败,实体数据已存在,请勿重复添加:{_fsql.GetEntityString(source)}"); - _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Insert, this, typeof(EntityState), state); - } - if (state.Value == null) { - state.Value = Activator.CreateInstance(); - _fsql.CopyEntityValue(state.Value, source); //copy, 记录旧值版本 - } - _vals.Add(key, state); - } - async public Task AddRangeAsync(TEntity[] source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - for (var a = 0; a < source.Length; a++) - await AddAsync(source[a]); - } - async public Task AddRangeAsync(IEnumerable source) { - if (source == null) throw new ArgumentNullException(nameof(source)); - foreach (var item in source) - await AddAsync(item); - } - - Task DbContextBetchUpdateAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, false); - Task DbContextBetchUpdateNowAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, true); - async Task DbContextBetchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) { - if (ups.Any() == false) return 0; - var uplst1 = ups[ups.Length - 1]; - var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; - - if (_vals.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; - var lstval2 = default(EntityState); - if (uplst2 != null && _vals.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"DbSet.Update 失败,实体应该先查询再修改:{_fsql.GetEntityString(uplst2.Value)}"); - - var cuig1 = _fsql.CompareEntityValueReturnColumns(uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(uplst2.Value, lstval2.Value, true) : null; - if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { - //最后一个不保存 - var source = ups.ToList(); - source.RemoveAt(ups.Length - 1); - var affrows = await this.OrmUpdate(null).SetSource(source.Select(a => a.Value)).IgnoreColumns(cuig2).ExecuteAffrowsAsync(); - foreach (var newval in source) { - if (_vals.TryGetValue(newval.Key, out var tryold)) - _fsql.CopyEntityValue(tryold.Value, newval.Value); - } - return affrows; - } else if (isLiveUpdate) { - //立即保存 - var source = ups; - var affrows = await this.OrmUpdate(null).SetSource(source.Select(a => a.Value)).IgnoreColumns(cuig1).ExecuteAffrowsAsync(); - foreach (var newval in source) { - if (_vals.TryGetValue(newval.Key, out var tryold)) - _fsql.CopyEntityValue(tryold.Value, newval.Value); - } - return Math.Min(ups.Length, affrows); - } - //等待下次对比再保存 - return 0; - } - async Task DbContextBetchRemoveAsync(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); - //foreach (var del in dels) - // _vals.Remove(del.Key); - return affrows; - } - } -} + \ No newline at end of file diff --git a/FreeSql.DbContext/DbSetSync.cs b/FreeSql.DbContext/DbSetSync.cs new file mode 100644 index 00000000..acc92a75 --- /dev/null +++ b/FreeSql.DbContext/DbSetSync.cs @@ -0,0 +1,216 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; +using FreeSql.Extensions; + +namespace FreeSql { + partial class DbSet { + + int DbContextBetchAdd(EntityState[] adds) { + if (adds.Any() == false) return 0; + var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); + return affrows; + } + + #region Add + void AddPriv(TEntity source, bool isCheck) { + if (isCheck && CanAdd(source, true) == false) return; + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { + _ctx.ExecCommand(); + var idtval = this.OrmInsert(source).ExecuteIdentity(); + _ctx._affrows++; + _fsql.SetEntityIdentityValueWithPrimary(source, idtval); + var state = CreateEntityState(source); + _states.Add(state.Key, state); + } else { + _ctx.ExecCommand(); + var newval = this.OrmInsert(source).ExecuteInserted().First(); + _ctx._affrows++; + _fsql.MapEntityValue(newval, source); + var state = CreateEntityState(newval); + _states.Add(state.Key, state); + } + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { + _ctx.ExecCommand(); + var idtval = this.OrmInsert(source).ExecuteIdentity(); + _ctx._affrows++; + _fsql.SetEntityIdentityValueWithPrimary(source, idtval); + var state = CreateEntityState(source); + _states.Add(state.Key, state); + } + return; + } + } else { + //进入队列,等待 SaveChanges 时执行 + _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Insert, this, typeof(EntityState), CreateEntityState(source)); + } + } + public void Add(TEntity source) => AddPriv(source, true); + #endregion + + #region AddRange + public void AddRange(TEntity[] data) { + if (CanAdd(data, true) == false) return; + if (data.Length == 1) { + Add(data.First()); + return; + } + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + _ctx.ExecCommand(); + var rets = this.OrmInsert(data).ExecuteInserted(); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + var idx = 0; + foreach (var s in data) + _fsql.MapEntityValue(rets[idx++], s); + _ctx._affrows += rets.Count; + TrackToList(rets); + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + foreach (var s in data) + AddPriv(s, false); + return; + } + } else { + //进入队列,等待 SaveChanges 时执行 + foreach (var s in data) + _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Insert, this, typeof(EntityState), CreateEntityState(s)); + } + } + public void AddRange(IEnumerable data) { + if (CanAdd(data, true) == false) return; + if (data.ElementAtOrDefault(1) == default(TEntity)) { + Add(data.First()); + return; + } + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + _ctx.ExecCommand(); + var rets = this.OrmInsert(data).ExecuteInserted(); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + var idx = 0; + foreach(var s in data) + _fsql.MapEntityValue(rets[idx++], s); + _ctx._affrows += rets.Count; + TrackToList(rets); + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + foreach (var s in data) + AddPriv(s, false); + return; + } + } else { + //进入队列,等待 SaveChanges 时执行 + foreach (var s in data) + _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Insert, this, typeof(EntityState), CreateEntityState(s)); + } + } + #endregion + + int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); + int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); + int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) { + if (ups.Any() == false) return 0; + var uplst1 = ups[ups.Length - 1]; + var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; + + if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; + var lstval2 = default(EntityState); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(uplst2.Value)}"); + + var cuig1 = _fsql.CompareEntityValueReturnColumns(uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(uplst2.Value, lstval2.Value, true) : null; + if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { + //最后一个不保存 + var data = ups.ToList(); + data.RemoveAt(ups.Length - 1); + var affrows = this.OrmUpdate(null).SetSource(data.Select(a => a.Value)).IgnoreColumns(cuig2).ExecuteAffrows(); + foreach (var newval in data) { + if (_states.TryGetValue(newval.Key, out var tryold)) + _fsql.MapEntityValue(newval.Value, tryold.Value); + } + return affrows; + } else if (isLiveUpdate) { + //立即保存 + var data = ups; + var affrows = this.OrmUpdate(null).SetSource(data.Select(a => a.Value)).IgnoreColumns(cuig1).ExecuteAffrows(); + foreach (var newval in data) { + if (_states.TryGetValue(newval.Key, out var tryold)) + _fsql.MapEntityValue(newval.Value, tryold.Value); + } + return Math.Min(ups.Length, affrows); + } + //等待下次对比再保存 + return 0; + } + + void UpdatePriv(TEntity data, bool isCheck) { + if (isCheck && CanUpdate(data, true) == false) return; + _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Update, this, typeof(EntityState), CreateEntityState(data)); + } + public void Update(TEntity data) => UpdatePriv(data, true); + public void UpdateRange(TEntity[] data) { + if (CanUpdate(data, true) == false) return; + foreach (var item in data) + UpdatePriv(item, false); + } + public void UpdateRange(IEnumerable data) { + if (CanUpdate(data, true) == false) return; + foreach (var item in data) + UpdatePriv(item, false); + } + + int DbContextBetchRemove(EntityState[] dels) { + if (dels.Any() == false) return 0; + var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); + return affrows; + } + void RemovePriv(TEntity data, bool isCheck) { + if (isCheck && CanRemove(data, true) == false) return; + var state = CreateEntityState(data); + _ctx.EnqueueAction(DbContext.ExecCommandInfoType.Delete, this, typeof(EntityState), state); + + _states.Remove(state.Key); + _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(data); + } + public void Remove(TEntity data) => RemovePriv(data, true); + public void RemoveRange(TEntity[] data) { + if (CanRemove(data, true) == false) return; + foreach (var item in data) + RemovePriv(item, false); + } + public void RemoveRange(IEnumerable data) { + if (CanRemove(data, true) == false) return; + foreach (var item in data) + RemovePriv(item, false); + } + } +} diff --git a/FreeSql.DbContext/EntityUtil.cs b/FreeSql.DbContext/EntityUtil.cs index fc4c2931..02b328dc 100644 --- a/FreeSql.DbContext/EntityUtil.cs +++ b/FreeSql.DbContext/EntityUtil.cs @@ -1,5 +1,4 @@ -using FreeSql.Internal.Model; -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -17,7 +16,7 @@ namespace FreeSql.Extensions { static ConcurrentDictionary>> _dicGetEntityKeyString = new ConcurrentDictionary>>(); /// - /// 获取实体的主键值,以 "*|_,[,_|*" 分割 + /// 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值,返回 null /// /// /// @@ -40,7 +39,7 @@ namespace FreeSql.Extensions { for (var a = 0; a < pks.Length; a++) { exps.Add( Expression.IfThen( - Expression.Equal(var3IsNull, Expression.Constant(false)), + Expression.IsFalse(var3IsNull), Expression.IfThenElse( Expression.Equal(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Default(pks[a].CsType)), Expression.Assign(var3IsNull, Expression.Constant(true)), @@ -58,7 +57,7 @@ namespace FreeSql.Extensions { } exps.Add( Expression.IfThen( - Expression.Equal(var3IsNull, Expression.Constant(false)), + Expression.IsFalse(var3IsNull), Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)) ) ); @@ -83,43 +82,31 @@ namespace FreeSql.Extensions { var parm1 = Expression.Parameter(typeof(object)); var var1Parm = Expression.Variable(t); var var2Sb = Expression.Variable(typeof(StringBuilder)); - var var3IsNull = Expression.Variable(typeof(bool)); var exps = new List(new Expression[] { Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), Expression.Assign(var2Sb, Expression.New(typeof(StringBuilder))), - Expression.Assign(var3IsNull, Expression.Constant(false)), Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant("(" )) }); var a = 0; foreach (var col in cols.Values) { exps.Add( - Expression.IfThen( - Expression.Equal(var3IsNull, Expression.Constant(false)), - Expression.IfThenElse( - Expression.Equal(Expression.MakeMemberAccess(var1Parm, _table.Properties[col.CsName]), Expression.Default(col.CsType)), - Expression.Assign(var3IsNull, Expression.Constant(true)), - Expression.Block( - new Expression[]{ - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(", " )) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[col.CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() + Expression.Block( + new Expression[]{ + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(", " )) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[col.CsName]), typeof(object)) ) - ) + }.Where(c => c != null).ToArray() ) ); a++; } exps.AddRange(new Expression[] { Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(")" )), - Expression.IfThen( - Expression.Equal(var3IsNull, Expression.Constant(false)), - Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)) - ) + Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)), + Expression.Label(returnTarget, Expression.Default(typeof(string))) }); - exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(string)))); - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb, var3IsNull }, exps), new[] { parm1 }).Compile(); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb }, exps), new[] { parm1 }).Compile(); }); return func(item); } @@ -128,7 +115,7 @@ namespace FreeSql.Extensions { /// 使用新实体的值,复盖旧实体的值 /// static ConcurrentDictionary>> _dicCopyNewValueToEntity = new ConcurrentDictionary>>(); - public static void CopyEntityValue(this IFreeSql orm, TEntity oldValue, TEntity newValue) { + public static void MapEntityValue(this IFreeSql orm, TEntity from, TEntity to) { var func = _dicCopyNewValueToEntity.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { var _table = orm.CodeFirst.GetTableByEntity(t); var parm1 = Expression.Parameter(typeof(object)); @@ -143,14 +130,14 @@ namespace FreeSql.Extensions { if (_table.ColumnsByCs.ContainsKey(prop.Name)) { exps.Add( Expression.Assign( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.MakeMemberAccess(var2Parm, prop) + Expression.MakeMemberAccess(var2Parm, prop), + Expression.MakeMemberAccess(var1Parm, prop) ) ); } else { exps.Add( Expression.Assign( - Expression.MakeMemberAccess(var1Parm, prop), + Expression.MakeMemberAccess(var2Parm, prop), Expression.Default(prop.PropertyType) ) ); @@ -158,19 +145,19 @@ namespace FreeSql.Extensions { } return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); }); - func(oldValue, newValue); + func(from, to); } - static ConcurrentDictionary>> _dicSetEntityIdentityValue = new ConcurrentDictionary>>(); + static ConcurrentDictionary>> _dicSetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); /// - /// 设置实体的自增字段值(若存在) + /// 设置实体中主键内的自增字段值(若存在) /// /// /// /// /// - public static void SetEntityIdentityValue(this IFreeSql orm, TEntity item, long idtval) { - var func = _dicSetEntityIdentityValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity item, long idtval) { + var func = _dicSetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { var _table = orm.CodeFirst.GetTableByEntity(t); var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); var parm1 = Expression.Parameter(typeof(object)); @@ -179,11 +166,12 @@ namespace FreeSql.Extensions { var exps = new List(new Expression[] { Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) }); - foreach (var pk in identitys) { + if (identitys.Any()) { + var idts0 = identitys.First(); exps.Add( Expression.Assign( - Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), - Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pk.CsType, Expression.Convert(parm2, typeof(object))), pk.CsType) + Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), + Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(idts0.CsType, Expression.Convert(parm2, typeof(object))), idts0.CsType) ) ); } @@ -191,6 +179,49 @@ namespace FreeSql.Extensions { }); func(item, idtval); } + static ConcurrentDictionary>> _dicGetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); + /// + /// 获取实体中主键内的自增字段值(若存在) + /// + /// + /// + /// + public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity item) { + var func = _dicGetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + var _table = orm.CodeFirst.GetTableByEntity(t); + var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); + + + var returnTarget = Expression.Label(typeof(long)); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + if (identitys.Any()) { + var idts0 = identitys.First(); + exps.Add( + Expression.IfThen( + Expression.NotEqual( + Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), + Expression.Default(idts0.CsType) + ), + Expression.Return( + returnTarget, + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression( + typeof(long), + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), typeof(object)) + ) + ) + ) + ); + } + exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(long)))); + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); + }); + return func(item); + } + static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentityAndGuid = new ConcurrentDictionary>>(); /// /// 清除实体的主键值,将自增、Guid类型的主键值清除 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ecbf65d4..784e8259 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.23 + 0.3.24 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 36036318..1ce52e7a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.23 + 0.3.24 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index da288d3e..406ba4e9 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -25,16 +25,16 @@ namespace FreeSql.Tests.MySql { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0), (?Clicks1, ?Title1, ?CreateTime1), (?Clicks2, ?Title2, ?CreateTime2), (?Clicks3, ?Title3, ?CreateTime3), (?Clicks4, ?Title4, ?CreateTime4), (?Clicks5, ?Title5, ?CreateTime5), (?Clicks6, ?Title6, ?CreateTime6), (?Clicks7, ?Title7, ?CreateTime7), (?Clicks8, ?Title8, ?CreateTime8), (?Clicks9, ?Title9, ?CreateTime9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title0), (?Title1), (?Title2), (?Title3), (?Title4), (?Title5), (?Title6), (?Title7), (?Title8), (?Title9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); } [Fact] @@ -43,10 +43,10 @@ namespace FreeSql.Tests.MySql { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title0), (?Title1), (?Title2), (?Title3), (?Title4), (?Title5), (?Title6), (?Title7), (?Title8), (?Title9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); } [Fact] public void IgnoreColumns() { @@ -54,10 +54,10 @@ namespace FreeSql.Tests.MySql { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks0), (?Clicks1), (?Clicks2), (?Clicks3), (?Clicks4), (?Clicks5), (?Clicks6), (?Clicks7), (?Clicks8), (?Clicks9)", sql); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); } [Fact] public void ExecuteAffrows() { @@ -88,28 +88,28 @@ namespace FreeSql.Tests.MySql { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0), (?Clicks1, ?Title1, ?CreateTime1), (?Clicks2, ?Title2, ?CreateTime2), (?Clicks3, ?Title3, ?CreateTime3), (?Clicks4, ?Title4, ?CreateTime4), (?Clicks5, ?Title5, ?CreateTime5), (?Clicks6, ?Title6, ?CreateTime6), (?Clicks7, ?Title7, ?CreateTime7), (?Clicks8, ?Title8, ?CreateTime8), (?Clicks9, ?Title9, ?CreateTime9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title0), (?Title1), (?Title2), (?Title3), (?Title4), (?Title5), (?Title6), (?Title7), (?Title8), (?Title9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title0), (?Title1), (?Title2), (?Title3), (?Title4), (?Title5), (?Title6), (?Title7), (?Title8), (?Title9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(?Clicks0), (?Clicks1), (?Clicks2), (?Clicks3), (?Clicks4), (?Clicks5), (?Clicks6), (?Clicks7), (?Clicks8), (?Clicks9)", sql); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); } } } diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index b873092d..df3d3c0a 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -665,6 +665,8 @@ namespace FreeSql.Tests.MySql { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) .ToList(a => new { a.Key.tt2, cou1 = a.Count(), diff --git a/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index 6b2db7e9..331a9703 100644 --- a/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -26,51 +26,51 @@ namespace FreeSql.Tests.Oracle { var data = new List(); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks0, :Title0, :CreateTime0)", sql); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); sql = insert.AppendData(items).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks0, :Title0, :CreateTime0) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks1, :Title1, :CreateTime1) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks2, :Title2, :CreateTime2) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks3, :Title3, :CreateTime3) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks4, :Title4, :CreateTime4) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks5, :Title5, :CreateTime5) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks6, :Title6, :CreateTime6) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks7, :Title7, :CreateTime7) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks8, :Title8, :CreateTime8) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks9, :Title9, :CreateTime9) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_0, :Title_0, :CreateTime_0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_1, :Title_1, :CreateTime_1) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_2, :Title_2, :CreateTime_2) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_3, :Title_3, :CreateTime_3) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_4, :Title_4, :CreateTime_4) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_5, :Title_5, :CreateTime_5) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_6, :Title_6, :CreateTime_6) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_7, :Title_7, :CreateTime_7) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_8, :Title_8, :CreateTime_8) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_9, :Title_9, :CreateTime_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title0) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title1) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title2) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title3) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title4) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title5) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title6) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title7) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title8) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title9) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_0) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_1) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_2) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_3) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_4) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_5) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_6) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_7) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_8) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks0, :Title0) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks1, :Title1) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks2, :Title2) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks3, :Title3) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks4, :Title4) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks5, :Title5) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks6, :Title6) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks7, :Title7) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks8, :Title8) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); } @@ -83,31 +83,31 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) var data = new List(); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title0) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title1) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title2) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title3) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title4) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title5) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title6) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title7) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title8) -INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title9) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_0) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_1) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_2) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_3) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_4) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_5) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_6) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_7) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_8) +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks0, :Title0) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks1, :Title1) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks2, :Title2) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks3, :Title3) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks4, :Title4) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks5, :Title5) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks6, :Title6) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks7, :Title7) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks8, :Title8) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); } @@ -119,31 +119,31 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) var data = new List(); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks0, :Title0) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks1, :Title1) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks2, :Title2) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks3, :Title3) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks4, :Title4) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks5, :Title5) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks6, :Title6) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks7, :Title7) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks8, :Title8) -INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); Assert.Equal(@"INSERT ALL -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks0) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks1) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks2) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks3) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks4) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks5) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks6) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks7) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks8) -INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks9) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_1) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_2) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_3) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_4) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_5) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_6) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_7) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_8) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); } @@ -176,104 +176,104 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks9) for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks0, :Title0, :CreateTime0)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks0, :Title0, :CreateTime0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks1, :Title1, :CreateTime1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks2, :Title2, :CreateTime2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks3, :Title3, :CreateTime3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks4, :Title4, :CreateTime4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks5, :Title5, :CreateTime5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks6, :Title6, :CreateTime6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks7, :Title7, :CreateTime7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks8, :Title8, :CreateTime8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks9, :Title9, :CreateTime9) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_0, :Title_0, :CreateTime_0) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_1, :Title_1, :CreateTime_1) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_2, :Title_2, :CreateTime_2) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_3, :Title_3, :CreateTime_3) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_4, :Title_4, :CreateTime_4) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_5, :Title_5, :CreateTime_5) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_6, :Title_6, :CreateTime_6) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_7, :Title_7, :CreateTime_7) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_8, :Title_8, :CreateTime_8) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_9, :Title_9, :CreateTime_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title0) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title1) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title2) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title3) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title4) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title5) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title6) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title7) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title8) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title9) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_0) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_1) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_2) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_3) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_4) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_5) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_6) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_7) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_8) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks0, :Title0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks1, :Title1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks2, :Title2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks3, :Title3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks4, :Title4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks5, :Title5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks6, :Title6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks7, :Title7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks8, :Title8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title0) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title1) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title2) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title3) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title4) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title5) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title6) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title7) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title8) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title9) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_0) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_1) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_2) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_3) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_4) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_5) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_6) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_7) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_8) +INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks0, :Title0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks1, :Title1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks2, :Title2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks3, :Title3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks4, :Title4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks5, :Title5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks6, :Title6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks7, :Title7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks8, :Title8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks0, :Title0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks1, :Title1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks2, :Title2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks3, :Title3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks4, :Title4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks5, :Title5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks6, :Title6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks7, :Title7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks8, :Title8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks9, :Title9) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks0) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks1) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks2) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks3) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks4) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks5) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks6) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks7) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks8) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks9) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_0) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_1) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_2) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_3) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_4) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_5) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_6) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_7) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_8) +INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_9) SELECT 1 FROM DUAL", sql); } } diff --git a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 011e8375..6babd1b3 100644 --- a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -577,6 +577,8 @@ namespace FreeSql.Tests.Oracle { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) .ToList(a => new { a.Key.tt2, cou1 = a.Count(), diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index 0e4a74f6..b9de2ad9 100644 --- a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -25,16 +25,16 @@ namespace FreeSql.Tests.PostgreSQL { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks0, @title0, @createtime0)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks0, @title0, @createtime0), (@clicks1, @title1, @createtime1), (@clicks2, @title2, @createtime2), (@clicks3, @title3, @createtime3), (@clicks4, @title4, @createtime4), (@clicks5, @title5, @createtime5), (@clicks6, @title6, @createtime6), (@clicks7, @title7, @createtime7), (@clicks8, @title8, @createtime8), (@clicks9, @title9, @createtime9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title0), (@title1), (@title2), (@title3), (@title4), (@title5), (@title6), (@title7), (@title8), (@title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks0, @title0), (@clicks1, @title1), (@clicks2, @title2), (@clicks3, @title3), (@clicks4, @title4), (@clicks5, @title5), (@clicks6, @title6), (@clicks7, @title7), (@clicks8, @title8), (@clicks9, @title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); } [Fact] @@ -43,10 +43,10 @@ namespace FreeSql.Tests.PostgreSQL { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title0), (@title1), (@title2), (@title3), (@title4), (@title5), (@title6), (@title7), (@title8), (@title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks0, @title0), (@clicks1, @title1), (@clicks2, @title2), (@clicks3, @title3), (@clicks4, @title4), (@clicks5, @title5), (@clicks6, @title6), (@clicks7, @title7), (@clicks8, @title8), (@clicks9, @title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); } [Fact] public void IgnoreColumns() { @@ -54,10 +54,10 @@ namespace FreeSql.Tests.PostgreSQL { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks0, @title0), (@clicks1, @title1), (@clicks2, @title2), (@clicks3, @title3), (@clicks4, @title4), (@clicks5, @title5), (@clicks6, @title6), (@clicks7, @title7), (@clicks8, @title8), (@clicks9, @title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@clicks0), (@clicks1), (@clicks2), (@clicks3), (@clicks4), (@clicks5), (@clicks6), (@clicks7), (@clicks8), (@clicks9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); } [Fact] public void ExecuteAffrows() { @@ -88,28 +88,28 @@ namespace FreeSql.Tests.PostgreSQL { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks0, @title0, @createtime0)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks0, @title0, @createtime0), (@clicks1, @title1, @createtime1), (@clicks2, @title2, @createtime2), (@clicks3, @title3, @createtime3), (@clicks4, @title4, @createtime4), (@clicks5, @title5, @createtime5), (@clicks6, @title6, @createtime6), (@clicks7, @title7, @createtime7), (@clicks8, @title8, @createtime8), (@clicks9, @title9, @createtime9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title0), (@title1), (@title2), (@title3), (@title4), (@title5), (@title6), (@title7), (@title8), (@title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks0, @title0), (@clicks1, @title1), (@clicks2, @title2), (@clicks3, @title3), (@clicks4, @title4), (@clicks5, @title5), (@clicks6, @title6), (@clicks7, @title7), (@clicks8, @title8), (@clicks9, @title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title0), (@title1), (@title2), (@title3), (@title4), (@title5), (@title6), (@title7), (@title8), (@title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks0, @title0), (@clicks1, @title1), (@clicks2, @title2), (@clicks3, @title3), (@clicks4, @title4), (@clicks5, @title5), (@clicks6, @title6), (@clicks7, @title7), (@clicks8, @title8), (@clicks9, @title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks0, @title0), (@clicks1, @title1), (@clicks2, @title2), (@clicks3, @title3), (@clicks4, @title4), (@clicks5, @title5), (@clicks6, @title6), (@clicks7, @title7), (@clicks8, @title8), (@clicks9, @title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\") VALUES(@clicks0), (@clicks1), (@clicks2), (@clicks3), (@clicks4), (@clicks5), (@clicks6), (@clicks7), (@clicks8), (@clicks9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); } } } diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index cdd16a15..b0bd6fff 100644 --- a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -645,6 +645,8 @@ namespace FreeSql.Tests.PostgreSQL { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) .ToList(a => new { a.Key.tt2, cou1 = a.Count(), diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index a4263c55..3b47f1f1 100644 --- a/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -35,16 +35,16 @@ namespace FreeSql.Tests.SqlServer { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] @@ -53,10 +53,10 @@ namespace FreeSql.Tests.SqlServer { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] public void IgnoreColumns() { @@ -64,10 +64,10 @@ namespace FreeSql.Tests.SqlServer { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql); + Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); } [Fact] public void ExecuteAffrows() { @@ -111,28 +111,28 @@ namespace FreeSql.Tests.SqlServer { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); } } } diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 4cd41797..03fe8af7 100644 --- a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -579,6 +579,8 @@ namespace FreeSql.Tests.SqlServer { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) .ToList(a => new { a.Key.tt2, cou1 = a.Count(), diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs index 3d9bb90c..c400746d 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs @@ -25,16 +25,16 @@ namespace FreeSql.Tests.Sqlite { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks0, @Title0, @CreateTime0)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] @@ -43,10 +43,10 @@ namespace FreeSql.Tests.Sqlite { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] public void IgnoreColumns() { @@ -54,10 +54,10 @@ namespace FreeSql.Tests.Sqlite { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\") VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); } [Fact] public void ExecuteAffrows() { @@ -84,28 +84,28 @@ namespace FreeSql.Tests.Sqlite { for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks0, @Title0, @CreateTime0)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\") VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); } } } diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 8b27d70e..991e0694 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -506,6 +506,8 @@ namespace FreeSql.Tests.Sqlite { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) .ToList(a => new { a.Key.tt2, cou1 = a.Count(), diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 94076037..70640e14 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.23 + 0.3.24 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 830080ef..c33ac859 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -43,6 +43,40 @@ namespace FreeSql { /// 选择列 /// string ToSql(Expression, TReturn>> select); + + + /// + /// 查询向后偏移行数 + /// + /// + /// + ISelectGrouping Skip(int offset); + /// + /// 查询向后偏移行数 + /// + /// 行数 + /// + ISelectGrouping Offset(int offset); + /// + /// 查询多少条数据 + /// + /// + /// + ISelectGrouping Limit(int limit); + /// + /// 查询多少条数据 + /// + /// + /// + ISelectGrouping Take(int limit); + + /// + /// 分页 + /// + /// 第几页 + /// 每页多少 + /// + ISelectGrouping Page(int pageIndex, int pageSize); } public interface ISelectGroupingAggregate { diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 1171a532..3b71b20b 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -30,6 +30,14 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + protected void ClearData() { + _source.Clear(); + _where.Clear(); + _whereTimes = 0; + _params.Clear(); + } + + public IDelete WithTransaction(DbTransaction transaction) { _transaction = transaction; return this; @@ -38,12 +46,16 @@ namespace FreeSql.Internal.CommonProvider { public int ExecuteAffrows() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params.ToArray()); + var affrows = _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params.ToArray()); + this.ClearData(); + return affrows; } async public Task ExecuteAffrowsAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params.ToArray()); + var affrows = await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params.ToArray()); + this.ClearData(); + return affrows; } public abstract List ExecuteDeleted(); public abstract Task> ExecuteDeletedAsync(); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index c33a0d9e..7b9dc92f 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -32,6 +32,12 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + protected void ClearData() { + _source.Clear(); + _ignore.Clear(); + _params = null; + } + public IInsert WithTransaction(DbTransaction transaction) { _transaction = transaction; return this; @@ -267,8 +273,16 @@ namespace FreeSql.Internal.CommonProvider { } #endregion - internal int RawExecuteAffrows() => _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, ToSql(), _params); - internal Task RawExecuteAffrowsAsync() => _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, ToSql(), _params); + internal int RawExecuteAffrows() { + var affrows = _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, ToSql(), _params); + this.ClearData(); + return affrows; + } + async internal Task RawExecuteAffrowsAsync() { + var affrows = await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, ToSql(), _params); + this.ClearData(); + return affrows; + } internal abstract long RawExecuteIdentity(); internal abstract Task RawExecuteIdentityAsync(); internal abstract List RawExecuteInserted(); @@ -331,8 +345,8 @@ namespace FreeSql.Internal.CommonProvider { if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.CsType, val)); else { - sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val); + sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.CsType, val); } ++colidx2; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index a1fecc2d..2e07e6f3 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -79,5 +79,25 @@ namespace FreeSql.Internal.CommonProvider { var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } + + public ISelectGrouping Skip(int offset) { + var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) }); + method.Invoke(_select, new object[] { offset }); + return this; + } + public ISelectGrouping Offset(int offset) => this.Skip(offset); + + public ISelectGrouping Limit(int limit) { + var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) }); + method.Invoke(_select, new object[] { limit }); + return this; + } + public ISelectGrouping Take(int limit) => this.Limit(limit); + + public ISelectGrouping Page(int pageIndex, int pageSize) { + var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) }); + method.Invoke(_select, new object[] { pageIndex, pageSize }); + return this; + } } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index ad372f53..79402cc5 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -35,6 +35,15 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + protected void ClearData() { + _source.Clear(); + _ignore.Clear(); + _where.Clear(); + _set.Clear(); + _params.Clear(); + _paramsSource.Clear(); + } + public IUpdate WithTransaction(DbTransaction transaction) { _transaction = transaction; return this; @@ -47,12 +56,16 @@ namespace FreeSql.Internal.CommonProvider { public int ExecuteAffrows() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); + var affrows = _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return affrows; } async public Task ExecuteAffrowsAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); + var affrows = await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return affrows; } public abstract List ExecuteUpdated(); public abstract Task> ExecuteUpdatedAsync(); diff --git a/FreeSql/MySql/Curd/MySqlDelete.cs b/FreeSql/MySql/Curd/MySqlDelete.cs index 0710db42..ec055aec 100644 --- a/FreeSql/MySql/Curd/MySqlDelete.cs +++ b/FreeSql/MySql/Curd/MySqlDelete.cs @@ -24,7 +24,9 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + this.ClearData(); + return ret; } async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -39,7 +41,9 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + this.ClearData(); + return ret; } } } diff --git a/FreeSql/MySql/Curd/MySqlInsert.cs b/FreeSql/MySql/Curd/MySqlInsert.cs index 8c2da2ba..1b520285 100644 --- a/FreeSql/MySql/Curd/MySqlInsert.cs +++ b/FreeSql/MySql/Curd/MySqlInsert.cs @@ -23,13 +23,17 @@ namespace FreeSql.MySql.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } async internal override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } internal override List RawExecuteInserted() { var sql = this.ToSql(); @@ -44,7 +48,9 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); + this.ClearData(); + return ret; } async internal override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -59,7 +65,9 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); + this.ClearData(); + return ret; } } } diff --git a/FreeSql/MySql/Curd/MySqlUpdate.cs b/FreeSql/MySql/Curd/MySqlUpdate.cs index 32d6a7a0..a647a68d 100644 --- a/FreeSql/MySql/Curd/MySqlUpdate.cs +++ b/FreeSql/MySql/Curd/MySqlUpdate.cs @@ -27,7 +27,9 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return ret; } async public override Task> ExecuteUpdatedAsync() { var sql = this.ToSql(); @@ -42,7 +44,9 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return ret; } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { diff --git a/FreeSql/Oracle/Curd/OracleInsert.cs b/FreeSql/Oracle/Curd/OracleInsert.cs index eda29036..cc69deb6 100644 --- a/FreeSql/Oracle/Curd/OracleInsert.cs +++ b/FreeSql/Oracle/Curd/OracleInsert.cs @@ -69,8 +69,8 @@ namespace FreeSql.Oracle.Curd { if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.CsType, val)); else { - sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val); + sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.CsType, val); } ++colidx2; } @@ -95,7 +95,9 @@ namespace FreeSql.Oracle.Curd { var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter; identParam.Direction = ParameterDirection.Output; _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray()); - return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } async internal override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -109,7 +111,9 @@ namespace FreeSql.Oracle.Curd { var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter; identParam.Direction = ParameterDirection.Output; await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray()); - return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } internal override List RawExecuteInserted() { @@ -117,6 +121,7 @@ namespace FreeSql.Oracle.Curd { if (string.IsNullOrEmpty(sql)) return new List(); this.ExecuteAffrows(); + this.ClearData(); return _source; } async internal override Task> RawExecuteInsertedAsync() { @@ -124,6 +129,7 @@ namespace FreeSql.Oracle.Curd { if (string.IsNullOrEmpty(sql)) return new List(); await this.ExecuteAffrowsAsync(); + this.ClearData(); return _source; } } diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs index e6692912..4a0cf9df 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs @@ -24,7 +24,9 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + this.ClearData(); + return ret; } async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -39,7 +41,9 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + this.ClearData(); + return ret; } } } diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs index b36e0987..31222f59 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs @@ -29,7 +29,9 @@ namespace FreeSql.PostgreSQL.Curd { _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params); return 0; } - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } async internal override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -40,7 +42,9 @@ namespace FreeSql.PostgreSQL.Curd { await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params); return 0; } - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } internal override List RawExecuteInserted() { @@ -56,7 +60,9 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); + this.ClearData(); + return ret; } async internal override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -71,7 +77,9 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); + this.ClearData(); + return ret; } } } diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs index 2528837b..b183b173 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -27,7 +27,9 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return ret; } async public override Task> ExecuteUpdatedAsync() { var sql = this.ToSql(); @@ -42,7 +44,9 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return ret; } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { diff --git a/FreeSql/SqlServer/Curd/SqlServerDelete.cs b/FreeSql/SqlServer/Curd/SqlServerDelete.cs index 1fb86696..bcb72a98 100644 --- a/FreeSql/SqlServer/Curd/SqlServerDelete.cs +++ b/FreeSql/SqlServer/Curd/SqlServerDelete.cs @@ -30,7 +30,9 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + this.ClearData(); + return ret; } async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -50,7 +52,9 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); + this.ClearData(); + return ret; } } } diff --git a/FreeSql/SqlServer/Curd/SqlServerInsert.cs b/FreeSql/SqlServer/Curd/SqlServerInsert.cs index 6932bf93..20c197a9 100644 --- a/FreeSql/SqlServer/Curd/SqlServerInsert.cs +++ b/FreeSql/SqlServer/Curd/SqlServerInsert.cs @@ -26,13 +26,17 @@ namespace FreeSql.SqlServer.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } async internal override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } internal override List RawExecuteInserted() { @@ -53,7 +57,9 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); + this.ClearData(); + return ret; } async internal override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -73,7 +79,9 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); + this.ClearData(); + return ret; } } } \ No newline at end of file diff --git a/FreeSql/SqlServer/Curd/SqlServerInsert2100.cs b/FreeSql/SqlServer/Curd/SqlServerInsert2100.cs deleted file mode 100644 index 2d129b81..00000000 --- a/FreeSql/SqlServer/Curd/SqlServerInsert2100.cs +++ /dev/null @@ -1,281 +0,0 @@ -//using FreeSql.Internal; -//using System; -//using System.Collections.Generic; -//using System.Data; -//using System.Data.Common; -//using System.Linq; -//using System.Text; -//using System.Threading.Tasks; - -//namespace FreeSql.SqlServer.Curd { - -// class SqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class { -// public SqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) -// : base(orm, commonUtils, commonExpression) { -// } - -// public override int ExecuteAffrows() { -// var sql = this.ToSql2100(); -// switch (sql.Count) { -// case 0: return 0; -// case 1: return _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql[0].Item1, sql[0].Item2); -// default: -// var affrows = 0; -// if (_transaction == null) { -// using (var conn = _orm.Ado.MasterPool.Get()) { -// var tran = conn.Value.BeginTransaction(); -// try { -// foreach (var s in sql) -// affrows += _orm.Ado.ExecuteNonQuery(tran, CommandType.Text, s.Item1, s.Item2); -// tran.Commit(); -// } catch { -// tran.Rollback(); -// } -// } -// } else { -// foreach (var s in sql) -// affrows += _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, s.Item1, s.Item2); -// } -// return affrows; -// } -// } -// async public override Task ExecuteAffrowsAsync() { -// var sql = this.ToSql2100(); -// switch (sql.Count) { -// case 0: return 0; -// case 1: return await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql[0].Item1, sql[0].Item2); -// default: -// var affrows = 0; -// if (_transaction == null) { -// using (var conn = await _orm.Ado.MasterPool.GetAsync()) { -// var tran = conn.Value.BeginTransaction(); -// try { -// foreach (var s in sql) -// affrows += await _orm.Ado.ExecuteNonQueryAsync(tran, CommandType.Text, s.Item1, s.Item2); -// tran.Commit(); -// } catch { -// tran.Rollback(); -// } -// } -// } else { -// foreach (var s in sql) -// affrows += await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, s.Item1, s.Item2); -// } -// return affrows; -// } -// } - -// public override long ExecuteIdentity() { -// var sql = this.ToSql2100(); -// switch (sql.Count) { -// case 0: return 0; -// case 1: -// if (string.IsNullOrEmpty(sql[0].Item1)) return 0; -// return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql[0].Item1, "; SELECT SCOPE_IDENTITY();"), sql[0].Item2)), out var trylng) ? trylng : 0; -// default: -// long ret = 0; -// if (_transaction == null) { -// using (var conn = _orm.Ado.MasterPool.Get()) { -// var tran = conn.Value.BeginTransaction(); -// try { -// for (var a = 0; a < sql.Count; a++) { -// var s = sql[a]; -// if (a < sql.Count - 1) _orm.Ado.ExecuteNonQuery(tran, CommandType.Text, s.Item1, s.Item2); -// else ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(tran, CommandType.Text, string.Concat(s.Item1, "; SELECT SCOPE_IDENTITY();"), s.Item2)), out trylng) ? trylng : 0; -// } -// tran.Commit(); -// } catch { -// tran.Rollback(); -// } -// } -// } else { -// for (var a = 0; a < sql.Count; a++) { -// var s = sql[a]; -// if (a < sql.Count - 1) _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, s.Item1, s.Item2); -// else ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(s.Item1, "; SELECT SCOPE_IDENTITY();"), s.Item2)), out trylng) ? trylng : 0; -// } -// } -// return ret; -// } -// } -// async public override Task ExecuteIdentityAsync() { -// var sql = this.ToSql2100(); -// switch (sql.Count) { -// case 0: return 0; -// case 1: -// if (string.IsNullOrEmpty(sql[0].Item1)) return 0; -// return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql[0].Item1, "; SELECT SCOPE_IDENTITY();"), sql[0].Item2)), out var trylng) ? trylng : 0; -// default: -// long ret = 0; -// if (_transaction == null) { -// using (var conn = await _orm.Ado.MasterPool.GetAsync()) { -// var tran = conn.Value.BeginTransaction(); -// try { -// for (var a = 0; a < sql.Count; a++) { -// var s = sql[a]; -// if (a < sql.Count - 1) await _orm.Ado.ExecuteNonQueryAsync(tran, CommandType.Text, s.Item1, s.Item2); -// else ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(tran, CommandType.Text, string.Concat(s.Item1, "; SELECT SCOPE_IDENTITY();"), s.Item2)), out trylng) ? trylng : 0; -// } -// tran.Commit(); -// } catch { -// tran.Rollback(); -// } -// } -// } else { -// for (var a = 0; a < sql.Count; a++) { -// var s = sql[a]; -// if (a < sql.Count - 1) await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, s.Item1, s.Item2); -// else ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(s.Item1, "; SELECT SCOPE_IDENTITY();"), s.Item2)), out trylng) ? trylng : 0; -// } -// } -// return ret; -// } -// } - -// public override List ExecuteInserted() { -// string output = null; -// Func getOutputSql = oldsql => { -// if (string.IsNullOrEmpty(output)) { -// 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.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); -// ++colidx; -// } -// output = sb.ToString(); -// } -// var validx = oldsql.IndexOf(") VALUES"); -// if (validx == -1) throw new ArgumentException("找不到 VALUES"); -// var newsql = new StringBuilder().Append(output); -// newsql.Insert(0, oldsql.Substring(0, validx + 1)); -// newsql.Append(oldsql.Substring(validx + 1)); -// return newsql.ToString(); -// }; - -// var sql = this.ToSql2100(); -// switch (sql.Count) { -// case 0: return new List(); -// case 1: -// if (string.IsNullOrEmpty(sql[0].Item1)) return new List(); -// return _orm.Ado.Query(_transaction, CommandType.Text, getOutputSql(sql[0].Item1), sql[0].Item2); -// default: -// var ret = new List(); -// if (_transaction == null) { -// using (var conn = _orm.Ado.MasterPool.Get()) { -// var tran = conn.Value.BeginTransaction(); -// try { -// foreach (var s in sql) -// ret.AddRange(_orm.Ado.Query(tran, CommandType.Text, getOutputSql(s.Item1), s.Item2)); -// tran.Commit(); -// } catch { -// tran.Rollback(); -// } -// } -// } else { -// foreach (var s in sql) -// ret.AddRange(_orm.Ado.Query(_transaction, CommandType.Text, getOutputSql(s.Item1), s.Item2)); -// } -// return ret; -// } -// } -// async public override Task> ExecuteInsertedAsync() { -// string output = null; -// Func getOutputSql = oldsql => { -// if (string.IsNullOrEmpty(output)) { -// 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.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); -// ++colidx; -// } -// output = sb.ToString(); -// } -// var validx = oldsql.IndexOf(") VALUES"); -// if (validx == -1) throw new ArgumentException("找不到 VALUES"); -// var newsql = new StringBuilder().Append(output); -// newsql.Insert(0, oldsql.Substring(0, validx + 1)); -// newsql.Append(oldsql.Substring(validx + 1)); -// return oldsql; -// }; - -// var sql = this.ToSql2100(); -// switch (sql.Count) { -// case 0: return new List(); -// case 1: -// if (string.IsNullOrEmpty(sql[0].Item1)) return new List(); -// return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, getOutputSql(sql[0].Item1), sql[0].Item2); -// default: -// var ret = new List(); -// if (_transaction == null) { -// using (var conn = await _orm.Ado.MasterPool.GetAsync()) { -// var tran = conn.Value.BeginTransaction(); -// try { -// foreach (var s in sql) -// ret.AddRange(await _orm.Ado.QueryAsync(tran, CommandType.Text, getOutputSql(s.Item1), s.Item2)); -// tran.Commit(); -// } catch { -// tran.Rollback(); -// } -// } -// } else { -// foreach (var s in sql) -// ret.AddRange(await _orm.Ado.QueryAsync(_transaction, CommandType.Text, getOutputSql(s.Item1), s.Item2)); -// } -// return ret; -// } -// } - -// public List<(string, DbParameter[])> ToSql2100() { //传入的请求具有过多的参数。该服务器支持最多 2100 个参数。请减少参数的数目,然后重新发送该请求。 -// if (_source == null || _source.Any() == false) return new List<(string, DbParameter[])>(); -// var ret = new List<(string, DbParameter[])>(); -// var sbhead = new StringBuilder(); -// sbhead.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); -// var colidx = 0; -// foreach (var col in _table.Columns.Values) -// if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) { -// if (colidx > 0) sbhead.Append(", "); -// sbhead.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); -// ++colidx; -// } -// sbhead.Append(") VALUES"); -// var sbh = sbhead.ToString(); - -// var sbsql = new StringBuilder().Append(sbh); -// var sbsqlParams = new List(); -// var didx = 0; -// foreach (var d in _source) { -// if ((didx + 1) * colidx >= 2100) { -// ret.Add((sbsql.ToString(), sbsqlParams.ToArray())); -// sbsql.Clear().Append(sbh); -// sbsqlParams.Clear(); -// didx = 0; -// } - -// if (sbsqlParams.Count > 0) sbsql.Append(", "); -// sbsql.Append("("); -// var colidx2 = 0; -// foreach (var col in _table.Columns.Values) -// if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) { -// if (colidx2 > 0) sbsql.Append(", "); -// sbsql.Append(_commonUtils.QuoteWriteParamter(col.CsType, $"{_commonUtils.QuoteParamterName(col.CsName)}{didx}")); -// object val = null; -// if (_table.Properties.TryGetValue(col.CsName, out var tryp)) { -// val = tryp.GetValue(d); -// if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?)) -// && (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId()); -// } -// sbsqlParams.Add(_commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val)); -// ++colidx2; -// } -// sbsql.Append(")"); -// ++didx; -// } -// ret.Add((sbsql.ToString(), sbsqlParams.ToArray())); -// return ret; -// } -// } -//} diff --git a/FreeSql/SqlServer/Curd/SqlServerUpdate.cs b/FreeSql/SqlServer/Curd/SqlServerUpdate.cs index fdfd9b78..74075a97 100644 --- a/FreeSql/SqlServer/Curd/SqlServerUpdate.cs +++ b/FreeSql/SqlServer/Curd/SqlServerUpdate.cs @@ -33,7 +33,9 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + var ret = _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return ret; } async public override Task> ExecuteUpdatedAsync() { var sql = this.ToSql(); @@ -53,7 +55,9 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + var ret = await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + this.ClearData(); + return ret; } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { diff --git a/FreeSql/Sqlite/Curd/SqliteInsert.cs b/FreeSql/Sqlite/Curd/SqliteInsert.cs index 84d6eef9..810e794f 100644 --- a/FreeSql/Sqlite/Curd/SqliteInsert.cs +++ b/FreeSql/Sqlite/Curd/SqliteInsert.cs @@ -25,19 +25,24 @@ namespace FreeSql.Sqlite.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } async internal override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; + var id = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; + this.ClearData(); + return id; } internal override List RawExecuteInserted() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); this.ExecuteAffrows(); + this.ClearData(); return _source; } async internal override Task> RawExecuteInsertedAsync() { @@ -45,6 +50,7 @@ namespace FreeSql.Sqlite.Curd { if (string.IsNullOrEmpty(sql)) return new List(); await this.ExecuteAffrowsAsync(); + this.ClearData(); return _source; } }