mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 增加 IUpdate.Join 联表更新功能;
This commit is contained in:
parent
39bb327022
commit
a6c1981bd6
@ -528,7 +528,7 @@ namespace base_entity
|
|||||||
//.UseSlaveWeight(10, 1, 1, 5)
|
//.UseSlaveWeight(10, 1, 1, 5)
|
||||||
|
|
||||||
|
|
||||||
//.UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5")
|
.UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5")
|
||||||
//.UseQuoteSqlName(false)
|
//.UseQuoteSqlName(false)
|
||||||
|
|
||||||
//.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=2")
|
//.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=2")
|
||||||
@ -569,6 +569,15 @@ namespace base_entity
|
|||||||
#endregion
|
#endregion
|
||||||
fsql.UseJsonMap();
|
fsql.UseJsonMap();
|
||||||
|
|
||||||
|
var updatejoin01 = fsql.Update<User1>()
|
||||||
|
.Join(fsql.Select<UserGroup>(), (a, b) => a.GroupId == b.Id)
|
||||||
|
.Set((a, b) => a.Nickname == b.GroupName)
|
||||||
|
.ExecuteAffrows();
|
||||||
|
var updatejoin02 = fsql.Update<User1>()
|
||||||
|
.Join<UserGroup>((a, b) => a.GroupId == b.Id)
|
||||||
|
.Set((a, b) => a.Nickname == b.GroupName)
|
||||||
|
.ExecuteAffrows();
|
||||||
|
|
||||||
fsql.Select<User1>().IncludeMany(a => a.Roles);
|
fsql.Select<User1>().IncludeMany(a => a.Roles);
|
||||||
|
|
||||||
var displayNameTb = fsql.CodeFirst.GetTableByEntity(typeof(DeviceCodes));
|
var displayNameTb = fsql.CodeFirst.GetTableByEntity(typeof(DeviceCodes));
|
||||||
|
@ -800,14 +800,5 @@
|
|||||||
<param name="that"></param>
|
<param name="that"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
|
|
||||||
<summary>
|
|
||||||
批量注入 Repository,可以参考代码自行调整
|
|
||||||
</summary>
|
|
||||||
<param name="services"></param>
|
|
||||||
<param name="globalDataFilter"></param>
|
|
||||||
<param name="assemblies"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
@ -2871,6 +2871,33 @@
|
|||||||
所有元素
|
所有元素
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdate`1.Join``1(FreeSql.ISelect{``0},System.Linq.Expressions.Expression{System.Func{`0,``0,System.Boolean}})">
|
||||||
|
<summary>
|
||||||
|
联表更新(危险操作),支持更复杂的联表更新<para></para>
|
||||||
|
fsql.Update<T1>()<para></para>
|
||||||
|
.Join(fsql.Select<T1>(), (a, b) => a.id == b.id)<para></para>
|
||||||
|
.Set((a, b) => a.name == b.name)<para></para>
|
||||||
|
.Set((a, b) => a.time == b.time2)<para></para>
|
||||||
|
.ExecuteAffrows();
|
||||||
|
</summary>
|
||||||
|
<typeparam name="T2"></typeparam>
|
||||||
|
<param name="query"></param>
|
||||||
|
<param name="on"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdate`1.Join``1(System.Linq.Expressions.Expression{System.Func{`0,``0,System.Boolean}})">
|
||||||
|
<summary>
|
||||||
|
联表更新(危险操作)<para></para>
|
||||||
|
fsql.Update<T1>()<para></para>
|
||||||
|
.Join<T2>((a, b) => a.id == b.id)<para></para>
|
||||||
|
.Set((a, b) => a.name == b.name)<para></para>
|
||||||
|
.Set((a, b) => a.time == b.time2)<para></para>
|
||||||
|
.ExecuteAffrows();
|
||||||
|
</summary>
|
||||||
|
<typeparam name="T2"></typeparam>
|
||||||
|
<param name="on"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:FreeSql.IUpdate`1.WithTransaction(System.Data.Common.DbTransaction)">
|
<member name="M:FreeSql.IUpdate`1.WithTransaction(System.Data.Common.DbTransaction)">
|
||||||
<summary>
|
<summary>
|
||||||
指定事务对象
|
指定事务对象
|
||||||
@ -3003,7 +3030,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:FreeSql.IUpdate`1.Set``1(System.Linq.Expressions.Expression{System.Func{`0,``0}})">
|
<member name="M:FreeSql.IUpdate`1.Set``1(System.Linq.Expressions.Expression{System.Func{`0,``0}})">
|
||||||
<summary>
|
<summary>
|
||||||
设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
设置列的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
||||||
<para></para>
|
<para></para>
|
||||||
指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
||||||
</summary>
|
</summary>
|
||||||
@ -3013,7 +3040,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:FreeSql.IUpdate`1.SetIf``1(System.Boolean,System.Linq.Expressions.Expression{System.Func{`0,``0}})">
|
<member name="M:FreeSql.IUpdate`1.SetIf``1(System.Boolean,System.Linq.Expressions.Expression{System.Func{`0,``0}})">
|
||||||
<summary>
|
<summary>
|
||||||
设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
设置列的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
||||||
<para></para>
|
<para></para>
|
||||||
指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
||||||
</summary>
|
</summary>
|
||||||
@ -3136,6 +3163,125 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.WithTransaction(System.Data.Common.DbTransaction)">
|
||||||
|
<summary>
|
||||||
|
指定事务对象
|
||||||
|
</summary>
|
||||||
|
<param name="transaction"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.WithConnection(System.Data.Common.DbConnection)">
|
||||||
|
<summary>
|
||||||
|
指定事务对象
|
||||||
|
</summary>
|
||||||
|
<param name="connection"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.CommandTimeout(System.Int32)">
|
||||||
|
<summary>
|
||||||
|
命令超时设置(秒)
|
||||||
|
</summary>
|
||||||
|
<param name="timeout"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.Set``1(System.Linq.Expressions.Expression{System.Func{`0,``0}},``0)">
|
||||||
|
<summary>
|
||||||
|
设置列的固定新值,Set(a => a.Name, "newvalue")
|
||||||
|
</summary>
|
||||||
|
<typeparam name="TMember"></typeparam>
|
||||||
|
<param name="column">lambda选择列</param>
|
||||||
|
<param name="value">新值</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.SetIf``1(System.Boolean,System.Linq.Expressions.Expression{System.Func{`0,``0}},``0)">
|
||||||
|
<summary>
|
||||||
|
设置列的固定新值,Set(a => a.Name, "newvalue")
|
||||||
|
</summary>
|
||||||
|
<typeparam name="TMember"></typeparam>
|
||||||
|
<param name="condition">true 时生效</param>
|
||||||
|
<param name="column">lambda选择列</param>
|
||||||
|
<param name="value">新值</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.Set(System.Linq.Expressions.Expression{System.Func{`0,`1,System.Boolean}})">
|
||||||
|
<summary>
|
||||||
|
设置列的联表值,格式:<para></para>
|
||||||
|
Set((a, b) => a.Clicks == b.xxx)<para></para>
|
||||||
|
Set((a, b) => a.Clicks == a.Clicks + 1)
|
||||||
|
</summary>
|
||||||
|
<param name="exp"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.SetIf(System.Boolean,System.Linq.Expressions.Expression{System.Func{`0,`1,System.Boolean}})">
|
||||||
|
<summary>
|
||||||
|
设置列的联表值,格式:<para></para>
|
||||||
|
Set((a, b) => a.Clicks == b.xxx)<para></para>
|
||||||
|
Set((a, b) => a.Clicks == a.Clicks + 1)
|
||||||
|
<para></para>
|
||||||
|
</summary>
|
||||||
|
<param name="condition">true 时生效</param>
|
||||||
|
<param name="exp"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.SetRaw(System.String,System.Object)">
|
||||||
|
<summary>
|
||||||
|
设置值,自定义SQL语法,SetRaw("title = @title", new { title = "newtitle" })<para></para>
|
||||||
|
提示:parms 参数还可以传 Dictionary<string, object>
|
||||||
|
</summary>
|
||||||
|
<param name="sql">sql语法</param>
|
||||||
|
<param name="parms">参数</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.Where(System.Linq.Expressions.Expression{System.Func{`0,`1,System.Boolean}})">
|
||||||
|
<summary>
|
||||||
|
lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||||
|
</summary>
|
||||||
|
<param name="exp">lambda表达式条件</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.WhereIf(System.Boolean,System.Linq.Expressions.Expression{System.Func{`0,`1,System.Boolean}})">
|
||||||
|
<summary>
|
||||||
|
lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||||
|
</summary>
|
||||||
|
<param name="condition">true 时生效</param>
|
||||||
|
<param name="exp">lambda表达式条件</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.Where(System.String,System.Object)">
|
||||||
|
<summary>
|
||||||
|
原生sql语法条件,Where("id = @id", new { id = 1 })<para></para>
|
||||||
|
提示:parms 参数还可以传 Dictionary<string, object>
|
||||||
|
</summary>
|
||||||
|
<param name="sql">sql语法条件</param>
|
||||||
|
<param name="parms">参数</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.DisableGlobalFilter(System.String[])">
|
||||||
|
<summary>
|
||||||
|
禁用全局过滤功能,不传参数时将禁用所有
|
||||||
|
</summary>
|
||||||
|
<param name="name">零个或多个过滤器名字</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.AsTable(System.String)">
|
||||||
|
<summary>
|
||||||
|
设置表名
|
||||||
|
</summary>
|
||||||
|
<param name="tableName"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.ToSql">
|
||||||
|
<summary>
|
||||||
|
返回即将执行的SQL语句
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.IUpdateJoin`2.ExecuteAffrows">
|
||||||
|
<summary>
|
||||||
|
执行SQL语句,返回影响的行数
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="P:FreeSql.IAdo.MasterPool">
|
<member name="P:FreeSql.IAdo.MasterPool">
|
||||||
<summary>
|
<summary>
|
||||||
主库连接池
|
主库连接池
|
||||||
|
@ -10,6 +10,31 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
public interface IUpdate<T1>
|
public interface IUpdate<T1>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 联表更新(危险操作),支持更复杂的联表更新<para></para>
|
||||||
|
/// fsql.Update<T1>()<para></para>
|
||||||
|
/// .Join(fsql.Select<T1>(), (a, b) => a.id == b.id)<para></para>
|
||||||
|
/// .Set((a, b) => a.name == b.name)<para></para>
|
||||||
|
/// .Set((a, b) => a.time == b.time2)<para></para>
|
||||||
|
/// .ExecuteAffrows();
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T2"></typeparam>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <param name="on"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> Join<T2>(ISelect<T2> query, Expression<Func<T1, T2, bool>> on) where T2 : class;
|
||||||
|
/// <summary>
|
||||||
|
/// 联表更新(危险操作)<para></para>
|
||||||
|
/// fsql.Update<T1>()<para></para>
|
||||||
|
/// .Join<T2>((a, b) => a.id == b.id)<para></para>
|
||||||
|
/// .Set((a, b) => a.name == b.name)<para></para>
|
||||||
|
/// .Set((a, b) => a.time == b.time2)<para></para>
|
||||||
|
/// .ExecuteAffrows();
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T2"></typeparam>
|
||||||
|
/// <param name="on"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> Join<T2>(Expression<Func<T1, T2, bool>> on) where T2 : class;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 指定事务对象
|
/// 指定事务对象
|
||||||
@ -134,7 +159,7 @@ namespace FreeSql
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IUpdate<T1> SetIf<TMember>(bool condition, Expression<Func<T1, TMember>> column, TMember value);
|
IUpdate<T1> SetIf<TMember>(bool condition, Expression<Func<T1, TMember>> column, TMember value);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
/// 设置列的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
||||||
/// <para></para>
|
/// <para></para>
|
||||||
/// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
/// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -143,7 +168,7 @@ namespace FreeSql
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IUpdate<T1> Set<TMember>(Expression<Func<T1, TMember>> exp);
|
IUpdate<T1> Set<TMember>(Expression<Func<T1, TMember>> exp);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
/// 设置列的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1
|
||||||
/// <para></para>
|
/// <para></para>
|
||||||
/// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
/// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....'
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
127
FreeSql/Interface/Curd/IUpdateJoin.cs
Normal file
127
FreeSql/Interface/Curd/IUpdateJoin.cs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql
|
||||||
|
{
|
||||||
|
public interface IUpdateJoin<T1, T2>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 指定事务对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transaction"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> WithTransaction(DbTransaction transaction);
|
||||||
|
/// <summary>
|
||||||
|
/// 指定事务对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> WithConnection(DbConnection connection);
|
||||||
|
/// <summary>
|
||||||
|
/// 命令超时设置(秒)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeout"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> CommandTimeout(int timeout);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置列的固定新值,Set(a => a.Name, "newvalue")
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TMember"></typeparam>
|
||||||
|
/// <param name="column">lambda选择列</param>
|
||||||
|
/// <param name="value">新值</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> Set<TMember>(Expression<Func<T1, TMember>> column, TMember value);
|
||||||
|
/// <summary>
|
||||||
|
/// 设置列的固定新值,Set(a => a.Name, "newvalue")
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TMember"></typeparam>
|
||||||
|
/// <param name="condition">true 时生效</param>
|
||||||
|
/// <param name="column">lambda选择列</param>
|
||||||
|
/// <param name="value">新值</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> SetIf<TMember>(bool condition, Expression<Func<T1, TMember>> column, TMember value);
|
||||||
|
/// <summary>
|
||||||
|
/// 设置列的联表值,格式:<para></para>
|
||||||
|
/// Set((a, b) => a.Clicks == b.xxx)<para></para>
|
||||||
|
/// Set((a, b) => a.Clicks == a.Clicks + 1)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exp"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> Set(Expression<Func<T1, T2, bool>> exp);
|
||||||
|
/// <summary>
|
||||||
|
/// 设置列的联表值,格式:<para></para>
|
||||||
|
/// Set((a, b) => a.Clicks == b.xxx)<para></para>
|
||||||
|
/// Set((a, b) => a.Clicks == a.Clicks + 1)
|
||||||
|
/// <para></para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="condition">true 时生效</param>
|
||||||
|
/// <param name="exp"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> SetIf(bool condition, Expression<Func<T1, T2, bool>> exp);
|
||||||
|
/// <summary>
|
||||||
|
/// 设置值,自定义SQL语法,SetRaw("title = @title", new { title = "newtitle" })<para></para>
|
||||||
|
/// 提示:parms 参数还可以传 Dictionary<string, object>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sql">sql语法</param>
|
||||||
|
/// <param name="parms">参数</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> SetRaw(string sql, object parms = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exp">lambda表达式条件</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> Where(Expression<Func<T1, T2, bool>> exp);
|
||||||
|
/// <summary>
|
||||||
|
/// lambda表达式条件,仅支持实体基础成员(不包含导航对象)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="condition">true 时生效</param>
|
||||||
|
/// <param name="exp">lambda表达式条件</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> WhereIf(bool condition, Expression<Func<T1, T2, bool>> exp);
|
||||||
|
/// <summary>
|
||||||
|
/// 原生sql语法条件,Where("id = @id", new { id = 1 })<para></para>
|
||||||
|
/// 提示:parms 参数还可以传 Dictionary<string, object>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sql">sql语法条件</param>
|
||||||
|
/// <param name="parms">参数</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> Where(string sql, object parms = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用全局过滤功能,不传参数时将禁用所有
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">零个或多个过滤器名字</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> DisableGlobalFilter(params string[] name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置表名
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IUpdateJoin<T1, T2> AsTable(string tableName);
|
||||||
|
/// <summary>
|
||||||
|
/// 返回即将执行的SQL语句
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
string ToSql();
|
||||||
|
/// <summary>
|
||||||
|
/// 执行SQL语句,返回影响的行数
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
int ExecuteAffrows();
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
306
FreeSql/Internal/CommonProvider/UpdateJoinProvider.cs
Normal file
306
FreeSql/Internal/CommonProvider/UpdateJoinProvider.cs
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
using FreeSql;
|
||||||
|
using FreeSql.Extensions.EntityUtil;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using FreeSql.Internal.ObjectPool;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql.Internal.CommonProvider
|
||||||
|
{
|
||||||
|
public class UpdateJoinProvider<T1, T2> : IUpdateJoin<T1, T2> where T1 : class where T2 : class
|
||||||
|
{
|
||||||
|
public IUpdate<T1> _update;
|
||||||
|
public UpdateProvider<T1> _updateProvider;
|
||||||
|
public ISelect<T2> _query;
|
||||||
|
public Select0Provider _queryProvider;
|
||||||
|
public ISelect<T1, T2> _query2;
|
||||||
|
public Select2Provider<T1, T2> _query2Provider;
|
||||||
|
|
||||||
|
public IFreeSql _orm;
|
||||||
|
public CommonUtils _commonUtils;
|
||||||
|
public CommonExpression _commonExpression;
|
||||||
|
public string _joinOn;
|
||||||
|
public string _tableName;
|
||||||
|
|
||||||
|
public UpdateJoinProvider(IUpdate<T1> update, ISelect<T2> query, Expression<Func<T1, T2, bool>> on)
|
||||||
|
{
|
||||||
|
_update = update;
|
||||||
|
_updateProvider = _update as UpdateProvider<T1>;
|
||||||
|
_orm = _updateProvider._orm;
|
||||||
|
_commonUtils = _updateProvider._commonUtils;
|
||||||
|
_commonExpression = _updateProvider._commonExpression;
|
||||||
|
|
||||||
|
ValidateDataType(null, null, null, null, null);
|
||||||
|
_query = query;
|
||||||
|
_queryProvider = _query as Select0Provider;
|
||||||
|
_query2 = _orm.Select<T1>().DisableGlobalFilter().FromQuery(_query);
|
||||||
|
_query2Provider = _query2 as Select2Provider<T1, T2>;
|
||||||
|
|
||||||
|
_query2Provider._where.Clear();
|
||||||
|
_query2.Where(on);
|
||||||
|
_joinOn = _query2Provider._where.ToString();
|
||||||
|
if (_joinOn.StartsWith(" AND ")) _joinOn = _joinOn.Substring(5);
|
||||||
|
|
||||||
|
_updateProvider.Where("1=1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ValidateDataType(Action InterceptSqlServer, Action InterceptMySql, Action InterceptPostgreSQL, Action InterceptMergeInto, Action InterceptGBase)
|
||||||
|
{
|
||||||
|
switch (_orm.Ado.DataType)
|
||||||
|
{
|
||||||
|
case DataType.SqlServer:
|
||||||
|
case DataType.OdbcSqlServer:
|
||||||
|
case DataType.CustomSqlServer:
|
||||||
|
InterceptSqlServer?.Invoke(); break;
|
||||||
|
case DataType.MySql:
|
||||||
|
case DataType.OdbcMySql:
|
||||||
|
case DataType.CustomMySql:
|
||||||
|
case DataType.MsAccess:
|
||||||
|
InterceptMySql?.Invoke(); break;
|
||||||
|
case DataType.PostgreSQL:
|
||||||
|
case DataType.OdbcPostgreSQL:
|
||||||
|
case DataType.CustomPostgreSQL:
|
||||||
|
case DataType.KingbaseES:
|
||||||
|
case DataType.OdbcKingbaseES:
|
||||||
|
case DataType.ShenTong:
|
||||||
|
InterceptPostgreSQL?.Invoke(); break;
|
||||||
|
case DataType.Oracle:
|
||||||
|
case DataType.OdbcOracle:
|
||||||
|
case DataType.CustomOracle:
|
||||||
|
case DataType.Dameng:
|
||||||
|
case DataType.OdbcDameng:
|
||||||
|
case DataType.Firebird:
|
||||||
|
InterceptMergeInto?.Invoke(); break;
|
||||||
|
case DataType.GBase:
|
||||||
|
InterceptGBase?.Invoke(); break;
|
||||||
|
|
||||||
|
default: throw new Exception($"{_orm.Ado.DataType} 暂时不支持 update join 操作。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region proxy IUpdate
|
||||||
|
public IUpdateJoin<T1, T2> AsTable(string tableName)
|
||||||
|
{
|
||||||
|
_update.AsTable(tableName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> WithConnection(DbConnection connection)
|
||||||
|
{
|
||||||
|
_update.WithConnection(connection);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUpdateJoin<T1, T2> WithTransaction(DbTransaction transaction)
|
||||||
|
{
|
||||||
|
_update.WithTransaction(transaction);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> CommandTimeout(int timeout)
|
||||||
|
{
|
||||||
|
_update.CommandTimeout(timeout);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> DisableGlobalFilter(params string[] name)
|
||||||
|
{
|
||||||
|
_update.DisableGlobalFilter(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> Set<TMember>(Expression<Func<T1, TMember>> column, TMember value)
|
||||||
|
{
|
||||||
|
_update.Set(column, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> SetIf<TMember>(bool condition, Expression<Func<T1, TMember>> column, TMember value)
|
||||||
|
{
|
||||||
|
_update.SetIf(condition, column, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> SetRaw(string sql, object parms = null)
|
||||||
|
{
|
||||||
|
_update.SetRaw(sql, parms);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public IUpdateJoin<T1, T2> Where(string sql, object parms = null)
|
||||||
|
{
|
||||||
|
_update.Where(sql, parms);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public IUpdateJoin<T1, T2> Where(Expression<Func<T1, T2, bool>> exp) => WhereIf(true, exp);
|
||||||
|
public IUpdateJoin<T1, T2> WhereIf(bool condition, Expression<Func<T1, T2, bool>> exp)
|
||||||
|
{
|
||||||
|
if (condition == false) return this;
|
||||||
|
_query2Provider._where.Clear();
|
||||||
|
_query2.Where(exp);
|
||||||
|
_updateProvider._where.Append(_query2Provider._where);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUpdateJoin<T1, T2> Set(Expression<Func<T1, T2, bool>> exp) => SetIf(true, exp);
|
||||||
|
public IUpdateJoin<T1, T2> SetIf(bool condition, Expression<Func<T1, T2, bool>> exp)
|
||||||
|
{
|
||||||
|
var body = exp?.Body;
|
||||||
|
var nodeType = body?.NodeType;
|
||||||
|
if (nodeType == ExpressionType.Convert)
|
||||||
|
{
|
||||||
|
body = (body as UnaryExpression)?.Operand;
|
||||||
|
nodeType = body?.NodeType;
|
||||||
|
}
|
||||||
|
switch (nodeType)
|
||||||
|
{
|
||||||
|
case ExpressionType.Equal:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("格式错了,请使用 .Set((a,b) => a.name == b.xname)");
|
||||||
|
}
|
||||||
|
|
||||||
|
var equalBinaryExp = body as BinaryExpression;
|
||||||
|
var cols = new List<SelectColumnInfo>();
|
||||||
|
_commonExpression.ExpressionSelectColumn_MemberAccess(null, null, cols, SelectTableInfoType.From, equalBinaryExp.Left, true, null);
|
||||||
|
if (cols.Count != 1) return this;
|
||||||
|
var col = cols[0].Column;
|
||||||
|
var columnSql = $"{_commonUtils.QuoteSqlName(col.Attribute.Name)}";
|
||||||
|
|
||||||
|
_query2Provider._groupby = null;
|
||||||
|
var valueExp = Expression.Lambda<Func<T1, T2, object>>(equalBinaryExp.Right, exp.Parameters);
|
||||||
|
_query2.GroupBy(valueExp);
|
||||||
|
var valueSql = _query2Provider._groupby?.Remove(0, " \r\nGROUP BY ".Length);
|
||||||
|
if (string.IsNullOrEmpty(valueSql)) return this;
|
||||||
|
|
||||||
|
switch (_orm.Ado.DataType)
|
||||||
|
{
|
||||||
|
case DataType.PostgreSQL:
|
||||||
|
case DataType.OdbcPostgreSQL:
|
||||||
|
case DataType.CustomPostgreSQL:
|
||||||
|
case DataType.KingbaseES:
|
||||||
|
case DataType.OdbcKingbaseES:
|
||||||
|
case DataType.ShenTong:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
columnSql = $"{_query2Provider._tables[0].Alias}.{columnSql}"; //set a.name = b.name
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_update.SetRaw($"{columnSql} = {valueSql}");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterceptSql(StringBuilder sb)
|
||||||
|
{
|
||||||
|
var sql = sb.ToString();
|
||||||
|
if (!sql.StartsWith("UPDATE ")) return;
|
||||||
|
var setStartIndex = sql.IndexOf(" SET ");
|
||||||
|
if (setStartIndex == -1) return;
|
||||||
|
var sqltab = sql.Substring(7, setStartIndex - 7);
|
||||||
|
var sqlset = "";
|
||||||
|
var sqlwhere = "";
|
||||||
|
var sqltab2 = _query2Provider._tableRules.FirstOrDefault()?.Invoke(typeof(T2), null).Replace(" \r\n", " \r\n ") ?? _commonUtils.QuoteSqlName(_query2Provider._tables[1].Table?.DbName);
|
||||||
|
var whereStartIndex = sql.IndexOf(" \r\nWHERE ", setStartIndex);
|
||||||
|
if (whereStartIndex == -1)
|
||||||
|
{
|
||||||
|
sqlset = sql.Substring(setStartIndex + 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sqlset = sql.Substring(setStartIndex + 5, whereStartIndex - setStartIndex - 5);
|
||||||
|
sqlwhere = sql.Substring(whereStartIndex);
|
||||||
|
if (sqlwhere == " \r\nWHERE (1=1)")
|
||||||
|
sqlwhere = "";
|
||||||
|
else if (sqlwhere.StartsWith(" \r\nWHERE (1=1) AND "))
|
||||||
|
sqlwhere = $" \r\nWHERE {sqlwhere.Substring(" \r\nWHERE (1=1) AND ".Length)}";
|
||||||
|
}
|
||||||
|
string t0alias = _query2Provider._tables[0].Alias;
|
||||||
|
string t1alias = _query2Provider._tables[1].Alias;
|
||||||
|
|
||||||
|
ValidateDataType(InterceptSqlServer, InterceptMySql, InterceptPostgreSQL, InterceptMergeInto, InterceptGBase);
|
||||||
|
void InterceptSqlServer()
|
||||||
|
{
|
||||||
|
sb.Clear().Append("UPDATE ").Append(t0alias).Append(" SET ").Append(sqlset)
|
||||||
|
.Append(" \r\nFROM ").Append(sqltab).Append(_commonUtils.FieldAsAlias(t0alias))
|
||||||
|
.Append(" \r\nINNER JOIN ").Append(sqltab2).Append(_commonUtils.FieldAsAlias(t1alias)).Append(" ON ").Append(_joinOn)
|
||||||
|
.Append(sqlwhere);
|
||||||
|
}
|
||||||
|
void InterceptMySql()
|
||||||
|
{
|
||||||
|
sb.Clear().Append("UPDATE ").Append(sqltab).Append(_commonUtils.FieldAsAlias(t0alias))
|
||||||
|
.Append(" \r\nINNER JOIN ").Append(sqltab2).Append(_commonUtils.FieldAsAlias(t1alias)).Append(" ON ").Append(_joinOn)
|
||||||
|
.Append(" \r\nSET ").Append(sqlset)
|
||||||
|
.Append(sqlwhere);
|
||||||
|
}
|
||||||
|
void InterceptPostgreSQL()
|
||||||
|
{
|
||||||
|
sb.Clear().Append("UPDATE ").Append(sqltab).Append(_commonUtils.FieldAsAlias(t0alias))
|
||||||
|
.Append(" \r\nSET ").Append(sqlset)
|
||||||
|
.Append(" \r\nFROM ").Append(sqltab2).Append(_commonUtils.FieldAsAlias(t1alias))
|
||||||
|
.Append(sqlwhere);
|
||||||
|
if (string.IsNullOrEmpty(sqlwhere)) sb.Append(" \r\nWHERE ").Append(_joinOn);
|
||||||
|
else sb.Append(" AND ").Append(_joinOn);
|
||||||
|
}
|
||||||
|
void InterceptMergeInto()
|
||||||
|
{
|
||||||
|
sb.Clear().Append("MERGE INTO ").Append(sqltab).Append(_commonUtils.FieldAsAlias(t0alias))
|
||||||
|
.Append(" \r\nUSING ").Append(sqltab2).Append(_commonUtils.FieldAsAlias(t1alias)).Append(" ON ").Append(_joinOn)
|
||||||
|
.Append(" \r\nWHEN MATCHED THEN")
|
||||||
|
.Append(" \r\nUPDATE SET ").Append(sqlset)
|
||||||
|
.Append(sqlwhere);
|
||||||
|
}
|
||||||
|
void InterceptGBase()
|
||||||
|
{
|
||||||
|
sb.Clear().Append("UPDATE ").Append(sqltab2).Append(_commonUtils.FieldAsAlias(t1alias)).Append(", ").Append(sqltab).Append(_commonUtils.FieldAsAlias(t0alias))
|
||||||
|
.Append(" \r\nSET ").Append(sqlset)
|
||||||
|
.Append(sqlwhere);
|
||||||
|
if (string.IsNullOrEmpty(sqlwhere)) sb.Append(" \r\nWHERE ").Append(_joinOn);
|
||||||
|
else sb.Append(" AND ").Append(_joinOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToSql()
|
||||||
|
{
|
||||||
|
_updateProvider._interceptSql = InterceptSql;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _update.ToSql();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_updateProvider._interceptSql = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int ExecuteAffrows()
|
||||||
|
{
|
||||||
|
_updateProvider._interceptSql = InterceptSql;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _update.ExecuteAffrows();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_updateProvider._interceptSql = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
async public Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
_updateProvider._interceptSql = InterceptSql;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await _update.ExecuteAffrowsAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_updateProvider._interceptSql = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -188,6 +188,15 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
_ignoreVersion = false;
|
_ignoreVersion = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IUpdateJoin<T1, T2> Join<T2>(Expression<Func<T1, T2, bool>> on) where T2 : class => Join<T2>(_orm.Select<T2>(), on);
|
||||||
|
public IUpdateJoin<T1, T2> Join<T2>(ISelect<T2> query, Expression<Func<T1, T2, bool>> on) where T2 : class
|
||||||
|
{
|
||||||
|
var ctor = typeof(UpdateJoinProvider<,>).MakeGenericType(typeof(T1), typeof(T2))
|
||||||
|
.GetConstructor(new[] { typeof(IUpdate<T1>), typeof(ISelect<T2>), typeof(Expression<Func<T1, T2, bool>>) });
|
||||||
|
if (ctor == null) throw new Exception(CoreStrings.Type_Cannot_Access_Constructor("UpdateJoinProvider<>"));
|
||||||
|
return ctor.Invoke(new object[] { this, query, on }) as IUpdateJoin<T1, T2>;
|
||||||
|
}
|
||||||
|
|
||||||
public IUpdate<T1> WithTransaction(DbTransaction transaction)
|
public IUpdate<T1> WithTransaction(DbTransaction transaction)
|
||||||
{
|
{
|
||||||
_transaction = transaction;
|
_transaction = transaction;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user