diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs index 402df5610..99ce54b97 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Xunit; namespace FreeSql.Tests.GBase @@ -80,9 +81,28 @@ namespace FreeSql.Tests.GBase [Fact] public void ExecuteDeleted() { - Assert.Throws(() => delete.Where(a => a.Id > 0).ExecuteDeleted()); + g.gbase.Delete().Where(a => a.Id > 0).ExecuteAffrows(); + var list = new[] { new Topic { Title = "t1" }, new Topic { Title = "t2" } }; + g.gbase.Insert().ExecuteAffrows(); + var datas = delete.Where(a => a.Id > 0).ExecuteDeleted(); + foreach (var data in datas) + { + Assert.Contains(list, it => it.Title == data.Title); + } } - + [Fact] + public async Task ExecuteDeletedAsync() + { + await g.gbase.Delete().Where(a => a.Id > 0).ExecuteAffrowsAsync(); + var list = new[] { new Topic { Title = "t1" }, new Topic { Title = "t2" } }; + var cnt = await g.gbase.Insert(list).ExecuteAffrowsAsync(); + var datas = await delete.Where(a => a.Id > 0).ExecuteDeletedAsync(); + foreach (var data in datas) + { + Assert.Contains(list, it => it.Title == data.Title); + } + } + [Fact] public void AsTable() { diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs index 3040ff3c4..41e767448 100644 --- a/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -16,11 +17,111 @@ namespace FreeSql.GBase.Curd { } - public override List ExecuteDeleted() => throw new NotImplementedException($"FreeSql.Provider.GBase {CoreErrorStrings.S_Not_Implemented_Feature}"); + public override List ExecuteDeleted() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var delSql = sb.ToString(); + var validx = delSql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException(CoreErrorStrings.S_NotFound_Name("WHERE")); + var wherePart = delSql.Substring(validx); + var selectSql = new StringBuilder() + .Append("SELECT ").Append(sbret) + .Append(" FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())) + .Append(wherePart); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, string.Concat(selectSql.ToString(), "; ", delSql, ";"), dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, selectSql.ToString(), _commandTimeout, dbParms)); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, delSql, _commandTimeout, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + return ret; + } #if net40 #else - public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException($"FreeSql.Provider.GBase {CoreErrorStrings.S_Not_Implemented_Feature}"); + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var delSql = sb.ToString(); + var validx = delSql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException(CoreErrorStrings.S_NotFound_Name("WHERE")); + var wherePart = delSql.Substring(validx); + var selectSql = new StringBuilder() + .Append("SELECT ").Append(sbret) + .Append(" FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())) + .Append(wherePart); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, string.Concat(selectSql.ToString(), "; ", delSql, ";"), dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, selectSql.ToString(), _commandTimeout, dbParms, cancellationToken)); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, delSql, _commandTimeout, dbParms, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + return ret; + } #endif } }