28810 dda7c8bc9c - 增加 AsTable 和 Repository 分表时的自动迁移分表功能;
- 增加 ICodeFirst.SyncStructure(Type entityType, string tableName) 指定表名来迁移实体;
```csharp
fsql.CodeFirst.SyncStructure(typeof(Log), "Log_1"); //迁移到 Log_1 表
fsql.CodeFirst.SyncStructure(typeof(Log), "Log_2"); //迁移到 Log_2 表
```
2019-11-13 19:57:44 +08:00

159 lines
6.3 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<T1> : IDelete<T1> where T1 : class
{
protected IFreeSql _orm;
protected CommonUtils _commonUtils;
protected CommonExpression _commonExpression;
protected TableInfo _table;
protected Func<string, string> _tableRule;
protected StringBuilder _where = new StringBuilder();
protected int _whereTimes = 0;
protected List<GlobalFilter.Item> _whereGlobalFilter;
protected List<DbParameter> _params = new List<DbParameter>();
protected DbTransaction _transaction;
protected DbConnection _connection;
public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
{
_orm = orm;
_commonUtils = commonUtils;
_commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1));
this.Where(_commonUtils.WhereObject(_table, "", dywhere));
if (_orm.CodeFirst.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;
_connection = _transaction?.Connection;
return this;
}
public IDelete<T1> WithConnection(DbConnection connection)
{
if (_transaction?.Connection != connection) _transaction = null;
_connection = connection;
return this;
}
public int ExecuteAffrows()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
var dbParms = _params.ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var affrows = 0;
Exception exception = null;
try
{
affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, affrows);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return affrows;
}
public abstract List<T1> ExecuteDeleted();
public IDelete<T1> Where(Expression<Func<T1, bool>> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null));
public IDelete<T1> Where(string sql, object parms = null)
{
if (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, "", items));
public IDelete<T1> WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere));
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 (string.IsNullOrEmpty(newname)) return _table.DbName;
if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
return newname;
}
public IDelete<T1> AsTable(Func<string, string> tableRule)
{
_tableRule = tableRule;
return this;
}
public IDelete<T1> AsType(Type entityType)
{
if (entityType == typeof(object)) throw new Exception("IDelete.AsType 参数不支持指定为 object");
if (entityType == _table.Type) return this;
var newtb = _commonUtils.GetTableByEntity(entityType);
_table = newtb ?? throw new Exception("IDelete.AsType 参数错误,请传入正确的实体类型");
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
return this;
}
public string ToSql()
{
if (_whereTimes <= 0) return null;
var sb = new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" WHERE ").Append(_where);
if (_whereGlobalFilter.Any())
{
var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList());
if (string.IsNullOrEmpty(globalFilterCondi) == false)
sb.Append(" AND ").Append(globalFilterCondi);
}
return sb.ToString();
}
}
}