mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-26 20:52:50 +08:00
270 lines
11 KiB
C#
270 lines
11 KiB
C#
using FreeSql.Internal.Model;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.Common;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace FreeSql.Internal.CommonProvider
|
|
{
|
|
public abstract partial class DeleteProvider
|
|
{
|
|
public IFreeSql _orm;
|
|
public CommonUtils _commonUtils;
|
|
public CommonExpression _commonExpression;
|
|
public TableInfo _table;
|
|
public Func<string, string> _tableRule;
|
|
public StringBuilder _where = new StringBuilder();
|
|
public int _whereTimes = 0;
|
|
public List<GlobalFilter.Item> _whereGlobalFilter;
|
|
public List<DbParameter> _params = new List<DbParameter>();
|
|
public DbTransaction _transaction;
|
|
public DbConnection _connection;
|
|
public int _commandTimeout = 0;
|
|
public Action<StringBuilder> _interceptSql;
|
|
public bool _isAutoSyncStructure;
|
|
}
|
|
|
|
public abstract partial class DeleteProvider<T1> : DeleteProvider, IDelete<T1>
|
|
{
|
|
public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
|
|
{
|
|
_orm = orm;
|
|
_commonUtils = commonUtils;
|
|
_commonExpression = commonExpression;
|
|
_table = _commonUtils.GetTableByEntity(typeof(T1));
|
|
_isAutoSyncStructure = _orm.CodeFirst.IsAutoSyncStructure;
|
|
this.Where(_commonUtils.WhereObject(_table, "", dywhere));
|
|
if (_isAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
|
|
_whereGlobalFilter = _orm.GlobalFilter.GetFilters();
|
|
}
|
|
|
|
protected void ClearData()
|
|
{
|
|
_where.Clear();
|
|
_whereTimes = 0;
|
|
_params.Clear();
|
|
_whereGlobalFilter = _orm.GlobalFilter.GetFilters();
|
|
}
|
|
|
|
public IDelete<T1> WithTransaction(DbTransaction transaction)
|
|
{
|
|
_transaction = transaction;
|
|
if (transaction != null) _connection = transaction.Connection;
|
|
return this;
|
|
}
|
|
public IDelete<T1> WithConnection(DbConnection connection)
|
|
{
|
|
if (_transaction?.Connection != connection) _transaction = null;
|
|
_connection = connection;
|
|
return this;
|
|
}
|
|
public IDelete<T1> CommandTimeout(int timeout)
|
|
{
|
|
_commandTimeout = timeout;
|
|
return this;
|
|
}
|
|
|
|
public virtual int ExecuteAffrows()
|
|
{
|
|
var affrows = 0;
|
|
DbParameter[] dbParms = null;
|
|
ToSqlFetch(sb =>
|
|
{
|
|
if (dbParms == null) dbParms = _params.ToArray();
|
|
var sql = sb.ToString();
|
|
var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms);
|
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
|
|
|
Exception exception = null;
|
|
try
|
|
{
|
|
affrows += _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
exception = ex;
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
var after = new Aop.CurdAfterEventArgs(before, exception, affrows);
|
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
|
}
|
|
});
|
|
if (dbParms != null) this.ClearData();
|
|
return affrows;
|
|
}
|
|
public abstract List<T1> ExecuteDeleted();
|
|
|
|
public IDelete<T1> Where(Expression<Func<T1, bool>> exp) => WhereIf(true, exp);
|
|
public IDelete<T1> WhereIf(bool condition, Expression<Func<T1, bool>> exp)
|
|
{
|
|
if (condition == false || exp == null) return this;
|
|
return this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, _table, null, exp?.Body, null, _params));
|
|
}
|
|
public IDelete<T1> Where(string sql, object parms = null) => WhereIf(true, sql, parms);
|
|
public IDelete<T1> WhereIf(bool condition, string sql, object parms = null)
|
|
{
|
|
if (condition == false || string.IsNullOrEmpty(sql)) return this;
|
|
if (++_whereTimes > 1) _where.Append(" AND ");
|
|
_where.Append('(').Append(sql).Append(')');
|
|
if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
|
|
return this;
|
|
}
|
|
public IDelete<T1> Where(T1 item) => this.Where(new[] { item });
|
|
public IDelete<T1> Where(IEnumerable<T1> items) => this.Where(_commonUtils.WhereItems(_table.Primarys, "", items));
|
|
public IDelete<T1> WhereDynamic(object dywhere, bool not = false) => not == false ?
|
|
this.Where(_commonUtils.WhereObject(_table, "", dywhere)) :
|
|
this.Where($"not({_commonUtils.WhereObject(_table, "", dywhere)})");
|
|
public IDelete<T1> WhereDynamicFilter(DynamicFilterInfo filter)
|
|
{
|
|
var alias = "t_" + Guid.NewGuid().ToString("n").Substring(0, 8);
|
|
var tempQuery = _orm.Select<object>().AsType(_table.Type).DisableGlobalFilter().As(alias);
|
|
tempQuery.WhereDynamicFilter(filter);
|
|
var where = (tempQuery as Select0Provider)._where.ToString().Replace(alias + ".", "");
|
|
if (where.StartsWith(" AND "))
|
|
{
|
|
if (++_whereTimes == 1) _where.Append(where.Substring(5));
|
|
else _where.Append(where);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public IDelete<T1> DisableGlobalFilter(params string[] name)
|
|
{
|
|
if (_whereGlobalFilter.Any() == false) return this;
|
|
if (name?.Any() != true)
|
|
{
|
|
_whereGlobalFilter.Clear();
|
|
return this;
|
|
}
|
|
foreach (var n in name)
|
|
{
|
|
if (n == null) continue;
|
|
var idx = _whereGlobalFilter.FindIndex(a => string.Compare(a.Name, n, true) == 0);
|
|
if (idx == -1) continue;
|
|
_whereGlobalFilter.RemoveAt(idx);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
protected string TableRuleInvoke()
|
|
{
|
|
if (_tableRule == null) return _table.DbName;
|
|
var newname = _tableRule(_table.DbName);
|
|
if (newname == _table.DbName) return _table.DbName;
|
|
if (string.IsNullOrEmpty(newname)) return _table.DbName;
|
|
if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
|
|
if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
|
|
if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
|
|
return newname;
|
|
}
|
|
public IDelete<T1> AsTable(Func<string, string> tableRule)
|
|
{
|
|
_tableRule = tableRule;
|
|
return this;
|
|
}
|
|
public IDelete<T1> AsTable(string tableName)
|
|
{
|
|
_tableRule = (oldname) => tableName;
|
|
return this;
|
|
}
|
|
public IDelete<T1> AsType(Type entityType)
|
|
{
|
|
if (entityType == typeof(object)) throw new Exception(CoreStrings.TypeAsType_NotSupport_Object("IDelete"));
|
|
if (entityType == _table.Type) return this;
|
|
var newtb = _commonUtils.GetTableByEntity(entityType);
|
|
_table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IDelete"));
|
|
if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
|
|
return this;
|
|
}
|
|
|
|
public virtual string ToSql()
|
|
{
|
|
if (_whereTimes <= 0 || _where.Length == 0) return null;
|
|
var sb = new StringBuilder();
|
|
ToSqlFetch(sql =>
|
|
{
|
|
sb.Append(sql).Append("\r\n\r\n;\r\n\r\n");
|
|
});
|
|
if (sb.Length > 0) sb.Remove(sb.Length - 9, 9);
|
|
if (sb.Length == 0) return null;
|
|
return sb.ToString();
|
|
}
|
|
|
|
public void ToSqlFetch(Action<StringBuilder> fetch)
|
|
{
|
|
if (_whereTimes <= 0 || _where.Length == 0) return;
|
|
var newwhere = new StringBuilder().Append(" WHERE ").Append(_where);
|
|
|
|
if (_whereGlobalFilter.Any())
|
|
{
|
|
var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false);
|
|
if (string.IsNullOrEmpty(globalFilterCondi) == false)
|
|
newwhere.Append(" AND ").Append(globalFilterCondi);
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
|
|
{
|
|
var oldTableRule = _tableRule;
|
|
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils).Names;
|
|
foreach (var name in names)
|
|
{
|
|
_tableRule = old => name;
|
|
sb.Clear().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere);
|
|
_interceptSql?.Invoke(sb);
|
|
if (sb.Length > 0) fetch(sb);
|
|
}
|
|
_tableRule = oldTableRule;
|
|
return;
|
|
}
|
|
|
|
sb.Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere);
|
|
_interceptSql?.Invoke(sb);
|
|
fetch(sb);
|
|
sb.Clear();
|
|
}
|
|
#if net40
|
|
#else
|
|
async public Task ToSqlFetchAsync(Func<StringBuilder, Task> fetchAsync)
|
|
{
|
|
if (_whereTimes <= 0 || _where.Length == 0) return;
|
|
var newwhere = new StringBuilder().Append(" WHERE ").Append(_where);
|
|
|
|
if (_whereGlobalFilter.Any())
|
|
{
|
|
var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false);
|
|
if (string.IsNullOrEmpty(globalFilterCondi) == false)
|
|
newwhere.Append(" AND ").Append(globalFilterCondi);
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
|
|
{
|
|
var oldTableRule = _tableRule;
|
|
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils).Names;
|
|
foreach (var name in names)
|
|
{
|
|
_tableRule = old => name;
|
|
sb.Clear().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere);
|
|
_interceptSql?.Invoke(sb);
|
|
if (sb.Length > 0) await fetchAsync(sb);
|
|
}
|
|
_tableRule = oldTableRule;
|
|
return;
|
|
}
|
|
|
|
sb.Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(newwhere);
|
|
_interceptSql?.Invoke(sb);
|
|
await fetchAsync(sb);
|
|
sb.Clear();
|
|
}
|
|
#endif
|
|
}
|
|
}
|