- 增加 InsertOrUpdateDict 字典操作方法;#481

This commit is contained in:
2881099 2022-03-29 21:13:45 +08:00
parent 5b65a17be0
commit 5d9afe8329
6 changed files with 153 additions and 6 deletions

View File

@ -538,5 +538,14 @@
<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>

View File

@ -78,6 +78,12 @@ namespace FreeSql.Tests.SqlServer
dicRet = fsql.DeleteDict(diclist).AsTable("table1dict").ExecuteDeleted(); dicRet = fsql.DeleteDict(diclist).AsTable("table1dict").ExecuteDeleted();
dicRet = fsql.InsertDict(diclist).AsTable("table1dict").NoneParameter().ExecuteInserted(); dicRet = fsql.InsertDict(diclist).AsTable("table1dict").NoneParameter().ExecuteInserted();
dicRet = fsql.DeleteDict(diclist).AsTable("table1dict").ExecuteDeleted(); 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] [Fact]

View File

@ -655,7 +655,7 @@ SELECT ");
} }
#endregion #endregion
#region IFreeSql Insert/Update/Delete Dictionary<string, object> #region IFreeSql Insert/Update/InsertOrUpdate/Delete Dictionary<string, object>
/// <summary> /// <summary>
/// 插入数据字典 Dictionary&lt;string, object&gt; /// 插入数据字典 Dictionary&lt;string, object&gt;
/// </summary> /// </summary>
@ -701,6 +701,32 @@ SELECT ");
return updateDict; return updateDict;
} }
/// <summary> /// <summary>
/// 插入或更新数据字典,此功能依赖数据库特性(低版本可能不支持),参考如下:<para></para>
/// MySql 5.6+: on duplicate key update<para></para>
/// PostgreSQL 9.4+: on conflict do update<para></para>
/// SqlServer 2008+: merge into<para></para>
/// Oracle 11+: merge into<para></para>
/// Sqlite: replace into<para></para>
/// 达梦: merge into<para></para>
/// 人大金仓on conflict do update<para></para>
/// 神通merge into<para></para>
/// MsAccess不支持<para></para>
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static InsertOrUpdateDictImpl InsertOrUpdateDict(this IFreeSql freesql, Dictionary<string, object> source)
{
var insertOrUpdateDict = new InsertOrUpdateDictImpl(freesql);
insertOrUpdateDict._insertOrUpdateProvider.SetSource(source);
return insertOrUpdateDict;
}
public static InsertOrUpdateDictImpl InsertOrUpdateDict(this IFreeSql freesql, IEnumerable<Dictionary<string, object>> source)
{
var insertOrUpdateDict = new InsertOrUpdateDictImpl(freesql);
insertOrUpdateDict._insertOrUpdateProvider.SetSource(source);
return insertOrUpdateDict;
}
/// <summary>
/// 删除数据字典 Dictionary&lt;string, object&gt; /// 删除数据字典 Dictionary&lt;string, object&gt;
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
@ -739,6 +765,7 @@ SELECT ");
return deleteDict ?? new DeleteDictImpl(freesql); return deleteDict ?? new DeleteDictImpl(freesql);
} }
#region InsertDictImpl
public class InsertDictImpl public class InsertDictImpl
{ {
internal readonly InsertProvider<Dictionary<string, object>> _insertProvider; internal readonly InsertProvider<Dictionary<string, object>> _insertProvider;
@ -802,6 +829,9 @@ SELECT ");
return this; return this;
} }
} }
#endregion
#region UpdateDictImpl
public class UpdateDictImpl public class UpdateDictImpl
{ {
internal readonly UpdateProvider<Dictionary<string, object>> _updateProvider; internal readonly UpdateProvider<Dictionary<string, object>> _updateProvider;
@ -827,6 +857,15 @@ SELECT ");
} }
return pks.ToArray(); 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) public UpdateDictImpl AsTable(string tableName)
{ {
@ -879,6 +918,63 @@ SELECT ");
return this; return this;
} }
} }
#endregion
#region InsertOrUpdateDictImpl
public class InsertOrUpdateDictImpl
{
internal readonly InsertOrUpdateProvider<Dictionary<string, object>> _insertOrUpdateProvider;
internal InsertOrUpdateDictImpl(IFreeSql orm)
{
_insertOrUpdateProvider = (orm as BaseDbProvider ?? throw new Exception("IFreeSql 无法转换成 BaseDbProvider"))
.CreateInsertOrUpdateProvider<Dictionary<string, object>>() as InsertOrUpdateProvider<Dictionary<string, object>>;
}
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<int> 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 public class DeleteDictImpl
{ {
internal readonly DeleteProvider<Dictionary<string, object>> _deleteProvider; internal readonly DeleteProvider<Dictionary<string, object>> _deleteProvider;
@ -923,4 +1019,6 @@ SELECT ");
} }
} }
#endregion #endregion
#endregion
} }

View File

@ -1748,6 +1748,13 @@
<param name="tableRule"></param> <param name="tableRule"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.IInsertOrUpdate`1.AsTable(System.String)">
<summary>
设置表名
</summary>
<param name="tableName"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IInsertOrUpdate`1.AsType(System.Type)"> <member name="M:FreeSql.IInsertOrUpdate`1.AsType(System.Type)">
<summary> <summary>
动态Type在使用 Update&lt;object&gt; 后使用本方法,指定实体类型 动态Type在使用 Update&lt;object&gt; 后使用本方法,指定实体类型
@ -4681,6 +4688,22 @@
<param name="source"></param> <param name="source"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSqlGlobalExtensions.InsertOrUpdateDict(IFreeSql,System.Collections.Generic.Dictionary{System.String,System.Object})">
<summary>
插入或更新数据字典,此功能依赖数据库特性(低版本可能不支持),参考如下:<para></para>
MySql 5.6+: on duplicate key update<para></para>
PostgreSQL 9.4+: on conflict do update<para></para>
SqlServer 2008+: merge into<para></para>
Oracle 11+: merge into<para></para>
Sqlite: replace into<para></para>
达梦: merge into<para></para>
人大金仓on conflict do update<para></para>
神通merge into<para></para>
MsAccess不支持<para></para>
</summary>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalExtensions.DeleteDict(IFreeSql,System.Collections.Generic.Dictionary{System.String,System.Object})"> <member name="M:FreeSqlGlobalExtensions.DeleteDict(IFreeSql,System.Collections.Generic.Dictionary{System.String,System.Object})">
<summary> <summary>
删除数据字典 Dictionary&lt;string, object&gt; 删除数据字典 Dictionary&lt;string, object&gt;

View File

@ -69,6 +69,12 @@ namespace FreeSql
/// <returns></returns> /// <returns></returns>
IInsertOrUpdate<T1> AsTable(Func<string, string> tableRule); IInsertOrUpdate<T1> AsTable(Func<string, string> tableRule);
/// <summary> /// <summary>
/// 设置表名
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
IInsertOrUpdate<T1> AsTable(string tableName);
/// <summary>
/// 动态Type在使用 Update&lt;object&gt; 后使用本方法,指定实体类型 /// 动态Type在使用 Update&lt;object&gt; 后使用本方法,指定实体类型
/// </summary> /// </summary>
/// <param name="entityType"></param> /// <param name="entityType"></param>

View File

@ -29,7 +29,7 @@ namespace FreeSql.Internal.CommonProvider
public DbTransaction _transaction; public DbTransaction _transaction;
public DbConnection _connection; public DbConnection _connection;
public int _commandTimeout = 0; public int _commandTimeout = 0;
public ColumnInfo IdentityColumn { get; } public ColumnInfo IdentityColumn { get; private set; }
public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
{ {
@ -37,12 +37,10 @@ namespace FreeSql.Internal.CommonProvider
_commonUtils = commonUtils; _commonUtils = commonUtils;
_commonExpression = commonExpression; _commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1)); _table = _commonUtils.GetTableByEntity(typeof(T1));
if (_table == null) if (_table == null && typeof(T1) != typeof(Dictionary<string, object>))
{
throw new Exception($"InsertOrUpdate<>的泛型参数 不支持 {typeof(T1)},请传递您的实体类"); throw new Exception($"InsertOrUpdate<>的泛型参数 不支持 {typeof(T1)},请传递您的实体类");
}
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>(); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault(); IdentityColumn = _table?.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
} }
protected void ClearData() protected void ClearData()
@ -112,6 +110,7 @@ namespace FreeSql.Internal.CommonProvider
public IInsertOrUpdate<T1> SetSource(IEnumerable<T1> source) public IInsertOrUpdate<T1> SetSource(IEnumerable<T1> source)
{ {
if (source == null || source.Any() == false) return this; if (source == null || source.Any() == false) return this;
UpdateProvider<T1>.GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table);
AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict);
_source.AddRange(source.Where(a => a != null)); _source.AddRange(source.Where(a => a != null));
return this; return this;
@ -139,6 +138,11 @@ namespace FreeSql.Internal.CommonProvider
_tableRule = tableRule; _tableRule = tableRule;
return this; return this;
} }
public IInsertOrUpdate<T1> AsTable(string tableName)
{
_tableRule = (oldname) => tableName;
return this;
}
public IInsertOrUpdate<T1> AsType(Type entityType) public IInsertOrUpdate<T1> AsType(Type entityType)
{ {
if (entityType == typeof(object)) throw new Exception("IInsertOrUpdate.AsType 参数不支持指定为 object"); if (entityType == typeof(object)) throw new Exception("IInsertOrUpdate.AsType 参数不支持指定为 object");
@ -146,6 +150,7 @@ namespace FreeSql.Internal.CommonProvider
var newtb = _commonUtils.GetTableByEntity(entityType); var newtb = _commonUtils.GetTableByEntity(entityType);
_table = newtb ?? throw new Exception("IInsertOrUpdate.AsType 参数错误,请传入正确的实体类型"); _table = newtb ?? throw new Exception("IInsertOrUpdate.AsType 参数错误,请传入正确的实体类型");
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
return this; return this;
} }