mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-19 20:38:16 +08:00
- 增加 ISelect ToDelete/ToUpdate 方法,实现更复杂的删除/更新操作;
This commit is contained in:
@ -611,7 +611,8 @@
|
||||
</member>
|
||||
<member name="M:FreeSql.IDelete`1.Where(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
|
||||
<summary>
|
||||
lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||
lambda表达式条件,仅支持实体基础成员(不包含导航对象)<para></para>
|
||||
若想使用导航对象,请使用 ISelect.ToDelete() 方法
|
||||
</summary>
|
||||
<param name="exp">lambda表达式条件</param>
|
||||
<returns></returns>
|
||||
@ -870,6 +871,30 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ISelect0`2.ToDelete">
|
||||
<summary>
|
||||
将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下:<para></para>
|
||||
fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows()<para></para>
|
||||
注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行:<para></para>
|
||||
DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1)<para></para>
|
||||
复杂删除使用该方案的好处:<para></para>
|
||||
1、删除前可预览测试数据,防止错误删除操作;<para></para>
|
||||
2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作);
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ISelect0`2.ToUpdate">
|
||||
<summary>
|
||||
将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下:<para></para>
|
||||
fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows()<para></para>
|
||||
注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行:<para></para>
|
||||
UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1)<para></para>
|
||||
复杂更新使用该方案的好处:<para></para>
|
||||
1、更新前可预览测试数据,防止错误更新操作;<para></para>
|
||||
2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作);
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ISelect0`2.AsTable(System.Func{System.Type,System.String,System.String})">
|
||||
<summary>
|
||||
设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; <para></para>
|
||||
@ -1710,7 +1735,8 @@
|
||||
</member>
|
||||
<member name="M:FreeSql.IUpdate`1.Where(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
|
||||
<summary>
|
||||
lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||
lambda表达式条件,仅支持实体基础成员(不包含导航对象)<para></para>
|
||||
若想使用导航对象,请使用 ISelect.ToUpdate() 方法
|
||||
</summary>
|
||||
<param name="exp">lambda表达式条件</param>
|
||||
<returns></returns>
|
||||
|
@ -23,7 +23,8 @@ namespace FreeSql
|
||||
IDelete<T1> WithConnection(DbConnection connection);
|
||||
|
||||
/// <summary>
|
||||
/// lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||
/// lambda表达式条件,仅支持实体基础成员(不包含导航对象)<para></para>
|
||||
/// 若想使用导航对象,请使用 ISelect.ToDelete() 方法
|
||||
/// </summary>
|
||||
/// <param name="exp">lambda表达式条件</param>
|
||||
/// <returns></returns>
|
||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql
|
||||
{
|
||||
public partial interface ISelect0<TSelect, T1>
|
||||
public partial interface ISelect0<TSelect, T1> where T1 : class
|
||||
{
|
||||
|
||||
#if net40
|
||||
@ -82,6 +82,29 @@ namespace FreeSql
|
||||
/// <returns></returns>
|
||||
T1 First();
|
||||
|
||||
/// <summary>
|
||||
/// 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下:<para></para>
|
||||
/// fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows()<para></para>
|
||||
/// 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行:<para></para>
|
||||
/// DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1)<para></para>
|
||||
/// 复杂删除使用该方案的好处:<para></para>
|
||||
/// 1、删除前可预览测试数据,防止错误删除操作;<para></para>
|
||||
/// 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作);
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IDelete<T1> ToDelete();
|
||||
/// <summary>
|
||||
/// 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下:<para></para>
|
||||
/// fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows()<para></para>
|
||||
/// 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行:<para></para>
|
||||
/// UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1)<para></para>
|
||||
/// 复杂更新使用该方案的好处:<para></para>
|
||||
/// 1、更新前可预览测试数据,防止错误更新操作;<para></para>
|
||||
/// 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作);
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IUpdate<T1> ToUpdate();
|
||||
|
||||
/// <summary>
|
||||
/// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; <para></para>
|
||||
/// 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 <para></para>
|
||||
|
@ -92,7 +92,8 @@ namespace FreeSql
|
||||
IUpdate<T1> SetRaw(string sql, object parms = null);
|
||||
|
||||
/// <summary>
|
||||
/// lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||
/// lambda表达式条件,仅支持实体基础成员(不包含导航对象)<para></para>
|
||||
/// 若想使用导航对象,请使用 ISelect.ToUpdate() 方法
|
||||
/// </summary>
|
||||
/// <param name="exp">lambda表达式条件</param>
|
||||
/// <returns></returns>
|
||||
|
@ -833,6 +833,43 @@ namespace FreeSql.Internal.CommonProvider
|
||||
return (map, field.ToString());
|
||||
}
|
||||
|
||||
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 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] = 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})";
|
||||
}
|
||||
}
|
||||
public IDelete<T1> ToDelete()
|
||||
{
|
||||
if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键");
|
||||
return _orm.Delete<T1>().Where(GetToDeleteWhere("ftb_del"));
|
||||
}
|
||||
public IUpdate<T1> ToUpdate()
|
||||
{
|
||||
if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键");
|
||||
return _orm.Update<T1>().Where(GetToDeleteWhere("ftb_upd"));
|
||||
}
|
||||
|
||||
protected List<Dictionary<Type, string>> GetTableRuleUnions()
|
||||
{
|
||||
var unions = new List<Dictionary<Type, string>>();
|
||||
|
@ -297,7 +297,11 @@ namespace FreeSql.Internal
|
||||
foreach (var col in trytb.Primarys)
|
||||
col.Attribute.IsPrimary = true;
|
||||
}
|
||||
foreach (var col in trytb.Primarys) col.Attribute.IsNullable = false;
|
||||
foreach (var col in trytb.Primarys)
|
||||
{
|
||||
col.Attribute.IsNullable = false;
|
||||
col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "");
|
||||
}
|
||||
tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb);
|
||||
|
||||
#region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类
|
||||
|
Reference in New Issue
Block a user