- 完善 AsTreeCte + ToUpdate/ToDelete 实现树所有子节点删除或更新;

This commit is contained in:
28810
2020-08-04 20:54:15 +08:00
parent 255cbf33aa
commit 18cabd22b9
24 changed files with 346 additions and 63 deletions

View File

@ -13,17 +13,18 @@ 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 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 Action<StringBuilder> _interceptSql;
public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
{
@ -155,6 +156,7 @@ namespace FreeSql.Internal.CommonProvider
if (string.IsNullOrEmpty(globalFilterCondi) == false)
sb.Append(" AND ").Append(globalFilterCondi);
}
_interceptSql?.Invoke(sb);
return sb.ToString();
}
}

View File

@ -928,43 +928,96 @@ namespace FreeSql.Internal.CommonProvider
string GetToDeleteWhere(string alias)
{
var pks = _tables[0].Table.Primarys;
if (pks.Length == 1)
return $"{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)} in (select * from ({this.ToSql($"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)}")}) {alias})";
else
var old_selectVal = _select;
switch (_orm.Ado.DataType)
{
var concatTypes = new Type[pks.Length * 2 - 1];
var concatMainCols = new string[pks.Length * 2 - 1];
var concatInCols = new string[pks.Length * 2 - 1];
var concatSplit = _commonUtils.FormatSql("{0}", $",{alias},");
for (var a = 0; a < pks.Length; a++)
case DataType.Dameng:
case DataType.OdbcDameng: //达梦不能这样
case DataType.Oracle:
case DataType.OdbcOracle:
break;
default:
_select = "SELECT ";
break;
}
try
{
if (pks.Length == 1)
return $"{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)} in (select * from ({this.ToSql($"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)}")}) {alias})";
else
{
concatTypes[a * 2] = pks[a].CsType;
concatMainCols[a * 2] = _commonUtils.QuoteSqlName(pks[a].Attribute.Name);
concatInCols[a * 2] = $"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(pks[a].Attribute.Name)}";
if (a < pks.Length - 1)
var concatTypes = new Type[pks.Length * 2 - 1];
var concatMainCols = new string[pks.Length * 2 - 1];
var concatInCols = new string[pks.Length * 2 - 1];
var concatSplit = _commonUtils.FormatSql("{0}", $",{alias},");
for (var a = 0; a < pks.Length; a++)
{
concatTypes[a * 2 + 1] = typeof(string);
concatMainCols[a * 2 + 1] = concatSplit;
concatInCols[a * 2 + 1] = concatSplit;
concatTypes[a * 2] = pks[a].CsType;
concatMainCols[a * 2] = _commonUtils.QuoteSqlName(pks[a].Attribute.Name);
concatInCols[a * 2] = $"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(pks[a].Attribute.Name)}";
if (a < pks.Length - 1)
{
concatTypes[a * 2 + 1] = typeof(string);
concatMainCols[a * 2 + 1] = concatSplit;
concatInCols[a * 2 + 1] = concatSplit;
}
}
return $"{_commonUtils.StringConcat(concatMainCols, concatTypes)} in (select * from ({this.ToSql($"{_commonUtils.StringConcat(concatInCols, concatTypes)} as as1")}) {alias})";
}
return $"{_commonUtils.StringConcat(concatMainCols, concatTypes)} in (select * from ({this.ToSql($"{_commonUtils.StringConcat(concatInCols, concatTypes)} as as1")}) {alias})";
}
finally
{
_select = old_selectVal;
}
}
public IDelete<T1> ToDelete()
{
if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键");
var del = _orm.Delete<T1>();
var del = _orm.Delete<T1>() as DeleteProvider<T1>;
if (_tables[0].Table.Type != typeof(T1)) del.AsType(_tables[0].Table.Type);
if (_params.Any()) del.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(del, new List<DbParameter>(_params.ToArray()));
switch (_orm.Ado.DataType)
{
case DataType.Dameng:
case DataType.OdbcDameng: //达梦不能这样
case DataType.Oracle:
case DataType.OdbcOracle:
break;
default:
var beforeSql = this._select;
if (beforeSql.EndsWith("SELECT ", StringComparison.OrdinalIgnoreCase))
{
beforeSql = beforeSql.Substring(0, beforeSql.Length - 7);
if (string.IsNullOrEmpty(beforeSql) == false)
del._interceptSql = sb => sb.Insert(0, beforeSql);
}
break;
}
return del.Where(GetToDeleteWhere("ftb_del"));
}
public IUpdate<T1> ToUpdate()
{
if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键");
var upd = _orm.Update<T1>();
var upd = _orm.Update<T1>() as UpdateProvider<T1>;
if (_tables[0].Table.Type != typeof(T1)) upd.AsType(_tables[0].Table.Type);
if (_params.Any()) upd.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(upd, new List<DbParameter>(_params.ToArray()));
switch (_orm.Ado.DataType)
{
case DataType.Dameng:
case DataType.OdbcDameng: //达梦不能这样
case DataType.Oracle:
case DataType.OdbcOracle:
break;
default:
var beforeSql = this._select;
if (beforeSql.EndsWith("SELECT ", StringComparison.OrdinalIgnoreCase))
{
beforeSql = beforeSql.Substring(0, beforeSql.Length - 7);
if (string.IsNullOrEmpty(beforeSql) == false)
upd._interceptSql = sb => sb.Insert(0, beforeSql);
}
break;
}
return upd.Where(GetToDeleteWhere("ftb_upd"));
}

View File

@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider
public Action<BatchProgressStatus<T1>> _batchProgress;
public DbTransaction _transaction;
public DbConnection _connection;
public Action<StringBuilder> _interceptSql;
public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
{
@ -766,6 +767,7 @@ namespace FreeSql.Internal.CommonProvider
sb.Append(" AND ").Append(versionCondi);
}
_interceptSql?.Invoke(sb);
return sb.ToString();
}
}