mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-10-15 18:55:07 +08:00
Merge branch 'master' of https://gitee.com/yanghs-cd/SqlSugar
This commit is contained in:
@@ -209,57 +209,73 @@ namespace SqlSugar
|
|||||||
|
|
||||||
private async Task<int> _BulkMerge(List<T> datas, string[] updateColumns, string[] whereColumns)
|
private async Task<int> _BulkMerge(List<T> datas, string[] updateColumns, string[] whereColumns)
|
||||||
{
|
{
|
||||||
Begin(datas, false,true);
|
try
|
||||||
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
|
||||||
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
|
||||||
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
|
||||||
DataTable dt = ToDdateTable(datas);
|
|
||||||
IFastBuilder buider = GetBuider();
|
|
||||||
buider.Context = context;
|
|
||||||
if (buider?.DbFastestProperties?.IsMerge == true)
|
|
||||||
{
|
{
|
||||||
await buider.CreateTempAsync<T>(dt);
|
Begin(datas, false, true);
|
||||||
await buider.ExecuteBulkCopyAsync(dt);
|
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
||||||
|
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
||||||
|
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
||||||
|
DataTable dt = ToDdateTable(datas);
|
||||||
|
IFastBuilder buider = GetBuider();
|
||||||
|
buider.Context = context;
|
||||||
|
if (buider?.DbFastestProperties?.IsMerge == true)
|
||||||
|
{
|
||||||
|
await buider.CreateTempAsync<T>(dt);
|
||||||
|
await buider.ExecuteBulkCopyAsync(dt);
|
||||||
|
}
|
||||||
|
var result = await buider.Merge(GetTableName(), dt, this.entityInfo, whereColumns, updateColumns, datas);
|
||||||
|
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
||||||
|
//var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
||||||
|
if (buider?.DbFastestProperties?.IsMerge == true && this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
||||||
|
{
|
||||||
|
this.context.DbMaintenance.DropTable(dt.TableName);
|
||||||
|
}
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
||||||
|
buider.CloseDb();
|
||||||
|
End(datas, false, true);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
var result = await buider.Merge(GetTableName(),dt, this.entityInfo,whereColumns,updateColumns, datas);
|
catch (Exception)
|
||||||
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
|
||||||
//var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
|
||||||
if (buider?.DbFastestProperties?.IsMerge == true&&this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
|
||||||
{
|
{
|
||||||
this.context.DbMaintenance.DropTable(dt.TableName);
|
this.context.Close();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
|
||||||
buider.CloseDb();
|
|
||||||
End(datas, false,true);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Core
|
#region Core
|
||||||
private async Task<int> _BulkUpdate(List<T> datas, string[] whereColumns, string[] updateColumns)
|
private async Task<int> _BulkUpdate(List<T> datas, string[] whereColumns, string[] updateColumns)
|
||||||
{
|
{
|
||||||
Begin(datas,false);
|
try
|
||||||
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
|
||||||
Check.Exception(updateColumns == null || updateColumns.Count() == 0, "set columns count=0");
|
|
||||||
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
|
||||||
DataTable dt = ToDdateTable(datas);
|
|
||||||
IFastBuilder buider = GetBuider();
|
|
||||||
ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns);
|
|
||||||
buider.Context = context;
|
|
||||||
await buider.CreateTempAsync<T>(dt);
|
|
||||||
await buider.ExecuteBulkCopyAsync(dt);
|
|
||||||
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
|
||||||
var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
|
||||||
if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
|
||||||
{
|
{
|
||||||
this.context.DbMaintenance.DropTable(dt.TableName);
|
Begin(datas, false);
|
||||||
|
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
||||||
|
Check.Exception(updateColumns == null || updateColumns.Count() == 0, "set columns count=0");
|
||||||
|
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
||||||
|
DataTable dt = ToDdateTable(datas);
|
||||||
|
IFastBuilder buider = GetBuider();
|
||||||
|
ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns);
|
||||||
|
buider.Context = context;
|
||||||
|
await buider.CreateTempAsync<T>(dt);
|
||||||
|
await buider.ExecuteBulkCopyAsync(dt);
|
||||||
|
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
||||||
|
var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
||||||
|
if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
||||||
|
{
|
||||||
|
this.context.DbMaintenance.DropTable(dt.TableName);
|
||||||
|
}
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
||||||
|
buider.CloseDb();
|
||||||
|
End(datas, false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
this.context.Close();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
|
||||||
buider.CloseDb();
|
|
||||||
End(datas, false);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ActionIgnoreColums(string[] whereColumns, string[] updateColumns, DataTable dt,bool IsActionUpdateColumns)
|
private void ActionIgnoreColums(string[] whereColumns, string[] updateColumns, DataTable dt,bool IsActionUpdateColumns)
|
||||||
|
@@ -681,6 +681,12 @@ namespace SqlSugar
|
|||||||
var entityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(joinInfo.EntityType);
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(joinInfo.EntityType);
|
||||||
result = $" {result} AND {shortName}.{UtilMethods.GetDiscrimator(entityInfo,this.Builder)}";
|
result = $" {result} AND {shortName}.{UtilMethods.GetDiscrimator(entityInfo,this.Builder)}";
|
||||||
}
|
}
|
||||||
|
if (joinInfo.JoinType == JoinType.Cross)
|
||||||
|
{
|
||||||
|
|
||||||
|
var onIndex=result.IndexOf(" ON ");
|
||||||
|
result = result.Substring(0,onIndex);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public virtual void Clear()
|
public virtual void Clear()
|
||||||
|
@@ -585,7 +585,7 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
var isLast = joinArray.Length == i;
|
var isLast = joinArray.Length == i;
|
||||||
var isJoinType = item.IsIn(JoinType.Full.ToString(),JoinType.Inner.ToString(), JoinType.Left.ToString(), JoinType.Right.ToString());
|
var isJoinType = item.IsIn(JoinType.Full.ToString(),JoinType.Inner.ToString(), JoinType.Left.ToString(), JoinType.Right.ToString(),JoinType.Cross.ToString());
|
||||||
if (isJoinType)
|
if (isJoinType)
|
||||||
{
|
{
|
||||||
if (joinValue != null)
|
if (joinValue != null)
|
||||||
|
@@ -726,14 +726,21 @@ namespace SqlSugar
|
|||||||
item.Columns = new List<DiffLogColumnInfo>();
|
item.Columns = new List<DiffLogColumnInfo>();
|
||||||
foreach (DataColumn col in dt.Columns)
|
foreach (DataColumn col in dt.Columns)
|
||||||
{
|
{
|
||||||
var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it =>
|
try
|
||||||
it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase));
|
{
|
||||||
DiffLogColumnInfo addItem = new DiffLogColumnInfo();
|
var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it =>
|
||||||
addItem.Value = row[col.ColumnName];
|
it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase));
|
||||||
addItem.ColumnName = col.ColumnName;
|
DiffLogColumnInfo addItem = new DiffLogColumnInfo();
|
||||||
addItem.IsPrimaryKey = sugarColumn.IsPrimarykey;
|
addItem.Value = row[col.ColumnName];
|
||||||
addItem.ColumnDescription = sugarColumn.ColumnDescription;
|
addItem.ColumnName = col.ColumnName;
|
||||||
item.Columns.Add(addItem);
|
addItem.IsPrimaryKey = sugarColumn.IsPrimarykey;
|
||||||
|
addItem.ColumnDescription = sugarColumn.ColumnDescription;
|
||||||
|
item.Columns.Add(addItem);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Check.ExceptionEasy(col.ColumnName + " No corresponding entity attribute found in difference log ."+ex.Message, col.ColumnName + "在差异日志中可能没有找到相应的实体属性,详细:"+ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.Add(item);
|
result.Add(item);
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ namespace SqlSugar
|
|||||||
Inner = 0,
|
Inner = 0,
|
||||||
Left = 1,
|
Left = 1,
|
||||||
Right = 2,
|
Right = 2,
|
||||||
Full=3
|
Full=3,
|
||||||
|
Cross
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1030,7 +1030,7 @@ namespace SqlSugar
|
|||||||
var newValue = "null";
|
var newValue = "null";
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
if (UtilMethods.IsNumber(columnInfo.UnderType.Name))
|
if (columnInfo.DbTableName!= "String" && UtilMethods.IsNumber(columnInfo.UnderType.Name))
|
||||||
{
|
{
|
||||||
newValue = value.ToString();
|
newValue = value.ToString();
|
||||||
}
|
}
|
||||||
|
@@ -446,14 +446,38 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public Subqueryable<T1, T2, T3> OrderBy(Func<T1, T2, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public new Subqueryable<T1, T2, T3> OrderBy(Func<T1, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1, T2,T3> OrderByDesc(Func<T1, T2,T3, object> expression)
|
public Subqueryable<T1, T2,T3> OrderByDesc(Func<T1, T2,T3, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public Subqueryable<T1, T2, T3> OrderByDesc(Func<T1, T2, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public new Subqueryable<T1, T2, T3> OrderByDesc(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1, T2,T3> GroupBy(Func<T1, T2,T3, object> expression)
|
public Subqueryable<T1, T2,T3> GroupBy(Func<T1, T2,T3, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public Subqueryable<T1, T2, T3> GroupBy(Func<T1, T2, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public new Subqueryable<T1, T2, T3> GroupBy(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public TResult Select<TResult>(Func<T1, T2,T3, TResult> expression) where TResult : struct
|
public TResult Select<TResult>(Func<T1, T2,T3, TResult> expression) where TResult : struct
|
||||||
{
|
{
|
||||||
return default(TResult);
|
return default(TResult);
|
||||||
@@ -550,14 +574,26 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public new Subqueryable<T1, T2> OrderBy(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1,T2> OrderByDesc(Func<T1,T2, object> expression)
|
public Subqueryable<T1,T2> OrderByDesc(Func<T1,T2, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public new Subqueryable<T1, T2> OrderByDesc(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1,T2> GroupBy(Func<T1,T2, object> expression)
|
public Subqueryable<T1,T2> GroupBy(Func<T1,T2, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public new Subqueryable<T1, T2> GroupBy(Func<T1, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1,T2> WhereIF(bool isWhere, Func<T1, T2, bool> expression)
|
public Subqueryable<T1,T2> WhereIF(bool isWhere, Func<T1, T2, bool> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@@ -460,7 +460,6 @@
|
|||||||
<Compile Include="Utilities\CallContext.cs" />
|
<Compile Include="Utilities\CallContext.cs" />
|
||||||
<Compile Include="Utilities\CallContextAsync.cs" />
|
<Compile Include="Utilities\CallContextAsync.cs" />
|
||||||
<Compile Include="Abstract\DynamicBuilder\DynamicBuilderHelper.cs" />
|
<Compile Include="Abstract\DynamicBuilder\DynamicBuilderHelper.cs" />
|
||||||
<Compile Include="Utilities\PivotHelper.cs" />
|
|
||||||
<Compile Include="Utilities\FastCopy.cs" />
|
<Compile Include="Utilities\FastCopy.cs" />
|
||||||
<Compile Include="Utilities\ExpressionBuilderHelper.cs" />
|
<Compile Include="Utilities\ExpressionBuilderHelper.cs" />
|
||||||
<Compile Include="Utilities\CommonExtensions.cs" />
|
<Compile Include="Utilities\CommonExtensions.cs" />
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>SqlSugar</id>
|
<id>SqlSugar</id>
|
||||||
<version>5.1.4.131</version>
|
<version>5.1.4.133-preview03</version>
|
||||||
<title>.Net Framework 安装此版本, 5.0.3.3-max 最低要求 .Net Framework 4.6 | 5.0.0.2-5.0.3.2 最低要求 .Net Framework 4.5 | 4.0-4.9.11 最低要求 .Net Framework 4.0+ .NET ORM </title>
|
<title>.Net Framework 安装此版本, 5.0.3.3-max 最低要求 .Net Framework 4.6 | 5.0.0.2-5.0.3.2 最低要求 .Net Framework 4.5 | 4.0-4.9.11 最低要求 .Net Framework 4.0+ .NET ORM </title>
|
||||||
<authors>sun kaixuan</authors>
|
<authors>sun kaixuan</authors>
|
||||||
<owners>landa</owners>
|
<owners>landa</owners>
|
||||||
|
@@ -1,129 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.Dynamic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SqlSugar
|
|
||||||
{
|
|
||||||
internal static class PivotHelper
|
|
||||||
{
|
|
||||||
public static DataTable ToPivotTable<T, TColumn, TRow, TData>(
|
|
||||||
IEnumerable<T> source,
|
|
||||||
Func<T, TColumn> columnSelector,
|
|
||||||
Expression<Func<T, TRow>> rowSelector,
|
|
||||||
Func<IEnumerable<T>, TData> dataSelector)
|
|
||||||
{
|
|
||||||
DataTable table = new DataTable();
|
|
||||||
var rowName = "";
|
|
||||||
if (rowSelector.Body is MemberExpression)
|
|
||||||
rowName = ((MemberExpression)rowSelector.Body).Member.Name;
|
|
||||||
else
|
|
||||||
rowName = string.Join(UtilConstants.ReplaceKey, ((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.Member.Name));
|
|
||||||
table.Columns.Add(new DataColumn(rowName));
|
|
||||||
var columns = source.Select(columnSelector).Distinct();
|
|
||||||
|
|
||||||
foreach (var column in columns)
|
|
||||||
table.Columns.Add(new DataColumn(column?.ToString()));
|
|
||||||
|
|
||||||
var rows = source.GroupBy(rowSelector.Compile())
|
|
||||||
.Select(rowGroup => new
|
|
||||||
{
|
|
||||||
Key = rowGroup.Key,
|
|
||||||
Values = columns.GroupJoin(
|
|
||||||
rowGroup,
|
|
||||||
c => c,
|
|
||||||
r => columnSelector(r),
|
|
||||||
(c, columnGroup) => dataSelector(columnGroup))
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var row in rows)
|
|
||||||
{
|
|
||||||
var dataRow = table.NewRow();
|
|
||||||
var items = row.Values.Cast<object>().ToList();
|
|
||||||
items.Insert(0, row.Key);
|
|
||||||
dataRow.ItemArray = items.ToArray();
|
|
||||||
table.Rows.Add(dataRow);
|
|
||||||
}
|
|
||||||
var firstName = table.Columns[0]?.ColumnName;
|
|
||||||
if (firstName.ObjToString().Contains(UtilConstants.ReplaceKey))
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
foreach (var item in Regex.Split(firstName, UtilConstants.ReplaceKey))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
table.Columns.Add(item);
|
|
||||||
table.Columns[item].SetOrdinal(i);
|
|
||||||
}
|
|
||||||
foreach (DataRow row in table.Rows)
|
|
||||||
{
|
|
||||||
var json = row[firstName];
|
|
||||||
var list = json.ToString().TrimStart('{', ' ').TrimEnd('}', ' ')
|
|
||||||
.Split(new[] { ", " }, StringSplitOptions.None)
|
|
||||||
.Select(it => it.Split(new[] { " = " }, StringSplitOptions.None)).ToList();
|
|
||||||
foreach (var item in Regex.Split(firstName, UtilConstants.ReplaceKey))
|
|
||||||
{
|
|
||||||
var x = list.First(it => it.First().Trim() == item.Trim());
|
|
||||||
row[item] = x[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table.Columns.Remove(firstName);
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
public static List<dynamic> ToPivotList<T, TColumn, TRow, TData>(
|
|
||||||
IEnumerable<T> source,
|
|
||||||
Func<T, TColumn> columnSelector,
|
|
||||||
Expression<Func<T, TRow>> rowSelector,
|
|
||||||
Func<IEnumerable<T>, TData> dataSelector)
|
|
||||||
{
|
|
||||||
|
|
||||||
var arr = new List<object>();
|
|
||||||
var cols = new List<string>();
|
|
||||||
var rowName = "";
|
|
||||||
if (rowSelector.Body is MemberExpression)
|
|
||||||
rowName = ((MemberExpression)rowSelector.Body).Member.Name;
|
|
||||||
else
|
|
||||||
rowName = "Group_" + string.Join("_", ((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.Member.Name));
|
|
||||||
var columns = source.Select(columnSelector).Distinct();
|
|
||||||
|
|
||||||
cols = (new[] { rowName }).Concat(columns.Select(x => x?.ToString())).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
var rows = source.GroupBy(rowSelector.Compile())
|
|
||||||
.Select(rowGroup => new
|
|
||||||
{
|
|
||||||
Key = rowGroup.Key,
|
|
||||||
Values = columns.GroupJoin(
|
|
||||||
rowGroup,
|
|
||||||
c => c,
|
|
||||||
r => columnSelector(r),
|
|
||||||
(c, columnGroup) => dataSelector(columnGroup))
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var row in rows)
|
|
||||||
{
|
|
||||||
var items = row.Values.Cast<object>().ToList();
|
|
||||||
items.Insert(0, row.Key);
|
|
||||||
var obj = GetAnonymousObject(cols, items);
|
|
||||||
arr.Add(obj);
|
|
||||||
}
|
|
||||||
return arr.ToList();
|
|
||||||
}
|
|
||||||
private static dynamic GetAnonymousObject(IEnumerable<string> columns, IEnumerable<object> values)
|
|
||||||
{
|
|
||||||
IDictionary<string, object> eo = new ExpandoObject() as IDictionary<string, object>;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < columns.Count(); i++)
|
|
||||||
{
|
|
||||||
eo.Add(columns.ElementAt<string>(i), values.ElementAt<object>(i));
|
|
||||||
}
|
|
||||||
return eo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -209,57 +209,73 @@ namespace SqlSugar
|
|||||||
|
|
||||||
private async Task<int> _BulkMerge(List<T> datas, string[] updateColumns, string[] whereColumns)
|
private async Task<int> _BulkMerge(List<T> datas, string[] updateColumns, string[] whereColumns)
|
||||||
{
|
{
|
||||||
Begin(datas, false,true);
|
try
|
||||||
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
|
||||||
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
|
||||||
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
|
||||||
DataTable dt = ToDdateTable(datas);
|
|
||||||
IFastBuilder buider = GetBuider();
|
|
||||||
buider.Context = context;
|
|
||||||
if (buider?.DbFastestProperties?.IsMerge == true)
|
|
||||||
{
|
{
|
||||||
await buider.CreateTempAsync<T>(dt);
|
Begin(datas, false, true);
|
||||||
await buider.ExecuteBulkCopyAsync(dt);
|
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
||||||
|
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
||||||
|
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
||||||
|
DataTable dt = ToDdateTable(datas);
|
||||||
|
IFastBuilder buider = GetBuider();
|
||||||
|
buider.Context = context;
|
||||||
|
if (buider?.DbFastestProperties?.IsMerge == true)
|
||||||
|
{
|
||||||
|
await buider.CreateTempAsync<T>(dt);
|
||||||
|
await buider.ExecuteBulkCopyAsync(dt);
|
||||||
|
}
|
||||||
|
var result = await buider.Merge(GetTableName(), dt, this.entityInfo, whereColumns, updateColumns, datas);
|
||||||
|
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
||||||
|
//var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
||||||
|
if (buider?.DbFastestProperties?.IsMerge == true && this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
||||||
|
{
|
||||||
|
this.context.DbMaintenance.DropTable(dt.TableName);
|
||||||
|
}
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
||||||
|
buider.CloseDb();
|
||||||
|
End(datas, false, true);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
var result = await buider.Merge(GetTableName(),dt, this.entityInfo,whereColumns,updateColumns, datas);
|
catch (Exception)
|
||||||
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
|
||||||
//var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
|
||||||
if (buider?.DbFastestProperties?.IsMerge == true&&this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
|
||||||
{
|
{
|
||||||
this.context.DbMaintenance.DropTable(dt.TableName);
|
this.context.Close();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
|
||||||
buider.CloseDb();
|
|
||||||
End(datas, false,true);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Core
|
#region Core
|
||||||
private async Task<int> _BulkUpdate(List<T> datas, string[] whereColumns, string[] updateColumns)
|
private async Task<int> _BulkUpdate(List<T> datas, string[] whereColumns, string[] updateColumns)
|
||||||
{
|
{
|
||||||
Begin(datas,false);
|
try
|
||||||
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
|
||||||
Check.Exception(updateColumns == null || updateColumns.Count() == 0, "set columns count=0");
|
|
||||||
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
|
||||||
DataTable dt = ToDdateTable(datas);
|
|
||||||
IFastBuilder buider = GetBuider();
|
|
||||||
ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns);
|
|
||||||
buider.Context = context;
|
|
||||||
await buider.CreateTempAsync<T>(dt);
|
|
||||||
await buider.ExecuteBulkCopyAsync(dt);
|
|
||||||
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
|
||||||
var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
|
||||||
if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
|
||||||
{
|
{
|
||||||
this.context.DbMaintenance.DropTable(dt.TableName);
|
Begin(datas, false);
|
||||||
|
Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key");
|
||||||
|
Check.Exception(updateColumns == null || updateColumns.Count() == 0, "set columns count=0");
|
||||||
|
var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
||||||
|
DataTable dt = ToDdateTable(datas);
|
||||||
|
IFastBuilder buider = GetBuider();
|
||||||
|
ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns);
|
||||||
|
buider.Context = context;
|
||||||
|
await buider.CreateTempAsync<T>(dt);
|
||||||
|
await buider.ExecuteBulkCopyAsync(dt);
|
||||||
|
//var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
|
||||||
|
var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
|
||||||
|
if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
|
||||||
|
{
|
||||||
|
this.context.DbMaintenance.DropTable(dt.TableName);
|
||||||
|
}
|
||||||
|
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
||||||
|
buider.CloseDb();
|
||||||
|
End(datas, false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
this.context.Close();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
|
||||||
buider.CloseDb();
|
|
||||||
End(datas, false);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ActionIgnoreColums(string[] whereColumns, string[] updateColumns, DataTable dt,bool IsActionUpdateColumns)
|
private void ActionIgnoreColums(string[] whereColumns, string[] updateColumns, DataTable dt,bool IsActionUpdateColumns)
|
||||||
|
@@ -681,6 +681,12 @@ namespace SqlSugar
|
|||||||
var entityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(joinInfo.EntityType);
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfoWithAttr(joinInfo.EntityType);
|
||||||
result = $" {result} AND {shortName}.{UtilMethods.GetDiscrimator(entityInfo,this.Builder)}";
|
result = $" {result} AND {shortName}.{UtilMethods.GetDiscrimator(entityInfo,this.Builder)}";
|
||||||
}
|
}
|
||||||
|
if (joinInfo.JoinType == JoinType.Cross)
|
||||||
|
{
|
||||||
|
|
||||||
|
var onIndex=result.IndexOf(" ON ");
|
||||||
|
result = result.Substring(0,onIndex);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public virtual void Clear()
|
public virtual void Clear()
|
||||||
|
@@ -585,7 +585,7 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
var isLast = joinArray.Length == i;
|
var isLast = joinArray.Length == i;
|
||||||
var isJoinType = item.IsIn(JoinType.Full.ToString(),JoinType.Inner.ToString(), JoinType.Left.ToString(), JoinType.Right.ToString());
|
var isJoinType = item.IsIn(JoinType.Full.ToString(),JoinType.Inner.ToString(), JoinType.Left.ToString(), JoinType.Right.ToString(),JoinType.Cross.ToString());
|
||||||
if (isJoinType)
|
if (isJoinType)
|
||||||
{
|
{
|
||||||
if (joinValue != null)
|
if (joinValue != null)
|
||||||
|
@@ -726,14 +726,21 @@ namespace SqlSugar
|
|||||||
item.Columns = new List<DiffLogColumnInfo>();
|
item.Columns = new List<DiffLogColumnInfo>();
|
||||||
foreach (DataColumn col in dt.Columns)
|
foreach (DataColumn col in dt.Columns)
|
||||||
{
|
{
|
||||||
var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it =>
|
try
|
||||||
it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase));
|
{
|
||||||
DiffLogColumnInfo addItem = new DiffLogColumnInfo();
|
var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it =>
|
||||||
addItem.Value = row[col.ColumnName];
|
it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase));
|
||||||
addItem.ColumnName = col.ColumnName;
|
DiffLogColumnInfo addItem = new DiffLogColumnInfo();
|
||||||
addItem.IsPrimaryKey = sugarColumn.IsPrimarykey;
|
addItem.Value = row[col.ColumnName];
|
||||||
addItem.ColumnDescription = sugarColumn.ColumnDescription;
|
addItem.ColumnName = col.ColumnName;
|
||||||
item.Columns.Add(addItem);
|
addItem.IsPrimaryKey = sugarColumn.IsPrimarykey;
|
||||||
|
addItem.ColumnDescription = sugarColumn.ColumnDescription;
|
||||||
|
item.Columns.Add(addItem);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Check.ExceptionEasy(col.ColumnName + " No corresponding entity attribute found in difference log ."+ex.Message, col.ColumnName + "在差异日志中可能没有找到相应的实体属性,详细:"+ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.Add(item);
|
result.Add(item);
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ namespace SqlSugar
|
|||||||
Inner = 0,
|
Inner = 0,
|
||||||
Left = 1,
|
Left = 1,
|
||||||
Right = 2,
|
Right = 2,
|
||||||
Full=3
|
Full=3,
|
||||||
|
Cross
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1030,7 +1030,7 @@ namespace SqlSugar
|
|||||||
var newValue = "null";
|
var newValue = "null";
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
if (UtilMethods.IsNumber(columnInfo.UnderType.Name))
|
if (columnInfo.DbTableName!= "String" && UtilMethods.IsNumber(columnInfo.UnderType.Name))
|
||||||
{
|
{
|
||||||
newValue = value.ToString();
|
newValue = value.ToString();
|
||||||
}
|
}
|
||||||
|
@@ -446,14 +446,38 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public Subqueryable<T1, T2, T3> OrderBy(Func<T1, T2, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public new Subqueryable<T1, T2, T3> OrderBy(Func<T1, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1, T2,T3> OrderByDesc(Func<T1, T2,T3, object> expression)
|
public Subqueryable<T1, T2,T3> OrderByDesc(Func<T1, T2,T3, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public Subqueryable<T1, T2, T3> OrderByDesc(Func<T1, T2, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public new Subqueryable<T1, T2, T3> OrderByDesc(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1, T2,T3> GroupBy(Func<T1, T2,T3, object> expression)
|
public Subqueryable<T1, T2,T3> GroupBy(Func<T1, T2,T3, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public Subqueryable<T1, T2, T3> GroupBy(Func<T1, T2, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public new Subqueryable<T1, T2, T3> GroupBy(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public TResult Select<TResult>(Func<T1, T2,T3, TResult> expression) where TResult : struct
|
public TResult Select<TResult>(Func<T1, T2,T3, TResult> expression) where TResult : struct
|
||||||
{
|
{
|
||||||
return default(TResult);
|
return default(TResult);
|
||||||
@@ -550,14 +574,26 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public new Subqueryable<T1, T2> OrderBy(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1,T2> OrderByDesc(Func<T1,T2, object> expression)
|
public Subqueryable<T1,T2> OrderByDesc(Func<T1,T2, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public new Subqueryable<T1, T2> OrderByDesc(Func<T1,object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1,T2> GroupBy(Func<T1,T2, object> expression)
|
public Subqueryable<T1,T2> GroupBy(Func<T1,T2, object> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public new Subqueryable<T1, T2> GroupBy(Func<T1, object> expression)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public Subqueryable<T1,T2> WhereIF(bool isWhere, Func<T1, T2, bool> expression)
|
public Subqueryable<T1,T2> WhereIF(bool isWhere, Func<T1, T2, bool> expression)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@@ -1,129 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.Dynamic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SqlSugar
|
|
||||||
{
|
|
||||||
internal static class PivotHelper
|
|
||||||
{
|
|
||||||
public static DataTable ToPivotTable<T, TColumn, TRow, TData>(
|
|
||||||
IEnumerable<T> source,
|
|
||||||
Func<T, TColumn> columnSelector,
|
|
||||||
Expression<Func<T, TRow>> rowSelector,
|
|
||||||
Func<IEnumerable<T>, TData> dataSelector)
|
|
||||||
{
|
|
||||||
DataTable table = new DataTable();
|
|
||||||
var rowName = "";
|
|
||||||
if (rowSelector.Body is MemberExpression)
|
|
||||||
rowName = ((MemberExpression)rowSelector.Body).Member.Name;
|
|
||||||
else
|
|
||||||
rowName = string.Join(UtilConstants.ReplaceKey, ((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.Member.Name));
|
|
||||||
table.Columns.Add(new DataColumn(rowName));
|
|
||||||
var columns = source.Select(columnSelector).Distinct();
|
|
||||||
|
|
||||||
foreach (var column in columns)
|
|
||||||
table.Columns.Add(new DataColumn(column?.ToString()));
|
|
||||||
|
|
||||||
var rows = source.GroupBy(rowSelector.Compile())
|
|
||||||
.Select(rowGroup => new
|
|
||||||
{
|
|
||||||
Key = rowGroup.Key,
|
|
||||||
Values = columns.GroupJoin(
|
|
||||||
rowGroup,
|
|
||||||
c => c,
|
|
||||||
r => columnSelector(r),
|
|
||||||
(c, columnGroup) => dataSelector(columnGroup))
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var row in rows)
|
|
||||||
{
|
|
||||||
var dataRow = table.NewRow();
|
|
||||||
var items = row.Values.Cast<object>().ToList();
|
|
||||||
items.Insert(0, row.Key);
|
|
||||||
dataRow.ItemArray = items.ToArray();
|
|
||||||
table.Rows.Add(dataRow);
|
|
||||||
}
|
|
||||||
var firstName = table.Columns[0]?.ColumnName;
|
|
||||||
if (firstName.ObjToString().Contains(UtilConstants.ReplaceKey))
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
foreach (var item in Regex.Split(firstName, UtilConstants.ReplaceKey))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
table.Columns.Add(item);
|
|
||||||
table.Columns[item].SetOrdinal(i);
|
|
||||||
}
|
|
||||||
foreach (DataRow row in table.Rows)
|
|
||||||
{
|
|
||||||
var json = row[firstName];
|
|
||||||
var list = json.ToString().TrimStart('{', ' ').TrimEnd('}', ' ')
|
|
||||||
.Split(new[] { ", " }, StringSplitOptions.None)
|
|
||||||
.Select(it => it.Split(new[] { " = " }, StringSplitOptions.None)).ToList();
|
|
||||||
foreach (var item in Regex.Split(firstName, UtilConstants.ReplaceKey))
|
|
||||||
{
|
|
||||||
var x = list.First(it => it.First().Trim() == item.Trim());
|
|
||||||
row[item] = x[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table.Columns.Remove(firstName);
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
public static List<dynamic> ToPivotList<T, TColumn, TRow, TData>(
|
|
||||||
IEnumerable<T> source,
|
|
||||||
Func<T, TColumn> columnSelector,
|
|
||||||
Expression<Func<T, TRow>> rowSelector,
|
|
||||||
Func<IEnumerable<T>, TData> dataSelector)
|
|
||||||
{
|
|
||||||
|
|
||||||
var arr = new List<object>();
|
|
||||||
var cols = new List<string>();
|
|
||||||
var rowName = "";
|
|
||||||
if (rowSelector.Body is MemberExpression)
|
|
||||||
rowName = ((MemberExpression)rowSelector.Body).Member.Name;
|
|
||||||
else
|
|
||||||
rowName = "Group_" + string.Join("_", ((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.Member.Name));
|
|
||||||
var columns = source.Select(columnSelector).Distinct();
|
|
||||||
|
|
||||||
cols = (new[] { rowName }).Concat(columns.Select(x => x?.ToString())).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
var rows = source.GroupBy(rowSelector.Compile())
|
|
||||||
.Select(rowGroup => new
|
|
||||||
{
|
|
||||||
Key = rowGroup.Key,
|
|
||||||
Values = columns.GroupJoin(
|
|
||||||
rowGroup,
|
|
||||||
c => c,
|
|
||||||
r => columnSelector(r),
|
|
||||||
(c, columnGroup) => dataSelector(columnGroup))
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var row in rows)
|
|
||||||
{
|
|
||||||
var items = row.Values.Cast<object>().ToList();
|
|
||||||
items.Insert(0, row.Key);
|
|
||||||
var obj = GetAnonymousObject(cols, items);
|
|
||||||
arr.Add(obj);
|
|
||||||
}
|
|
||||||
return arr.ToList();
|
|
||||||
}
|
|
||||||
private static dynamic GetAnonymousObject(IEnumerable<string> columns, IEnumerable<object> values)
|
|
||||||
{
|
|
||||||
IDictionary<string, object> eo = new ExpandoObject() as IDictionary<string, object>;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < columns.Count(); i++)
|
|
||||||
{
|
|
||||||
eo.Add(columns.ElementAt<string>(i), values.ElementAt<object>(i));
|
|
||||||
}
|
|
||||||
return eo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user