From 5d9afe8329013e06d8ece7cc2a089a10e793b180 Mon Sep 17 00:00:00 2001
From: 2881099 <2881099@qq.com>
Date: Tue, 29 Mar 2022 21:13:45 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20InsertOrUpdateDict=20?=
=?UTF-8?q?=E5=AD=97=E5=85=B8=E6=93=8D=E4=BD=9C=E6=96=B9=E6=B3=95=EF=BC=9B?=
=?UTF-8?q?#481?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++
.../SqlServer/Curd/SqlServerInsertTest.cs | 6 ++
FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 100 +++++++++++++++++-
FreeSql/FreeSql.xml | 23 ++++
FreeSql/Interface/Curd/IInsertOrUpdate.cs | 6 ++
.../CommonProvider/InsertOrUpdateProvider.cs | 15 ++-
6 files changed, 153 insertions(+), 6 deletions(-)
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/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs
index 5849fa92..63fd18b2 100644
--- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs
@@ -78,6 +78,12 @@ namespace FreeSql.Tests.SqlServer
dicRet = fsql.DeleteDict(diclist).AsTable("table1dict").ExecuteDeleted();
dicRet = fsql.InsertDict(diclist).AsTable("table1dict").NoneParameter().ExecuteInserted();
dicRet = fsql.DeleteDict(diclist).AsTable("table1dict").ExecuteDeleted();
+
+ sql1 = fsql.InsertOrUpdateDict(dic).AsTable("table1").WherePrimary("id").ToSql();
+ sql2 = fsql.InsertOrUpdateDict(diclist).AsTable("table1").WherePrimary("id").ToSql();
+
+ sql1 = fsql.InsertOrUpdateDict(dic).AsTable("table1").WherePrimary("name").ToSql();
+ sql2 = fsql.InsertOrUpdateDict(diclist).AsTable("table1").WherePrimary("name").ToSql();
}
[Fact]
diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
index f4f2eae7..df2ea79d 100644
--- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
+++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
@@ -655,7 +655,7 @@ SELECT ");
}
#endregion
- #region IFreeSql Insert/Update/Delete Dictionary
+ #region IFreeSql Insert/Update/InsertOrUpdate/Delete Dictionary
///
/// 插入数据字典 Dictionary<string, object>
///
@@ -701,6 +701,32 @@ SELECT ");
return updateDict;
}
///
+ /// 插入或更新数据字典,此功能依赖数据库特性(低版本可能不支持),参考如下:
+ /// MySql 5.6+: on duplicate key update
+ /// PostgreSQL 9.4+: on conflict do update
+ /// SqlServer 2008+: merge into
+ /// Oracle 11+: merge into
+ /// Sqlite: replace into
+ /// 达梦: merge into
+ /// 人大金仓:on conflict do update
+ /// 神通:merge into
+ /// MsAccess:不支持
+ ///
+ ///
+ ///
+ public static InsertOrUpdateDictImpl InsertOrUpdateDict(this IFreeSql freesql, Dictionary source)
+ {
+ var insertOrUpdateDict = new InsertOrUpdateDictImpl(freesql);
+ insertOrUpdateDict._insertOrUpdateProvider.SetSource(source);
+ return insertOrUpdateDict;
+ }
+ public static InsertOrUpdateDictImpl InsertOrUpdateDict(this IFreeSql freesql, IEnumerable> source)
+ {
+ var insertOrUpdateDict = new InsertOrUpdateDictImpl(freesql);
+ insertOrUpdateDict._insertOrUpdateProvider.SetSource(source);
+ return insertOrUpdateDict;
+ }
+ ///
/// 删除数据字典 Dictionary<string, object>
///
///
@@ -739,6 +765,7 @@ SELECT ");
return deleteDict ?? new DeleteDictImpl(freesql);
}
+ #region InsertDictImpl
public class InsertDictImpl
{
internal readonly InsertProvider> _insertProvider;
@@ -802,6 +829,9 @@ SELECT ");
return this;
}
}
+ #endregion
+
+ #region UpdateDictImpl
public class UpdateDictImpl
{
internal readonly UpdateProvider> _updateProvider;
@@ -827,6 +857,15 @@ SELECT ");
}
return pks.ToArray();
}
+ public static void SetTablePrimary(TableInfo table, params string[] primarys)
+ {
+ foreach (var primary in primarys)
+ {
+ if (table.ColumnsByCs.TryGetValue(string.Concat(primary), out var col)) col.Attribute.IsPrimary = true;
+ else throw new Exception($"GetPrimarys 传递的参数 \"{primary}\" 不正确,它不属于字典数据的键名");
+ }
+ table.Primarys = table.Columns.Where(a => a.Value.Attribute.IsPrimary).Select(a => a.Value).ToArray();
+ }
public UpdateDictImpl AsTable(string tableName)
{
@@ -879,6 +918,63 @@ SELECT ");
return this;
}
}
+ #endregion
+
+ #region InsertOrUpdateDictImpl
+ public class InsertOrUpdateDictImpl
+ {
+ internal readonly InsertOrUpdateProvider> _insertOrUpdateProvider;
+ internal InsertOrUpdateDictImpl(IFreeSql orm)
+ {
+ _insertOrUpdateProvider = (orm as BaseDbProvider ?? throw new Exception("IFreeSql 无法转换成 BaseDbProvider"))
+ .CreateInsertOrUpdateProvider>() as InsertOrUpdateProvider>;
+ }
+
+ public InsertOrUpdateDictImpl WherePrimary(params string[] primarys)
+ {
+ UpdateDictImpl.SetTablePrimary(_insertOrUpdateProvider._table, primarys);
+ return this;
+ }
+
+ public InsertOrUpdateDictImpl AsTable(string tableName)
+ {
+ _insertOrUpdateProvider.AsTable(tableName);
+ return this;
+ }
+
+ public InsertOrUpdateDictImpl CommandTimeout(int timeout)
+ {
+ _insertOrUpdateProvider.CommandTimeout(timeout);
+ return this;
+ }
+
+ public int ExecuteAffrows() => _insertOrUpdateProvider.ExecuteAffrows();
+#if net40
+#else
+ public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => _insertOrUpdateProvider.ExecuteAffrowsAsync(cancellationToken);
+#endif
+ public InsertOrUpdateDictImpl IfExistsDoNothing()
+ {
+ _insertOrUpdateProvider.IfExistsDoNothing();
+ return this;
+ }
+
+ public string ToSql() => _insertOrUpdateProvider.ToSql();
+
+ public InsertOrUpdateDictImpl WithConnection(DbConnection connection)
+ {
+ _insertOrUpdateProvider.WithConnection(connection);
+ return this;
+ }
+ public InsertOrUpdateDictImpl WithTransaction(DbTransaction transaction)
+ {
+ _insertOrUpdateProvider.WithTransaction(transaction);
+ return this;
+ }
+ }
+ #endregion
+
+ #region DeleteDictImpl
public class DeleteDictImpl
{
internal readonly DeleteProvider> _deleteProvider;
@@ -923,4 +1019,6 @@ SELECT ");
}
}
#endregion
+
+ #endregion
}
diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml
index 33789455..55a8f429 100644
--- a/FreeSql/FreeSql.xml
+++ b/FreeSql/FreeSql.xml
@@ -1748,6 +1748,13 @@
+
+
+ 设置表名
+
+
+
+
动态Type,在使用 Update<object> 后使用本方法,指定实体类型
@@ -4681,6 +4688,22 @@
+
+
+ 插入或更新数据字典,此功能依赖数据库特性(低版本可能不支持),参考如下:
+ MySql 5.6+: on duplicate key update
+ PostgreSQL 9.4+: on conflict do update
+ SqlServer 2008+: merge into
+ Oracle 11+: merge into
+ Sqlite: replace into
+ 达梦: merge into
+ 人大金仓:on conflict do update
+ 神通:merge into
+ MsAccess:不支持
+
+
+
+
删除数据字典 Dictionary<string, object>
diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs
index f2926980..c2cb1abb 100644
--- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs
+++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs
@@ -69,6 +69,12 @@ namespace FreeSql
///
IInsertOrUpdate AsTable(Func tableRule);
///
+ /// 设置表名
+ ///
+ ///
+ ///
+ IInsertOrUpdate AsTable(string tableName);
+ ///
/// 动态Type,在使用 Update<object> 后使用本方法,指定实体类型
///
///
diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs
index 91968281..0c67b569 100644
--- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs
+++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs
@@ -29,7 +29,7 @@ namespace FreeSql.Internal.CommonProvider
public DbTransaction _transaction;
public DbConnection _connection;
public int _commandTimeout = 0;
- public ColumnInfo IdentityColumn { get; }
+ public ColumnInfo IdentityColumn { get; private set; }
public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
{
@@ -37,12 +37,10 @@ namespace FreeSql.Internal.CommonProvider
_commonUtils = commonUtils;
_commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1));
- if (_table == null)
- {
+ if (_table == null && typeof(T1) != typeof(Dictionary))
throw new Exception($"InsertOrUpdate<>的泛型参数 不支持 {typeof(T1)},请传递您的实体类");
- }
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure();
- IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
+ IdentityColumn = _table?.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
}
protected void ClearData()
@@ -112,6 +110,7 @@ namespace FreeSql.Internal.CommonProvider
public IInsertOrUpdate SetSource(IEnumerable source)
{
if (source == null || source.Any() == false) return this;
+ UpdateProvider.GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table);
AuditDataValue(this, source, _orm, _table, _auditValueChangedDict);
_source.AddRange(source.Where(a => a != null));
return this;
@@ -139,6 +138,11 @@ namespace FreeSql.Internal.CommonProvider
_tableRule = tableRule;
return this;
}
+ public IInsertOrUpdate AsTable(string tableName)
+ {
+ _tableRule = (oldname) => tableName;
+ return this;
+ }
public IInsertOrUpdate AsType(Type entityType)
{
if (entityType == typeof(object)) throw new Exception("IInsertOrUpdate.AsType 参数不支持指定为 object");
@@ -146,6 +150,7 @@ namespace FreeSql.Internal.CommonProvider
var newtb = _commonUtils.GetTableByEntity(entityType);
_table = newtb ?? throw new Exception("IInsertOrUpdate.AsType 参数错误,请传入正确的实体类型");
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
+ IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
return this;
}