mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-09-23 12:33:44 +08:00
Synchronization code
This commit is contained in:
@@ -10,6 +10,9 @@ using System.Reflection;
|
|||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using NetTaste;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace SqlSugar
|
namespace SqlSugar
|
||||||
{
|
{
|
||||||
@@ -1159,8 +1162,12 @@ namespace SqlSugar
|
|||||||
RestoreMapping();
|
RestoreMapping();
|
||||||
_Mapper(result);
|
_Mapper(result);
|
||||||
_InitNavigat(result);
|
_InitNavigat(result);
|
||||||
|
_SubQuery(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected async Task<List<TResult>> _ToListAsync<TResult>()
|
protected async Task<List<TResult>> _ToListAsync<TResult>()
|
||||||
{
|
{
|
||||||
List<TResult> result = null;
|
List<TResult> result = null;
|
||||||
@@ -1177,6 +1184,7 @@ namespace SqlSugar
|
|||||||
RestoreMapping();
|
RestoreMapping();
|
||||||
_Mapper(result);
|
_Mapper(result);
|
||||||
await _InitNavigatAsync(result);
|
await _InitNavigatAsync(result);
|
||||||
|
await _SubQueryAsync(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
private void ToSqlBefore()
|
private void ToSqlBefore()
|
||||||
@@ -1391,5 +1399,96 @@ namespace SqlSugar
|
|||||||
return new KeyValuePair<string, List<SugarParameter>>(sql, QueryBuilder.Parameters);
|
return new KeyValuePair<string, List<SugarParameter>>(sql, QueryBuilder.Parameters);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Subquery
|
||||||
|
private void _SubQuery<TResult>(List<TResult> result)
|
||||||
|
{
|
||||||
|
var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Any();
|
||||||
|
if (!isSubToList)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection;
|
||||||
|
|
||||||
|
if(!this.Context.Ado.IsAnyTran())
|
||||||
|
this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
|
||||||
|
|
||||||
|
Console.WriteLine("Subquery long link start");
|
||||||
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(this.QueryBuilder.EntityType);
|
||||||
|
foreach (var paramter in this.QueryBuilder.SubToListParameters)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < result.Count; i++)
|
||||||
|
{
|
||||||
|
var ps = this.QueryBuilder.Parameters.ToList();
|
||||||
|
var item = result[i];
|
||||||
|
var sqlPart = paramter.Value.ObjToString();
|
||||||
|
int j = 0;
|
||||||
|
foreach (var column in entityInfo.Columns)
|
||||||
|
{
|
||||||
|
j++;
|
||||||
|
if (column.DbColumnName == null) continue;
|
||||||
|
var isumber = UtilMethods.IsNumber(column.PropertyInfo.PropertyType.Name);
|
||||||
|
var name = this.SqlBuilder.GetTranslationColumnName(this.QueryBuilder.TableShortName) + "." + this.SqlBuilder.GetTranslationColumnName(column.DbColumnName);
|
||||||
|
var guid = Guid.NewGuid() + "-" + Guid.NewGuid();
|
||||||
|
var oldLength = sqlPart.Length;
|
||||||
|
sqlPart = sqlPart.Replace(name, guid);
|
||||||
|
var newLength = sqlPart.Length;
|
||||||
|
if (oldLength != newLength)
|
||||||
|
{
|
||||||
|
PropertyInfo property = item.GetType().GetProperties().FirstOrDefault(it => it.Name.Equals(column.PropertyName));
|
||||||
|
Check.ExceptionEasy(property == null, $"The subquery condition uses {column.PropertyName}, so the Select DTO must have a {column.PropertyName} column", $"子查询条件用到了{column.PropertyName},所以 Select DTO 中必须要有 {column.PropertyName} 列");
|
||||||
|
var parameterName = this.SqlBuilder.SqlParameterKeyWord + "sublistp" +column.PropertyName+ j;
|
||||||
|
var parameter = new SugarParameter(parameterName, property.GetValue(item));
|
||||||
|
ps.Add(parameter);
|
||||||
|
sqlPart = sqlPart.Replace(guid, parameterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//sqlPart = sqlPart.Replace("@SugarlistRowIndex", 0);
|
||||||
|
var methodParamters = new object[] { sqlPart, ps };
|
||||||
|
var itemProperty = item.GetType().GetProperty(paramter.Key);
|
||||||
|
var callType = itemProperty.PropertyType.GetGenericArguments()[0];
|
||||||
|
var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this, "SubQueryList");
|
||||||
|
if (item.GetType().IsAnonymousType())
|
||||||
|
{
|
||||||
|
var jobj = JObject.FromObject(item);
|
||||||
|
var prop = jobj.Property(paramter.Key);
|
||||||
|
prop.Value = JArray.FromObject(subList);
|
||||||
|
result[i] = jobj.ToObject<TResult>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemProperty.SetValue(item, subList);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Console.WriteLine("Subquery long link end");
|
||||||
|
|
||||||
|
if (!this.Context.Ado.IsAnyTran())
|
||||||
|
{
|
||||||
|
this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
|
||||||
|
if (isAuto)
|
||||||
|
{
|
||||||
|
this.Context.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private async Task _SubQueryAsync<TResult>(List<TResult> result)
|
||||||
|
{
|
||||||
|
var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Any();
|
||||||
|
if (!isSubToList)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await Task.Run(() =>{_SubQuery(result);});
|
||||||
|
}
|
||||||
|
public List<Type> SubQueryList<Type>(string sql,object parameters)
|
||||||
|
{
|
||||||
|
return this.Context.Ado.SqlQuery<Type>(sql,parameters);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,7 @@ namespace SqlSugar
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Splicing basic
|
#region Splicing basic
|
||||||
|
public Dictionary<string, object> SubToListParameters { get; set; }
|
||||||
public bool IsCrossQueryWithAttr { get; set; }
|
public bool IsCrossQueryWithAttr { get; set; }
|
||||||
public Dictionary<string,string> CrossQueryItems { get; set; }
|
public Dictionary<string,string> CrossQueryItems { get; set; }
|
||||||
public bool IsSelectSingleFiledJson { get; set; }
|
public bool IsSelectSingleFiledJson { get; set; }
|
||||||
|
@@ -135,6 +135,14 @@ namespace SqlSugar
|
|||||||
var value = GetNewExpressionValue(item);
|
var value = GetNewExpressionValue(item);
|
||||||
parameter.Context.Result.Append($" {value} AS {asName} ");
|
parameter.Context.Result.Append($" {value} AS {asName} ");
|
||||||
}
|
}
|
||||||
|
else if (IsSubToList(item))
|
||||||
|
{
|
||||||
|
var value = GetNewExpressionValue(item);
|
||||||
|
if (this.Context.SugarContext.QueryBuilder.SubToListParameters == null)
|
||||||
|
this.Context.SugarContext.QueryBuilder.SubToListParameters = new Dictionary<string, object>();
|
||||||
|
this.Context.SugarContext.QueryBuilder.SubToListParameters.Add(asName, value);
|
||||||
|
//throw new Exception("子查询ToList开发中..");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
asName = GetAsNameResolveAnObject(parameter, item, asName, isSameType);
|
asName = GetAsNameResolveAnObject(parameter, item, asName, isSameType);
|
||||||
|
@@ -12,6 +12,21 @@ namespace SqlSugar
|
|||||||
public partial class BaseResolve
|
public partial class BaseResolve
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static bool IsSubToList(Expression item)
|
||||||
|
{
|
||||||
|
return ExpressionTool.GetMethodName(item) == "ToList" && IsSubquery(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsSubquery(Expression item)
|
||||||
|
{
|
||||||
|
var method = (item as MethodCallExpression);
|
||||||
|
if (method == null)
|
||||||
|
return false;
|
||||||
|
if (method.Object == null)
|
||||||
|
return false;
|
||||||
|
return method.Object.Type.Name.StartsWith("Subquery");
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsExtSqlFuncObj(Expression item)
|
private bool IsExtSqlFuncObj(Expression item)
|
||||||
{
|
{
|
||||||
return this.Context.SqlFuncServices != null && item is MethodCallExpression && this.Context.SqlFuncServices.Any(it => it.UniqueMethodName == ExpressionTool.GetMethodName(item));
|
return this.Context.SqlFuncServices != null && item is MethodCallExpression && this.Context.SqlFuncServices.Any(it => it.UniqueMethodName == ExpressionTool.GetMethodName(item));
|
||||||
|
@@ -0,0 +1,107 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public class SubToList:ISubOperation
|
||||||
|
{
|
||||||
|
public bool HasWhere
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "ToList";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (exp.Arguments.Count == 0)
|
||||||
|
return "*";
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -37,7 +37,8 @@ namespace SqlSugar
|
|||||||
new SubWithNolock(){ Context=Context },
|
new SubWithNolock(){ Context=Context },
|
||||||
new SubEnableTableFilter(){ Context=Context },
|
new SubEnableTableFilter(){ Context=Context },
|
||||||
new SubSelectStringJoin{ Context=Context },
|
new SubSelectStringJoin{ Context=Context },
|
||||||
new SubDistinctCount{ Context=Context }
|
new SubDistinctCount{ Context=Context },
|
||||||
|
new SubToList{ Context=Context}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -170,5 +170,15 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<T> ToList()
|
||||||
|
{
|
||||||
|
return new List<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TResult> ToList<TResult>(Func<T, TResult> selector) where TResult:class,new()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,27 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
public class ExpressionBuilderHelper
|
public class ExpressionBuilderHelper
|
||||||
{
|
{
|
||||||
|
public static object CallFunc(Type type, object[] param, object methodData, string methodName)
|
||||||
|
{
|
||||||
|
MethodInfo mi = methodData.GetType().GetMethod(methodName).MakeGenericMethod(new Type[] { type });
|
||||||
|
var ret = mi.Invoke(methodData, param);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
public static T CallFunc<T>(object param, object methodData, string methodName)
|
||||||
|
{
|
||||||
|
Type type = param.GetType();
|
||||||
|
MethodInfo mi = methodData.GetType().GetMethod(methodName).MakeGenericMethod(new Type[] { type });
|
||||||
|
var ret = mi.Invoke(methodData, new object[] { param });
|
||||||
|
return (T)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T CallStaticFunc<T>(object param, Type methodType, string methodName)
|
||||||
|
{
|
||||||
|
Type type = param.GetType();
|
||||||
|
MethodInfo mi = methodType.GetMethod(methodName).MakeGenericMethod(new Type[] { type });
|
||||||
|
var ret = mi.Invoke(null, new object[] { param });
|
||||||
|
return (T)ret;
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create Expression
|
/// Create Expression
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Reference in New Issue
Block a user