From 0fcc5619be54b32c31d78ab7d039d363b598e4e3 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 25 Mar 2022 19:07:47 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20fsql.InsertDict/Update?= =?UTF-8?q?Dict/DeleteDict=20=E5=AD=97=E5=85=B8=E6=93=8D=E4=BD=9C=E7=9A=84?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=EF=BC=9B#481?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 34 ++- FreeSql.DbContext/FreeSql.DbContext.xml | 9 + .../MySqlConnector/Curd/MySqlInsertTest.cs | 8 +- .../Dameng/Curd/DamengInsertTest.cs | 8 +- .../Firebird/Curd/FirebirdInsertTest.cs | 8 +- .../MsAccess/Curd/MsAccessInsertTest.cs | 4 +- .../MySql/Curd/MySqlInsertTest.cs | 8 +- .../Oracle/Curd/OracleInsertTest.cs | 8 +- .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 8 +- .../ShenTong/Curd/ShenTongInsertTest.cs | 8 +- .../SqlServer/Curd/SqlServerInsertTest.cs | 8 +- .../Sqlite/Curd/SqliteInsertTest.cs | 8 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 270 ++++++++++++++++++ FreeSql/FreeSql.xml | 56 ++++ FreeSql/Interface/Curd/IDelete.cs | 6 + FreeSql/Interface/Curd/IUpdate.cs | 6 + .../Internal/CommonProvider/BaseDbProvider.cs | 6 +- .../Internal/CommonProvider/DeleteProvider.cs | 5 + .../CommonProvider/InsertOrUpdateProvider.cs | 4 +- .../Internal/CommonProvider/InsertProvider.cs | 44 +-- .../Internal/CommonProvider/UpdateProvider.cs | 54 +++- FreeSql/Internal/Model/ColumnInfo.cs | 12 +- 22 files changed, 491 insertions(+), 91 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index ba2c84c6..5a71b8ea 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -141,6 +141,11 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + fsql.Aop.AuditValue += new EventHandler((_, e) => + { + + }); + Dictionary dic = new Dictionary(); dic.Add("id", 1); dic.Add("name", "xxxx"); @@ -152,10 +157,31 @@ namespace base_entity ["name"] = "yyyy" }); - var sqss = fsql.Insert(dic).AsTable("table1").ToSql(); - var sqss2 = fsql.Insert(diclist).AsTable("table1").ToSql(); - sqss = fsql.Insert(dic).AsTable("table1").NoneParameter(false).ToSql(); - sqss2 = fsql.Insert(diclist).AsTable("table1").NoneParameter(false).ToSql(); + var sqss = fsql.InsertDict(dic).AsTable("table1").ToSql(); + var sqss2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); + sqss = fsql.InsertDict(dic).AsTable("table1").NoneParameter(false).ToSql(); + sqss2 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter(false).ToSql(); + + var sqlupd1 = fsql.UpdateDict(dic).AsTable("table1").WherePrimary("id").ToSql(); + var sqlupd2 = fsql.UpdateDict(diclist).AsTable("table1").WherePrimary("id").ToSql(); + var sqlupd11 = fsql.UpdateDict(dic).AsTable("table1").WherePrimary("id").NoneParameter(false).ToSql(); + var sqlupd22 = fsql.UpdateDict(diclist).AsTable("table1").WherePrimary("id").NoneParameter(false).ToSql(); + + var sqldel1 = fsql.DeleteDict(dic).AsTable("table1").ToSql(); + var sqldel2 = fsql.DeleteDict(diclist).AsTable("table1").ToSql(); + diclist[1]["title"] = "newtitle"; + var sqldel3 = fsql.DeleteDict(diclist).AsTable("table1").ToSql(); + diclist.Clear(); + diclist.Add(new Dictionary + { + ["id"] = 1 + }); + diclist.Add(new Dictionary + { + ["id"] = 2 + }); + var sqldel4 = fsql.DeleteDict(diclist).AsTable("table1").ToSql(); + for (var a = 0; a < 10000; a++) fsql.Select().First(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index da7ace6b..bdd16ff9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -538,5 +538,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs index 9df9421f..e6c259e3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs @@ -44,13 +44,13 @@ namespace FreeSql.Tests.MySqlConnector ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(@id_0, @name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(@id_0, @name_0), (@id_1, @name_1)", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(1, 'xxxx'), (2, 'yyyy')", sql4); } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs index 6ea7883b..eea8403d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs @@ -37,16 +37,16 @@ namespace FreeSql.Tests.Dameng ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_0, :name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT ALL INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_0, :name_0) INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_1, :name_1) SELECT 1 FROM DUAL", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT ALL INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx') INTO ""TABLE1""(""ID"", ""NAME"") VALUES(2, 'yyyy') diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs index f4ff5666..8bfe7d5f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs @@ -37,15 +37,15 @@ namespace FreeSql.Tests.Firebird ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(@id_0, @name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") SELECT FIRST 1 @id_0, @name_0 FROM rdb$database UNION ALL SELECT FIRST 1 @id_1, @name_1 FROM rdb$database", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") SELECT FIRST 1 1, 'xxxx' FROM rdb$database UNION ALL SELECT FIRST 1 2, 'yyyy' FROM rdb$database", sql4); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs index 50652b86..3eedeada 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs @@ -37,9 +37,9 @@ namespace FreeSql.Tests.MsAccess ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO [table1]([id], [name]) VALUES(1, 'xxxx')", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO [table1]([id], [name]) VALUES(1, 'xxxx'), (2, 'yyyy')", sql2); } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index db55bc8b..df4eb1f4 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -45,13 +45,13 @@ namespace FreeSql.Tests.MySql ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(?id_0, ?name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(?id_0, ?name_0), (?id_1, ?name_1)", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO `table1`(`id`, `name`) VALUES(1, 'xxxx'), (2, 'yyyy')", sql4); } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index 77392883..6b75fa19 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -37,16 +37,16 @@ namespace FreeSql.Tests.Oracle ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_0, :name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT ALL INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_0, :name_0) INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_1, :name_1) SELECT 1 FROM DUAL", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT ALL INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx') INTO ""TABLE1""(""ID"", ""NAME"") VALUES(2, 'yyyy') diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index b3f6831a..6e05d833 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -37,13 +37,13 @@ namespace FreeSql.Tests.PostgreSQL ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(@id_0, @name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(@id_0, @name_0), (@id_1, @name_1)", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(1, 'xxxx'), (2, 'yyyy')", sql4); } diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs index 072ecbbf..f25ee748 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs @@ -37,13 +37,13 @@ namespace FreeSql.Tests.ShenTong ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(@id_0, @name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(@id_0, @name_0), (@id_1, @name_1)", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx'), (2, 'yyyy')", sql4); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index b9a98052..44c3f049 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -47,13 +47,13 @@ namespace FreeSql.Tests.SqlServer ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO [table1]([id], [name]) VALUES(@id_0, @name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO [table1]([id], [name]) VALUES(@id_0, @name_0), (@id_1, @name_1)", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO [table1]([id], [name]) VALUES(1, N'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO [table1]([id], [name]) VALUES(1, N'xxxx'), (2, N'yyyy')", sql4); } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs index 46321dcd..cb06bf3e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs @@ -37,13 +37,13 @@ namespace FreeSql.Tests.Sqlite ["name"] = "yyyy" }); - var sql1 = fsql.Insert(dic).AsTable("table1").ToSql(); + var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(@id_0, @name_0)", sql1); - var sql2 = fsql.Insert(diclist).AsTable("table1").ToSql(); + var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(@id_0, @name_0), (@id_1, @name_1)", sql2); - var sql3 = fsql.Insert(dic).AsTable("table1").NoneParameter().ToSql(); + var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(1, 'xxxx')", sql3); - var sql4 = fsql.Insert(diclist).AsTable("table1").NoneParameter().ToSql(); + var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql(); Assert.Equal(@"INSERT INTO ""table1""(""id"", ""name"") VALUES(1, 'xxxx'), (2, 'yyyy')", sql4); } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index b306b417..7cc4c2bb 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -1,6 +1,7 @@ using FreeSql; using FreeSql.DataAnnotations; using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.Model; using FreeSql.Internal.ObjectPool; using System; using System.Collections; @@ -653,4 +654,273 @@ SELECT "); throw new NotSupportedException($"{s0p._orm.Ado.DataType} 不支持 OrderByRandom 随机排序"); } #endregion + + #region IFreeSql Insert/Update/Delete Dictionary + /// + /// 插入数据字典 Dictionary<string, object> + /// + /// + /// + public static InsertDictImpl InsertDict(this IFreeSql freesql, Dictionary source) + { + var insertDict = new InsertDictImpl(freesql); + insertDict._insertProvider.AppendData(source); + return insertDict; + } + /// + /// 插入数据字典,传入 Dictionary<string, object> 集合 + /// + /// + /// + public static InsertDictImpl InsertDict(this IFreeSql freesql, IEnumerable> source) + { + var insertDict = new InsertDictImpl(freesql); + insertDict._insertProvider.AppendData(source); + return insertDict; + } + /// + /// 更新数据字典 Dictionary<string, object> + /// + /// + /// + public static UpdateDictImpl UpdateDict(this IFreeSql freesql, Dictionary source) + { + var updateDict = new UpdateDictImpl(freesql); + updateDict._updateProvider.SetSource(source); + return updateDict; + } + /// + /// 更新数据字典,传入 Dictionary<string, object> 集合 + /// + /// + /// + public static UpdateDictImpl UpdateDict(this IFreeSql freesql, IEnumerable> source) + { + var updateDict = new UpdateDictImpl(freesql); + updateDict._updateProvider.SetSource(source); + return updateDict; + } + /// + /// 删除数据字典 Dictionary<string, object> + /// + /// + /// + public static DeleteDictImpl DeleteDict(this IFreeSql freesql, Dictionary source) + { + var deleteDict = new DeleteDictImpl(freesql); + UpdateProvider>.GetDictionaryTableInfo(source, deleteDict._deleteProvider._orm, ref deleteDict._deleteProvider._table); + var primarys = UpdateDictImpl.GetPrimarys(deleteDict._deleteProvider._table, source.Keys.ToArray()); + deleteDict._deleteProvider.Where(deleteDict._deleteProvider._commonUtils.WhereItems(primarys, "", new[] { source })); + return deleteDict; + } + /// + /// 删除数据字典,传入 Dictionary<string, object> 集合 + /// + /// + /// + public static DeleteDictImpl DeleteDict(this IFreeSql freesql, IEnumerable> source) + { + DeleteDictImpl deleteDict = null; + if (source.Select(a => string.Join(",", a.Keys)).Distinct().Count() == 1) + { + deleteDict = new DeleteDictImpl(freesql); + var sourceFirst = source.FirstOrDefault(); + UpdateProvider>.GetDictionaryTableInfo(sourceFirst, deleteDict._deleteProvider._orm, ref deleteDict._deleteProvider._table); + var primarys = UpdateDictImpl.GetPrimarys(deleteDict._deleteProvider._table, sourceFirst.Keys.ToArray()); + deleteDict._deleteProvider.Where(deleteDict._deleteProvider._commonUtils.WhereItems(primarys, "", source)); + return deleteDict; + } + foreach (var item in source) + { + var tmpDelteDict = DeleteDict(freesql, item); + if (deleteDict == null) deleteDict = tmpDelteDict; + else deleteDict._deleteProvider._where.Append(" OR ").Append(tmpDelteDict._deleteProvider._where); + } + return deleteDict ?? new DeleteDictImpl(freesql); + } + + public class InsertDictImpl + { + internal readonly InsertProvider> _insertProvider; + internal InsertDictImpl(IFreeSql orm) + { + _insertProvider = (orm as BaseDbProvider ?? throw new Exception("IFreeSql 无法转换成 BaseDbProvider")) + .CreateInsertProvider>() as InsertProvider>; + } + + public InsertDictImpl AsTable(string tableName) + { + _insertProvider.AsTable(tableName); + return this; + } + + public InsertDictImpl BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true) + { + _insertProvider.BatchOptions(valuesLimit, parameterLimit, autoTransaction); + return this; + } + public InsertDictImpl BatchProgress(Action>> callback) + { + _insertProvider.BatchProgress(callback); + return this; + } + + public InsertDictImpl CommandTimeout(int timeout) + { + _insertProvider.CommandTimeout(timeout); + return this; + } + + public int ExecuteAffrows() => _insertProvider.ExecuteAffrows(); + public long ExecuteIdentity() => _insertProvider.ExecuteAffrows(); + public List> ExecuteInserted() => _insertProvider.ExecuteInserted(); + +#if net40 +#else + public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => _insertProvider.ExecuteAffrowsAsync(cancellationToken); + public Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => _insertProvider.ExecuteIdentityAsync(cancellationToken); + public Task>> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => _insertProvider.ExecuteInsertedAsync(cancellationToken); +#endif + + public InsertDictImpl NoneParameter(bool isNotCommandParameter = true) + { + _insertProvider.NoneParameter(isNotCommandParameter); + return this; + } + + public DataTable ToDataTable() => _insertProvider.ToDataTable(); + public string ToSql() => _insertProvider.ToSql(); + + public InsertDictImpl WithConnection(DbConnection connection) + { + _insertProvider.WithConnection(connection); + return this; + } + public InsertDictImpl WithTransaction(DbTransaction transaction) + { + _insertProvider.WithTransaction(transaction); + return this; + } + } + public class UpdateDictImpl + { + internal readonly UpdateProvider> _updateProvider; + internal UpdateDictImpl(IFreeSql orm) + { + _updateProvider = (orm as BaseDbProvider ?? throw new Exception("IFreeSql 无法转换成 BaseDbProvider")) + .CreateUpdateProvider>(null) as UpdateProvider>; + } + + public UpdateDictImpl WherePrimary(params string[] primarys) + { + _updateProvider._tempPrimarys = GetPrimarys(_updateProvider._table, primarys); + return this; + } + public static ColumnInfo[] GetPrimarys(TableInfo table, params string[] primarys) + { + if (primarys?.Any() != true) throw new ArgumentException(nameof(primarys)); + var pks = new List(); + foreach (var primary in primarys) + { + if (table.ColumnsByCs.TryGetValue(string.Concat(primary), out var col)) pks.Add(col); + else throw new Exception($"GetPrimarys 传递的参数 \"{primary}\" 不正确,它不属于字典数据的键名"); + } + return pks.ToArray(); + } + + public UpdateDictImpl AsTable(string tableName) + { + _updateProvider.AsTable(tableName); + return this; + } + + public UpdateDictImpl BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true) + { + _updateProvider.BatchOptions(rowsLimit, parameterLimit, autoTransaction); + return this; + } + public UpdateDictImpl BatchProgress(Action>> callback) + { + _updateProvider.BatchProgress(callback); + return this; + } + + public UpdateDictImpl CommandTimeout(int timeout) + { + _updateProvider.CommandTimeout(timeout); + return this; + } + + public int ExecuteAffrows() => _updateProvider.ExecuteAffrows(); + public List> ExecuteUpdated() => _updateProvider.ExecuteUpdated(); + +#if net40 +#else + public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => _updateProvider.ExecuteAffrowsAsync(cancellationToken); + public Task>> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => _updateProvider.ExecuteUpdatedAsync(cancellationToken); +#endif + + public UpdateDictImpl NoneParameter(bool isNotCommandParameter = true) + { + _updateProvider.NoneParameter(isNotCommandParameter); + return this; + } + + public string ToSql() => _updateProvider.ToSql(); + + public UpdateDictImpl WithConnection(DbConnection connection) + { + _updateProvider.WithConnection(connection); + return this; + } + public UpdateDictImpl WithTransaction(DbTransaction transaction) + { + _updateProvider.WithTransaction(transaction); + return this; + } + } + public class DeleteDictImpl + { + internal readonly DeleteProvider> _deleteProvider; + internal DeleteDictImpl(IFreeSql orm) + { + _deleteProvider = (orm as BaseDbProvider ?? throw new Exception("IFreeSql 无法转换成 BaseDbProvider")) + .CreateDeleteProvider>(null) as DeleteProvider>; + } + + public DeleteDictImpl AsTable(string tableName) + { + _deleteProvider.AsTable(tableName); + return this; + } + + public DeleteDictImpl CommandTimeout(int timeout) + { + _deleteProvider.CommandTimeout(timeout); + return this; + } + + public int ExecuteAffrows() => _deleteProvider.ExecuteAffrows(); + public List> ExecuteDeleted() => _deleteProvider.ExecuteDeleted(); + +#if net40 +#else + public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => _deleteProvider.ExecuteAffrowsAsync(cancellationToken); + public Task>> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => _deleteProvider.ExecuteDeletedAsync(cancellationToken); +#endif + + public string ToSql() => _deleteProvider.ToSql(); + + public DeleteDictImpl WithConnection(DbConnection connection) + { + _deleteProvider.WithConnection(connection); + return this; + } + public DeleteDictImpl WithTransaction(DbTransaction transaction) + { + _deleteProvider.WithTransaction(transaction); + return this; + } + } + #endregion } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 63908a16..33789455 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1490,6 +1490,13 @@ + + + 设置表名 + + + + 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 @@ -2953,6 +2960,13 @@ + + + 设置表名 + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 @@ -4639,6 +4653,48 @@ + + + 插入数据字典 Dictionary<string, object> + + + + + + + 插入数据字典,传入 Dictionary<string, object> 集合 + + + + + + + 更新数据字典 Dictionary<string, object> + + + + + + + 更新数据字典,传入 Dictionary<string, object> 集合 + + + + + + + 删除数据字典 Dictionary<string, object> + + + + + + + 删除数据字典,传入 Dictionary<string, object> 集合 + + + + 使用 and 拼接两个 lambda 表达式 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 54ed617a..95d6c19b 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -95,6 +95,12 @@ namespace FreeSql /// IDelete AsTable(Func tableRule); /// + /// 设置表名 + /// + /// + /// + IDelete AsTable(string tableName); + /// /// 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 /// /// diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 7f46756e..afe48dd8 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -227,6 +227,12 @@ namespace FreeSql /// IUpdate AsTable(Func tableRule); /// + /// 设置表名 + /// + /// + /// + IUpdate AsTable(string tableName); + /// /// 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 /// /// diff --git a/FreeSql/Internal/CommonProvider/BaseDbProvider.cs b/FreeSql/Internal/CommonProvider/BaseDbProvider.cs index 54c76fa5..44f3c75e 100644 --- a/FreeSql/Internal/CommonProvider/BaseDbProvider.cs +++ b/FreeSql/Internal/CommonProvider/BaseDbProvider.cs @@ -15,7 +15,11 @@ namespace FreeSql.Internal.CommonProvider public ISelect Select() where T1 : class => CreateSelectProvider(null); public ISelect Select(object dywhere) where T1 : class => CreateSelectProvider(dywhere); - public IInsert Insert() where T1 : class => CreateInsertProvider(); + public IInsert Insert() where T1 : class + { + if (typeof(T1) == typeof(Dictionary)) throw new Exception("请使用 fsql.InsertDict(dict) 方法插入字典数据"); + return CreateInsertProvider(); + } public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 652623db..1e84d341 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -147,6 +147,11 @@ namespace FreeSql.Internal.CommonProvider _tableRule = tableRule; return this; } + public IDelete AsTable(string tableName) + { + _tableRule = (oldname) => tableName; + return this; + } public IDelete AsType(Type entityType) { if (entityType == typeof(object)) throw new Exception("IDelete.AsType 参数不支持指定为 object"); diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 11bb8b85..91968281 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -88,14 +88,14 @@ namespace FreeSql.Internal.CommonProvider } public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { - if (data == null) return; + if (data == null || table == null) return; if (typeof(T1) == typeof(object) && new[] { table.Type, table.TypeLazy }.Contains(data.GetType()) == false) throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); if (orm.Aop.AuditValueHandler == null) return; foreach (var col in table.Columns.Values) { object val = col.GetValue(data); - var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties.TryGetValue(col.CsName, out var tryprop) ? tryprop : null, val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.ValueIsChanged) { diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 76a9b1db..36450189 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -116,7 +116,7 @@ namespace FreeSql.Internal.CommonProvider { if (source != null) { - GetDictionaryTableInfo(source, _orm, ref _table); + UpdateProvider.GetDictionaryTableInfo(source, _orm, ref _table); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.Add(source); } @@ -126,7 +126,7 @@ namespace FreeSql.Internal.CommonProvider { if (source != null) { - GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table); + UpdateProvider.GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source); } @@ -137,49 +137,13 @@ namespace FreeSql.Internal.CommonProvider if (source != null) { source = source.Where(a => a != null).ToList(); - GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table); + UpdateProvider.GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source); } return this; } - public static void GetDictionaryTableInfo(T1 source, IFreeSql orm, ref TableInfo table) - { - if (table == null && typeof(T1) == typeof(Dictionary)) - { - var dic = source as Dictionary; - table = new TableInfo(); - table.Type = typeof(Dictionary); - table.CsName = dic.TryGetValue("", out var tryval) ? string.Concat(tryval) : ""; - table.DbName = table.CsName; - table.DisableSyncStructure = true; - table.IsDictionaryType = true; - var colpos = new List(); - foreach (var kv in dic) - { - var colName = kv.Key; - if (orm.CodeFirst.IsSyncStructureToLower) colName = colName.ToLower(); - if (orm.CodeFirst.IsSyncStructureToUpper) colName = colName.ToUpper(); - var col = new ColumnInfo - { - CsName = kv.Key, - Table = table, - Attribute = new DataAnnotations.ColumnAttribute - { - Name = colName, - MapType = typeof(object) - }, - CsType = typeof(object) - }; - table.Columns.Add(colName, col); - table.ColumnsByCs.Add(kv.Key, col); - colpos.Add(col); - } - table.ColumnsByPosition = colpos.ToArray(); - colpos.Clear(); - } - } public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data?.Any() != true) return; @@ -196,7 +160,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetValue(data); if (orm.Aop.AuditValueHandler != null) { - var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties.TryGetValue(col.CsName, out var tryprop) ? tryprop : null, val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.ValueIsChanged) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 63b81baf..cd1bb84d 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -46,7 +46,7 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); - _tempPrimarys = _table.Primarys; + _tempPrimarys = _table?.Primarys ?? new ColumnInfo[0]; _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); @@ -60,7 +60,7 @@ namespace FreeSql.Internal.CommonProvider protected void IgnoreCanUpdate() { if (_table == null || _table.Type == typeof(object)) return; - foreach (var col in _table.Columns.Values) + foreach (var col in _table?.Columns.Values) if (col.Attribute.CanUpdate == false && _ignore.ContainsKey(col.Attribute.Name) == false) _ignore.Add(col.Attribute.Name, true); } @@ -377,7 +377,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var col in table.Columns.Values) { object val = col.GetValue(d); - var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties.TryGetValue(col.CsName, out var tryprop) ? tryprop : null, val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.ValueIsChanged) { @@ -393,13 +393,13 @@ namespace FreeSql.Internal.CommonProvider public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (orm.Aop.AuditValueHandler == null) return; - if (data == null) return; + if (data == null || table == null) return; if (typeof(T1) == typeof(object) && new[] { table.Type, table.TypeLazy }.Contains(data.GetType()) == false) throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { object val = col.GetValue(data); - var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties.TryGetValue(col.CsName, out var tryprop) ? tryprop : null, val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.ValueIsChanged) { @@ -412,10 +412,49 @@ namespace FreeSql.Internal.CommonProvider } } + public static void GetDictionaryTableInfo(T1 source, IFreeSql orm, ref TableInfo table) + { + if (table == null && typeof(T1) == typeof(Dictionary)) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + var dic = source as Dictionary; + table = new TableInfo(); + table.Type = typeof(Dictionary); + table.CsName = dic.TryGetValue("", out var tryval) ? string.Concat(tryval) : ""; + table.DbName = table.CsName; + table.DisableSyncStructure = true; + table.IsDictionaryType = true; + var colpos = new List(); + foreach (var kv in dic) + { + var colName = kv.Key; + if (orm.CodeFirst.IsSyncStructureToLower) colName = colName.ToLower(); + if (orm.CodeFirst.IsSyncStructureToUpper) colName = colName.ToUpper(); + var col = new ColumnInfo + { + CsName = kv.Key, + Table = table, + Attribute = new DataAnnotations.ColumnAttribute + { + Name = colName, + MapType = typeof(object) + }, + CsType = typeof(object) + }; + table.Columns.Add(colName, col); + table.ColumnsByCs.Add(kv.Key, col); + colpos.Add(col); + } + table.ColumnsByPosition = colpos.ToArray(); + colpos.Clear(); + } + } + public IUpdate SetSource(T1 source) => this.SetSource(new[] { source }); public IUpdate SetSource(IEnumerable source, Expression> tempPrimarys = null) { if (source == null || source.Any() == false) return this; + GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source.Where(a => a != null)); @@ -665,6 +704,11 @@ namespace FreeSql.Internal.CommonProvider _tableRule = tableRule; return this; } + public IUpdate AsTable(string tableName) + { + _tableRule = (oldname) => tableName; + return this; + } public IUpdate AsType(Type entityType) { if (entityType == typeof(object)) throw new Exception("IUpdate.AsType 参数不支持指定为 object"); diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index 9a175b7b..d8a5c42c 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -51,7 +51,17 @@ namespace FreeSql.Internal.Model /// /// /// - public void SetValue(object obj, object val) => Table.SetPropertyValue(obj, CsName, Utils.GetDataReaderValue(CsType, val)); + public void SetValue(object obj, object val) + { + if (Table.IsDictionaryType) + { + var dic = obj as Dictionary; + if (dic.ContainsKey(CsName)) dic[CsName] = val; + else dic.Add(CsName, val); + return; + } + Table.SetPropertyValue(obj, CsName, Utils.GetDataReaderValue(CsType, val)); + }