Synchronization code

This commit is contained in:
sunkaixuan 2023-03-12 17:58:21 +08:00
parent e46aa97f5d
commit b8bd7281a9
9 changed files with 402 additions and 16 deletions

View File

@ -1693,7 +1693,13 @@ namespace SqlSugar
{
var ps = this.QueryBuilder.Parameters;
var itemProperty = typeof(TResult).GetProperty(subPara.Key);
var callType = itemProperty.PropertyType.GetGenericArguments()[0];
var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault();
var isFirst = false;
if (callType == null)
{
callType = itemProperty.PropertyType;
isFirst = true;
}
var sql = subPara.Value.ObjToString().Replace("@sugarIndex", "0");
sql =SqlBuilder.RemoveParentheses(sql);
var methodParamters = new object[] { sql, ps };
@ -1704,14 +1710,31 @@ namespace SqlSugar
var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList;
if (typeof(TResult).IsAnonymousType())
{
var jobj = JObject.FromObject(item);
var prop = jobj.Property(itemProperty.Name);
prop.Value = JArray.FromObject(subList);
result[i] = jobj.ToObject<TResult>();
if (isFirst)
{
var jobj = JObject.FromObject(item);
var prop = jobj.Property(itemProperty.Name);
prop.Value = JObject.FromObject((subList as IList).Cast<object>().FirstOrDefault());
result[i] = jobj.ToObject<TResult>();
}
else
{
var jobj = JObject.FromObject(item);
var prop = jobj.Property(itemProperty.Name);
prop.Value = JArray.FromObject(subList);
result[i] = jobj.ToObject<TResult>();
}
}
else
{
itemProperty.SetValue(item, subList);
if (isFirst)
{
itemProperty.SetValue(item, (subList as IList)[0] );
}
else
{
itemProperty.SetValue(item, subList);
}
}
}
}
@ -1741,10 +1764,14 @@ namespace SqlSugar
index++;
}
var itemProperty = typeof(TResult).GetProperty(subPara.Key);
var callType = itemProperty.PropertyType.GetGenericArguments()[0];
var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault();
var isFirst = false;
if (callType == null)
{
callType = itemProperty.PropertyType;
isFirst = true;
}
var sqlstring = string.Join(" \r\n UNION ALL ", sqls);
var methodParamters = new object[] { sqlstring, ps.ToArray() };
this.QueryBuilder.SubToListParameters = null;
@ -1755,7 +1782,15 @@ namespace SqlSugar
var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList");
var appendValue = this.QueryBuilder.AppendValues;
var list = (subList as IEnumerable).Cast<object>().ToList();
if (typeof(TResult).IsAnonymousType())
if (isFirst && !typeof(TResult).IsAnonymousType())
{
SetSubListWithClassFirst(result, itemProperty, appendValue, list, 0);
}
else if (isFirst && typeof(TResult).IsAnonymousType())
{
SetSubListWithAnonymousTypeFirst(result, itemProperty, appendValue, list, 0);
}
else if (typeof(TResult).IsAnonymousType())
{
SetSubListWithAnonymousType(result, itemProperty, appendValue, list, 0);
}
@ -1791,6 +1826,60 @@ namespace SqlSugar
}
return resIndex;
}
private static int SetSubListWithAnonymousTypeFirst<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> list, int resIndex)
{
for (int i = 0; i < result.Count; i++)
{
var item = result[i];
object setValue = null;
if (appendValue != null)
{
var appindex = 0;
foreach (var appValue in appendValue)
{
if (appValue[0].Value.ObjToInt() == i)
{
setValue = list[appindex];
//setValue.Add(addItem);
}
appindex++;
}
}
var jobj = JObject.FromObject(item);
var prop = jobj.Property(itemProperty.Name);
if (setValue != null)
{
prop.Value = JObject.FromObject(setValue);
}
result[i] = jobj.ToObject<TResult>();
//itemProperty.SetValue(item, setValue);
}
return resIndex;
}
private static int SetSubListWithClassFirst<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> list, int resIndex)
{
foreach (var item in result)
{
//var setValue = Activator.CreateInstance(itemProperty.PropertyType, true);
if (appendValue != null)
{
var appindex = 0;
foreach (var appValue in appendValue)
{
if (appValue[0].Value.ObjToInt() == resIndex)
{
var addItem = list[appindex];
itemProperty.SetValue(item, addItem);
}
appindex++;
}
}
//itemProperty.SetValue(item, setValue);
resIndex++;
}
return resIndex;
}
private static int SetSubListWithClass<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> list, int resIndex)
{

View File

@ -11,14 +11,118 @@ namespace SqlSugar
{
public partial class UpdateableProvider<T> : IUpdateable<T> where T : class, new()
{
private bool IsUpdateNullByList()
{
return this.UpdateObjs.Count() > 1 && (this.UpdateBuilder.IsNoUpdateNull || this.UpdateBuilder.IsNoUpdateDefaultValue);
}
private int DatasTrackingExecommand()
{
var trakRows = 0;
try
{
if (this.Context.Ado.IsNoTran())
{
this.Context.Ado.BeginTran();
}
int i = 0;
foreach (var item in this.UpdateObjs)
{
var newUpdateable = this.Clone();
(newUpdateable as UpdateableProvider<T>).UpdateObjs = new[] { item };
newUpdateable.UpdateBuilder.IsListUpdate = null;
newUpdateable.UpdateBuilder.DbColumnInfoList =
newUpdateable.UpdateBuilder.DbColumnInfoList.Where(it => it.TableId == i).ToList();
AppendTracking(item, newUpdateable);
if (newUpdateable.UpdateBuilder.DbColumnInfoList?.Any() == true)
{
trakRows += newUpdateable.ExecuteCommand();
}
++i;
}
if (this.Context.Ado.IsNoTran())
{
this.Context.Ado.CommitTran();
}
}
catch (Exception)
{
if (this.Context.Ado.IsNoTran())
{
this.Context.Ado.RollbackTran();
}
throw;
}
return trakRows;
}
private async Task<int> DatasTrackingExecommandAsync()
{
var trakRows = 0;
try
{
if (this.Context.Ado.IsNoTran())
{
await this.Context.Ado.BeginTranAsync();
}
int i = 0;
foreach (var item in this.UpdateObjs)
{
var newUpdateable = this.Clone();
(newUpdateable as UpdateableProvider<T>).UpdateObjs = new[] { item };
newUpdateable.UpdateBuilder.IsListUpdate = null;
newUpdateable.UpdateBuilder.DbColumnInfoList =
newUpdateable.UpdateBuilder.DbColumnInfoList.Where(it => it.TableId == i).ToList();
AppendTracking(item, newUpdateable);
if (newUpdateable.UpdateBuilder.DbColumnInfoList?.Any() == true)
{
trakRows +=await newUpdateable.ExecuteCommandAsync();
}
++i;
}
if (this.Context.Ado.IsNoTran())
{
await this.Context.Ado.CommitTranAsync();
}
}
catch (Exception)
{
if (this.Context.Ado.IsNoTran())
{
await this.Context.Ado.RollbackTranAsync();
}
throw;
}
return trakRows;
}
private bool UpdateObjectNotWhere()
{
return this.Context.CurrentConnectionConfig.DbType != DbType.MySql
&& this.Context.CurrentConnectionConfig.DbType != DbType.MySqlConnector
&& this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer;
}
private void AppendTracking(T item, IUpdateable<T> newUpdateable)
{
if (IsTrakingData() || IsTrakingDatas())
{
var trackingData = this.Context.TempItems.FirstOrDefault(it => it.Key.StartsWith("Tracking_" + item.GetHashCode()));
var diffColumns = FastCopy.GetDiff(item, (T)trackingData.Value);
if (diffColumns.Count > 0)
{
var pks = EntityInfo.Columns
.Where(it => it.IsPrimarykey).Select(it => it.PropertyName).ToList();
diffColumns = diffColumns.Where(it => !pks.Contains(it)).ToList();
if (diffColumns.Count > 0)
{
newUpdateable.UpdateColumns(diffColumns.ToArray());
}
}
else
{
(newUpdateable as UpdateableProvider<T>).UpdateObjs = new T[] { null };
newUpdateable.UpdateBuilder.DbColumnInfoList = new List<DbColumnInfo>();
}
}
}
private void AppendSets()
{
if (SetColumnsIndex > 0)
@ -139,6 +243,13 @@ namespace SqlSugar
&& this.UpdateObjs.Length == 1;
}
private bool IsTrakingDatas()
{
return this.UpdateParameterIsNull == false
&& this.Context.TempItems != null
&& this.Context.TempItems.Any(it => it.Key.StartsWith("Tracking_"))
&& this.UpdateObjs.Length > 1;
}
private void DataAop(T item)
{
var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting;

View File

@ -80,6 +80,11 @@ namespace SqlSugar
public virtual int ExecuteCommand()
{
if (this.IsTrakingDatas() || IsUpdateNullByList())
{
int trakRows = DatasTrackingExecommand();
return trakRows;
}
string sql = _ExecuteCommand();
if (string.IsNullOrEmpty(sql))
{
@ -90,6 +95,7 @@ namespace SqlSugar
return result;
}
public bool ExecuteCommandHasChange()
{
return this.ExecuteCommand() > 0;
@ -111,6 +117,11 @@ namespace SqlSugar
public virtual async Task<int> ExecuteCommandAsync()
{
if (this.IsTrakingDatas()||IsUpdateNullByList())
{
int trakRows =await DatasTrackingExecommandAsync();
return trakRows;
}
string sql = _ExecuteCommand();
if (string.IsNullOrEmpty(sql))
{
@ -128,6 +139,46 @@ namespace SqlSugar
#endregion
#region Common
public IUpdateable<T> Clone()
{
this.Context.SugarActionType = SugarActionType.Update;
var result = InstanceFactory.GetUpdateableProvider<T>(this.Context.CurrentConnectionConfig);
var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); ;
result.Context = this.Context;
result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
result.SqlBuilder = sqlBuilder;
result.SqlBuilder.Context = this.Context;
result.UpdateObjs = UpdateObjs;
result.WhereColumnList= this.WhereColumnList;
result.IsWhereColumns = this.IsWhereColumns;
result.IgnoreColumnNameList= this.IgnoreColumnNameList;
result.IsAs = this.IsAs;
result.IsOffIdentity= this.IsOffIdentity;
result.IsEnableDiffLogEvent= this.IsEnableDiffLogEvent;
result.diffModel = this.diffModel;
result.UpdateParameterIsNull= this.UpdateParameterIsNull;
result.RemoveCacheFunc= this.RemoveCacheFunc;
result.SetColumnsIndex = this.SetColumnsIndex;
result.OldMappingTableList= this.OldMappingTableList;
result.MappingColumnList= this.MappingColumnList;
result.columns = this.columns.ToList();
result.UpdateBuilder = InstanceFactory.GetUpdateBuilder(this.Context.CurrentConnectionConfig);
result.UpdateBuilder.Builder = sqlBuilder;
result.UpdateBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig);
result.Context=this.Context;
result.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.ToList();
result.UpdateBuilder.TableName= this.UpdateBuilder.TableName;
result.UpdateBuilder.WhereValues = this.UpdateBuilder.WhereValues.ToList();
result.UpdateBuilder.Parameters= this.UpdateBuilder.Parameters.ToList();
result.UpdateBuilder.IsListUpdate= this.UpdateBuilder.IsListUpdate;
result.UpdateBuilder.IsWhereColumns= this.UpdateBuilder.IsWhereColumns;
result.UpdateBuilder.WhereValues=this.UpdateBuilder.WhereValues.ToList();
result.UpdateBuilder.IsNoUpdateDefaultValue = this.UpdateBuilder.IsNoUpdateDefaultValue;
result.UpdateBuilder.IsNoUpdateNull= this.UpdateBuilder.IsNoUpdateNull;
result.UpdateBuilder.SetValues= this.UpdateBuilder.SetValues.ToList();
result.UpdateBuilder.Context = this.Context;
return result;
}
public IUpdateable<T> With(string lockString)
{
if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer)
@ -227,7 +278,7 @@ namespace SqlSugar
public IUpdateable<T> IgnoreColumns(bool ignoreAllNullColumns, bool isOffIdentity = false, bool ignoreAllDefaultValue = false)
{
Check.Exception(this.UpdateObjs.Count() > 1 && ignoreAllNullColumns, ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert", "ignoreNullColumn 不支持批量操作"));
//Check.Exception(this.UpdateObjs.Count() > 1 && ignoreAllNullColumns, ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert", "ignoreNullColumn 不支持批量操作"));
UpdateBuilder.IsOffIdentity = isOffIdentity;
if (this.UpdateBuilder.LambdaExpressions == null)
this.UpdateBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig);

View File

@ -14,7 +14,7 @@ namespace SqlSugar
private static bool IsSubToList(Expression item)
{
return ExpressionTool.GetMethodName(item) == "ToList" && IsSubquery(item);
return ExpressionTool.GetMethodName(item).IsIn("ToList","First") && IsSubquery(item);
}
private static bool IsSubquery(Expression item)

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public class SubFirst : ISubOperation
{
public bool HasWhere
{
get; set;
}
public string Name
{
get
{
return "First";
}
}
public Expression Expression
{
get; set;
}
public int Sort
{
get
{
return 200;
}
}
public ExpressionContext Context
{
get; set;
}
public string GetValue(Expression expression = null)
{
;
var exp = expression as MethodCallExpression;
InitType(exp);
var type = expression.Type;
if (type.FullName.IsCollectionsList()
&& exp.Arguments.Count == 0 && type.GenericTypeArguments.Length > 0
&& this.Context.SugarContext != null
&& this.Context.SugarContext.QueryBuilder.IsSelectNoAll)
{
var entity = type.GenericTypeArguments[0];
var columnNames = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(entity).Columns;
var columnsString = string.Join(",", columnNames
.Where(it => it.IsIgnore == false)
.Where(it => it.DbColumnName.HasValue())
.Select(it => this.Context.GetTranslationColumnName(it.DbColumnName)));
return $"{columnsString},@sugarIndex as sugarIndex";
}
else if (exp.Arguments.Count == 0)
{
return "*,@sugarIndex as sugarIndex";
}
var argExp = exp.Arguments[0];
var parametres = (argExp as LambdaExpression).Parameters;
if ((argExp as LambdaExpression).Body is UnaryExpression)
{
argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand;
}
var argLambda = argExp as LambdaExpression;
var copyContext = this.Context.GetCopyContextWithMapping();
copyContext.Resolve(argLambda, ResolveExpressType.SelectMultiple);
var select = copyContext.Result.GetString();
this.Context.Parameters.AddRange(copyContext.Parameters);
this.Context.Index = copyContext.Index;
this.Context.ParameterIndex = copyContext.ParameterIndex;
SetShortName(exp, null);
return select + ",@sugarIndex as sugarIndex";
}
private void InitType(MethodCallExpression exp)
{
if (exp.Arguments.Count > 0)
{
foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters)
{
if (this.Context.InitMappingInfo != null)
{
this.Context.InitMappingInfo(arg.Type);
this.Context.RefreshMapping();
}
}
}
}
public void SetShortName(MethodCallExpression exp, string result)
{
if (exp.Arguments[0] is LambdaExpression)
{
var parameters = (exp.Arguments[0] as LambdaExpression).Parameters;
if (parameters != null && parameters.Count > 0)
{
this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString());
}
}
}
public void SetShortNameNext(MethodCallExpression exp, string result)
{
if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression)
{
var parameters = (exp.Arguments[1] as LambdaExpression).Parameters;
if (parameters != null && parameters.Count > 0)
{
this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString());
}
}
}
}
}

View File

@ -223,7 +223,7 @@ namespace SqlSugar
}).ToList();
SetOrderByIndex(isubList);
isubList.Insert(0, new SubBegin());
if (isubList.Any(it => it is SubSelect))
if (isubList.Any(it => it is SubSelect||it is SubFirst))
{
isubList.Add(new SubTop() { Context = this.context });
}

View File

@ -38,7 +38,8 @@ namespace SqlSugar
new SubEnableTableFilter(){ Context=Context },
new SubSelectStringJoin{ Context=Context },
new SubDistinctCount{ Context=Context },
new SubToList{ Context=Context}
new SubToList{ Context=Context},
new SubFirst(){ Context=Context }
};
}

View File

@ -180,5 +180,14 @@ namespace SqlSugar
{
return null;
}
public T First()
{
return default(T);
}
public TResult First<TResult>(Func<T, TResult> selector) where TResult : class, new()
{
return default(TResult);
}
}
}

View File

@ -104,5 +104,6 @@ namespace SqlSugar
SplitTableUpdateProvider<T> SplitTable(Func<List<SplitTableInfo>, IEnumerable<SplitTableInfo>> getTableNamesFunc);
SplitTableUpdateByObjectProvider<T> SplitTable();
IUpdateable<T> EnableQueryFilter();
IUpdateable<T> Clone();
}
}