mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-09-24 04:53:45 +08:00
Update Core
This commit is contained in:
@@ -25,6 +25,7 @@ namespace SqlSugar
|
|||||||
|
|
||||||
private List<Expression> _preExpressionList = new List<Expression>();
|
private List<Expression> _preExpressionList = new List<Expression>();
|
||||||
private List<object> _preList = new List<object>();
|
private List<object> _preList = new List<object>();
|
||||||
|
private List<Expression> _ListCallFunc;
|
||||||
//private Expression[] _expressions;
|
//private Expression[] _expressions;
|
||||||
//private List<T> _list;
|
//private List<T> _list;
|
||||||
//private EntityInfo _entityInfo;
|
//private EntityInfo _entityInfo;
|
||||||
@@ -40,7 +41,7 @@ namespace SqlSugar
|
|||||||
|
|
||||||
private void ExecuteByLay(int i, Expression item)
|
private void ExecuteByLay(int i, Expression item)
|
||||||
{
|
{
|
||||||
|
_ListCallFunc = GetWhereExpression(ref item);
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
{
|
{
|
||||||
ExecuteByLay(item, RootList.Select(it => it as object).ToList(), SelectR1);
|
ExecuteByLay(item, RootList.Select(it => it as object).ToList(), SelectR1);
|
||||||
@@ -88,6 +89,7 @@ namespace SqlSugar
|
|||||||
_preList = list.ToList();
|
_preList = list.ToList();
|
||||||
}
|
}
|
||||||
_preExpressionList.Add(item);
|
_preExpressionList.Add(item);
|
||||||
|
_ListCallFunc = new List<Expression>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteByLay(Expression expression, List<object> list, Func<ISugarQueryable<object>, List<object>> selector)
|
private void ExecuteByLay(Expression expression, List<object> list, Func<ISugarQueryable<object>, List<object>> selector)
|
||||||
@@ -130,6 +132,23 @@ namespace SqlSugar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Expression> GetWhereExpression(ref Expression expression)
|
||||||
|
{
|
||||||
|
List<Expression> expressions = new List<Expression>();
|
||||||
|
var isCall = (expression as LambdaExpression).Body is MethodCallExpression;
|
||||||
|
if (isCall)
|
||||||
|
{
|
||||||
|
var newexp = (expression as LambdaExpression).Body;
|
||||||
|
while (newexp is MethodCallExpression)
|
||||||
|
{
|
||||||
|
expressions.Add(newexp);
|
||||||
|
newexp= (newexp as MethodCallExpression).Arguments[0];
|
||||||
|
}
|
||||||
|
expression =LambdaExpression.Lambda(newexp);
|
||||||
|
}
|
||||||
|
return expressions;
|
||||||
|
}
|
||||||
|
|
||||||
private void ManyToMany(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
|
private void ManyToMany(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
|
||||||
{
|
{
|
||||||
var bEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0];
|
var bEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0];
|
||||||
@@ -159,7 +178,8 @@ namespace SqlSugar
|
|||||||
FieldValue = String.Join(",", abids.Select(it => it.Bid).ToArray()),
|
FieldValue = String.Join(",", abids.Select(it => it.Bid).ToArray()),
|
||||||
CSharpTypeName = bColumn.PropertyInfo.PropertyType.Name
|
CSharpTypeName = bColumn.PropertyInfo.PropertyType.Name
|
||||||
}));
|
}));
|
||||||
var bList = selector(this.Context.Queryable<object>().AS(bEntityInfo.DbTableName).Where(conditionalModels2));
|
var sql = GetWhereSql();
|
||||||
|
var bList = selector(this.Context.Queryable<object>().AS(bEntityInfo.DbTableName).AddParameters(sql.Parameters).Where(conditionalModels2).WhereIF(sql.WhereString.HasValue(),sql.WhereString).OrderByIF(sql.OrderByString.HasValue(),sql.OrderByString));
|
||||||
if (bList.HasValue())
|
if (bList.HasValue())
|
||||||
{
|
{
|
||||||
foreach (var listItem in list)
|
foreach (var listItem in list)
|
||||||
@@ -187,7 +207,7 @@ namespace SqlSugar
|
|||||||
var navType = navObjectNamePropety.PropertyType;
|
var navType = navObjectNamePropety.PropertyType;
|
||||||
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navType);
|
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navType);
|
||||||
var navPkColumn = navEntityInfo.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
|
var navPkColumn = navEntityInfo.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
|
||||||
|
Check.ExceptionEasy(navPkColumn==null, navEntityInfo.EntityName+ "need primarykey", navEntityInfo.EntityName + " 需要主键");
|
||||||
var ids = list.Select(it => it.GetType().GetProperty(navObjectNameColumnInfo.Navigat.Name).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
|
var ids = list.Select(it => it.GetType().GetProperty(navObjectNameColumnInfo.Navigat.Name).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
|
||||||
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
|
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
|
||||||
conditionalModels.Add((new ConditionalModel()
|
conditionalModels.Add((new ConditionalModel()
|
||||||
@@ -212,17 +232,18 @@ namespace SqlSugar
|
|||||||
var navColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
|
var navColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
|
||||||
//var navType = navObjectNamePropety.PropertyType;
|
//var navType = navObjectNamePropety.PropertyType;
|
||||||
var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
|
var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
|
||||||
|
Check.ExceptionEasy(listItemPkColumn == null, listItemEntity.EntityName + " not primary key", listItemEntity.EntityName + "没有主键");
|
||||||
var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
|
var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
|
||||||
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
|
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
|
||||||
conditionalModels.Add((new ConditionalModel()
|
conditionalModels.Add((new ConditionalModel()
|
||||||
{
|
{
|
||||||
ConditionalType = ConditionalType.In,
|
ConditionalType = ConditionalType.In,
|
||||||
FieldName = navObjectNameColumnInfo.Navigat.Name,
|
FieldName = navColumn.DbColumnName,
|
||||||
FieldValue = String.Join(",", ids),
|
FieldValue = String.Join(",", ids),
|
||||||
CSharpTypeName = listItemPkColumn.PropertyInfo.PropertyType.Name
|
CSharpTypeName = listItemPkColumn.PropertyInfo.PropertyType.Name
|
||||||
}));
|
}));
|
||||||
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).Where(conditionalModels));
|
var sqlObj = GetWhereSql();
|
||||||
|
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).AddParameters(sqlObj.Parameters).Where(conditionalModels).WhereIF(sqlObj.WhereString.HasValue(),sqlObj.WhereString).OrderByIF(sqlObj.OrderByString.HasValue(),sqlObj.OrderByString));
|
||||||
if (navList.HasValue())
|
if (navList.HasValue())
|
||||||
{
|
{
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
@@ -239,5 +260,65 @@ namespace SqlSugar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SqlInfo GetWhereSql()
|
||||||
|
{
|
||||||
|
if (_ListCallFunc == null|| _ListCallFunc.Count==0) return new SqlInfo();
|
||||||
|
List<string> where = new List<string>();
|
||||||
|
List<string> oredrBy = new List<string>();
|
||||||
|
_ListCallFunc.Reverse();
|
||||||
|
SqlInfo result = new SqlInfo();
|
||||||
|
result.Parameters = new List<SugarParameter>();
|
||||||
|
var isList = false;
|
||||||
|
foreach (var item in _ListCallFunc)
|
||||||
|
{
|
||||||
|
var method = item as MethodCallExpression;
|
||||||
|
var queryable = this.Context.Queryable<object>();
|
||||||
|
if (method.Method.Name == "Where")
|
||||||
|
{
|
||||||
|
var exp = method.Arguments[1];
|
||||||
|
where.Add(" " +queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString());
|
||||||
|
}
|
||||||
|
else if (method.Method.Name == "OrderBy")
|
||||||
|
{
|
||||||
|
var exp = method.Arguments[1];
|
||||||
|
oredrBy.Add( " "+ queryable.QueryBuilder.GetExpressionValue(exp,ResolveExpressType.WhereSingle).GetString());
|
||||||
|
}
|
||||||
|
else if (method.Method.Name == "OrderByDescending")
|
||||||
|
{
|
||||||
|
var exp = method.Arguments[1];
|
||||||
|
oredrBy.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString()+" DESC");
|
||||||
|
}
|
||||||
|
else if (method.Method.Name == "ToList")
|
||||||
|
{
|
||||||
|
isList = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Check.ExceptionEasy($"no support {item}", $"不支持表达式{item} 不支持方法{method.Method.Name}");
|
||||||
|
}
|
||||||
|
if(queryable.QueryBuilder.Parameters!=null)
|
||||||
|
result.Parameters.AddRange(queryable.QueryBuilder.Parameters);
|
||||||
|
}
|
||||||
|
if (where.Any())
|
||||||
|
{
|
||||||
|
Check.Exception(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList");
|
||||||
|
result.WhereString= String.Join(" AND ", where);
|
||||||
|
}
|
||||||
|
if (oredrBy.Any())
|
||||||
|
{
|
||||||
|
Check.Exception(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList");
|
||||||
|
result.OrderByString = String.Join(" , ", oredrBy);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SqlInfo
|
||||||
|
{
|
||||||
|
public string WhereString { get; set; }
|
||||||
|
public string OrderByString { get; set; }
|
||||||
|
public List<SugarParameter> Parameters { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1420,6 +1420,26 @@ namespace SqlSugar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public virtual async Task ForEachAsync(Action<T> action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null)
|
||||||
|
{
|
||||||
|
Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach"));
|
||||||
|
RefAsync<int> totalNumber = 0;
|
||||||
|
RefAsync<int> totalPage = 1;
|
||||||
|
for (int i = 1; i <= totalPage; i++)
|
||||||
|
{
|
||||||
|
if (cancellationTokenSource?.IsCancellationRequested == true) return;
|
||||||
|
var queryable = this.Clone();
|
||||||
|
var page =
|
||||||
|
totalPage == 1 ?
|
||||||
|
await queryable.ToPageListAsync(i, singleMaxReads, totalNumber, totalPage) :
|
||||||
|
await queryable.ToPageListAsync(i, singleMaxReads);
|
||||||
|
foreach (var item in page)
|
||||||
|
{
|
||||||
|
if (cancellationTokenSource?.IsCancellationRequested == true) return;
|
||||||
|
action.Invoke(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public virtual void ForEachByPage(Action<T> action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null)
|
public virtual void ForEachByPage(Action<T> action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null)
|
||||||
{
|
{
|
||||||
int count = this.Clone().Count();
|
int count = this.Clone().Count();
|
||||||
@@ -1457,6 +1477,43 @@ namespace SqlSugar
|
|||||||
}
|
}
|
||||||
totalNumber = count;
|
totalNumber = count;
|
||||||
}
|
}
|
||||||
|
public virtual async Task ForEachByPageAsync(Action<T> action, int pageIndex, int pageSize,RefAsync<int> totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null)
|
||||||
|
{
|
||||||
|
int count = this.Clone().Count();
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads)
|
||||||
|
{
|
||||||
|
Int32 Skip = (pageIndex - 1) * pageSize;
|
||||||
|
Int32 NowCount = count - Skip;
|
||||||
|
Int32 number = 0;
|
||||||
|
if (NowCount > pageSize) NowCount = pageSize;
|
||||||
|
while (NowCount > 0)
|
||||||
|
{
|
||||||
|
if (cancellationTokenSource?.IsCancellationRequested == true) return;
|
||||||
|
if (number + singleMaxReads > pageSize) singleMaxReads = NowCount;
|
||||||
|
foreach (var item in await this.Clone().Skip(Skip).Take(singleMaxReads).ToListAsync())
|
||||||
|
{
|
||||||
|
if (cancellationTokenSource?.IsCancellationRequested == true) return;
|
||||||
|
action.Invoke(item);
|
||||||
|
}
|
||||||
|
NowCount -= singleMaxReads;
|
||||||
|
Skip += singleMaxReads;
|
||||||
|
number += singleMaxReads;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cancellationTokenSource?.IsCancellationRequested == true) return;
|
||||||
|
foreach (var item in this.Clone().ToPageList(pageIndex, pageSize))
|
||||||
|
{
|
||||||
|
if (cancellationTokenSource?.IsCancellationRequested == true) return;
|
||||||
|
action.Invoke(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalNumber = count;
|
||||||
|
}
|
||||||
|
|
||||||
public List<T> ToOffsetPage(int pageIndex, int pageSize)
|
public List<T> ToOffsetPage(int pageIndex, int pageSize)
|
||||||
{
|
{
|
||||||
@@ -1769,6 +1826,12 @@ namespace SqlSugar
|
|||||||
this.Context.MappingTables = oldMapping;
|
this.Context.MappingTables = oldMapping;
|
||||||
return await this.Clone().ToPageListAsync(pageIndex, pageSize);
|
return await this.Clone().ToPageListAsync(pageIndex, pageSize);
|
||||||
}
|
}
|
||||||
|
public Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber, RefAsync<int> totalPage)
|
||||||
|
{
|
||||||
|
var result = ToPageListAsync(pageNumber, pageSize, totalNumber);
|
||||||
|
totalPage = (totalNumber + pageSize - 1) / pageSize;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
public async Task<string> ToJsonAsync()
|
public async Task<string> ToJsonAsync()
|
||||||
{
|
{
|
||||||
if (IsCache)
|
if (IsCache)
|
||||||
@@ -2248,6 +2311,10 @@ namespace SqlSugar
|
|||||||
if (this.QueryBuilder.Includes != null)
|
if (this.QueryBuilder.Includes != null)
|
||||||
{
|
{
|
||||||
var managers=(this.QueryBuilder.Includes as List<object>);
|
var managers=(this.QueryBuilder.Includes as List<object>);
|
||||||
|
if (this.QueryBuilder.SelectValue.HasValue())
|
||||||
|
{
|
||||||
|
Check.ExceptionEasy("To use includes, use select after tolist()", "使用Includes请在ToList()之后在使用Select");
|
||||||
|
}
|
||||||
foreach (var it in managers)
|
foreach (var it in managers)
|
||||||
{
|
{
|
||||||
var manager = it as NavigatManager<TResult>;
|
var manager = it as NavigatManager<TResult>;
|
||||||
|
@@ -242,6 +242,7 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
resolveExpress.PgSqlIsAutoToLower = true;
|
resolveExpress.PgSqlIsAutoToLower = true;
|
||||||
}
|
}
|
||||||
|
resolveExpress.SugarContext = new ExpressionOutParameter() { Context = this.Context };
|
||||||
resolveExpress.RootExpression = expression;
|
resolveExpress.RootExpression = expression;
|
||||||
resolveExpress.JoinQueryInfos = Builder.QueryBuilder.JoinQueryInfos;
|
resolveExpress.JoinQueryInfos = Builder.QueryBuilder.JoinQueryInfos;
|
||||||
resolveExpress.IsSingle = IsSingle()&& resolveType!= ResolveExpressType.WhereMultiple;
|
resolveExpress.IsSingle = IsSingle()&& resolveType!= ResolveExpressType.WhereMultiple;
|
||||||
|
@@ -221,6 +221,7 @@ namespace SqlSugar
|
|||||||
this.MappingType = MappingTableType;
|
this.MappingType = MappingTableType;
|
||||||
this.MappingAId = typeAiD;
|
this.MappingAId = typeAiD;
|
||||||
this.MappingBId = typeBId;
|
this.MappingBId = typeBId;
|
||||||
|
this.NavigatType = NavigatType.ManyToMany;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public class ExpressionOutParameter
|
||||||
|
{
|
||||||
|
public SqlSugarProvider Context { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -19,6 +19,7 @@ namespace SqlSugar
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
public ExpressionOutParameter SugarContext { get; set; }
|
||||||
public IDbMethods DbMehtods
|
public IDbMethods DbMehtods
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@@ -319,7 +319,7 @@ namespace SqlSugar
|
|||||||
return methodCallExpressionArgs;
|
return methodCallExpressionArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string GetNewExpressionValue(Expression item)
|
public string GetNewExpressionValue(Expression item)
|
||||||
{
|
{
|
||||||
var newContext = this.Context.GetCopyContextWithMapping();
|
var newContext = this.Context.GetCopyContextWithMapping();
|
||||||
newContext.Resolve(item, this.Context.IsJoin ? ResolveExpressType.WhereMultiple : ResolveExpressType.WhereSingle);
|
newContext.Resolve(item, this.Context.IsJoin ? ResolveExpressType.WhereMultiple : ResolveExpressType.WhereSingle);
|
||||||
|
@@ -17,19 +17,6 @@ namespace SqlSugar
|
|||||||
public MapperExpressionResolve(Expression expression, InvalidOperationException ex)
|
public MapperExpressionResolve(Expression expression, InvalidOperationException ex)
|
||||||
{
|
{
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
NavgateExpression navgate = new NavgateExpression(context);
|
|
||||||
if (navgate.IsNavgate(expression))
|
|
||||||
{
|
|
||||||
navgate.Execute(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OldNavgate(expression, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OldNavgate(Expression expression, InvalidOperationException ex)
|
|
||||||
{
|
|
||||||
this.ex = ex;
|
this.ex = ex;
|
||||||
this.mappers = CallContext.MapperExpression.Value;
|
this.mappers = CallContext.MapperExpression.Value;
|
||||||
Error01();
|
Error01();
|
||||||
@@ -244,7 +231,8 @@ namespace SqlSugar
|
|||||||
this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString();
|
this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString();
|
||||||
}
|
}
|
||||||
this.context.InitMappingInfo(childExpression.Type);
|
this.context.InitMappingInfo(childExpression.Type);
|
||||||
return new MapperExpressionInfo() {
|
return new MapperExpressionInfo()
|
||||||
|
{
|
||||||
EntityInfo = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type)
|
EntityInfo = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -57,9 +57,26 @@ namespace SqlSugar
|
|||||||
ResolveDateDate(parameter, isLeft, expression);
|
ResolveDateDate(parameter, isLeft, expression);
|
||||||
}
|
}
|
||||||
else if (isMemberValue)
|
else if (isMemberValue)
|
||||||
|
{
|
||||||
|
var nav = new OneToOneNavgateExpression(this.Context?.SugarContext?.Context);
|
||||||
|
if (nav.IsNavgate(expression))
|
||||||
|
{
|
||||||
|
var value = nav.GetSql();
|
||||||
|
this.Context.SingleTableNameSubqueryShortName = nav.ShorName;
|
||||||
|
if (isSetTempData)
|
||||||
|
{
|
||||||
|
baseParameter.CommonTempData = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppendValue(parameter, isLeft, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression);
|
ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (fieldIsBool && !isField && !isSelectField)
|
else if (fieldIsBool && !isField && !isSelectField)
|
||||||
{
|
{
|
||||||
ResolvefieldIsBool(parameter, baseParameter, isLeft, isSetTempData, expression, isSingle);
|
ResolvefieldIsBool(parameter, baseParameter, isLeft, isSetTempData, expression, isSingle);
|
||||||
|
@@ -244,6 +244,15 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
OneToManyNavgateExpression nav=new OneToManyNavgateExpression(this.Context?.SugarContext?.Context,this);
|
||||||
|
if (nav.IsNavgate(express))
|
||||||
|
{
|
||||||
|
var sql = nav.GetSql();
|
||||||
|
this.Context.SingleTableNameSubqueryShortName = nav.ShorName;
|
||||||
|
base.AppendValue(parameter, isLeft, sql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var constValue = ExpressionTool.DynamicInvoke(express);
|
var constValue = ExpressionTool.DynamicInvoke(express);
|
||||||
if (constValue is MapperSql)
|
if (constValue is MapperSql)
|
||||||
{
|
{
|
||||||
|
@@ -7,17 +7,22 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace SqlSugar
|
namespace SqlSugar
|
||||||
{
|
{
|
||||||
internal class NavgateExpression
|
internal class OneToOneNavgateExpression
|
||||||
{
|
{
|
||||||
private SqlSugarProvider context;
|
private SqlSugarProvider context;
|
||||||
|
private EntityInfo EntityInfo;
|
||||||
public NavgateExpression(SqlSugarProvider context)
|
private EntityInfo ProPertyEntity;
|
||||||
|
private Navigat Navigat;
|
||||||
|
public string ShorName;
|
||||||
|
private string MemberName;
|
||||||
|
public OneToOneNavgateExpression(SqlSugarProvider context)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool IsNavgate(Expression expression)
|
internal bool IsNavgate(Expression expression)
|
||||||
{
|
{
|
||||||
|
var result = false;
|
||||||
var exp = expression;
|
var exp = expression;
|
||||||
if (exp is UnaryExpression)
|
if (exp is UnaryExpression)
|
||||||
{
|
{
|
||||||
@@ -26,13 +31,58 @@ namespace SqlSugar
|
|||||||
if (exp is MemberExpression)
|
if (exp is MemberExpression)
|
||||||
{
|
{
|
||||||
var memberExp = exp as MemberExpression;
|
var memberExp = exp as MemberExpression;
|
||||||
|
var childExpression = memberExp.Expression;
|
||||||
|
result = ValidateNav(result, memberExp, childExpression);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateNav(bool result, MemberExpression memberExp, Expression childExpression)
|
||||||
|
{
|
||||||
|
if (childExpression != null && childExpression is MemberExpression)
|
||||||
|
{
|
||||||
|
var child2Expression = (childExpression as MemberExpression).Expression;
|
||||||
|
if (child2Expression == null)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (child2Expression.Type.IsClass() && child2Expression is ParameterExpression)
|
||||||
internal void Execute(MapperExpressionResolve mapperExpressionResolve)
|
|
||||||
{
|
{
|
||||||
|
var entity = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type);
|
||||||
|
if (entity.Columns.Any(x => x.PropertyName == (childExpression as MemberExpression).Member.Name && x.Navigat != null))
|
||||||
|
{
|
||||||
|
EntityInfo = entity;
|
||||||
|
ShorName = child2Expression.ToString();
|
||||||
|
MemberName = memberExp.Member.Name;
|
||||||
|
ProPertyEntity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type);
|
||||||
|
Navigat = entity.Columns.FirstOrDefault(x => x.PropertyName == (childExpression as MemberExpression).Member.Name).Navigat;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal MapperSql GetSql()
|
||||||
|
{
|
||||||
|
if (this.ProPertyEntity.Type.Name.StartsWith("List`"))
|
||||||
|
{
|
||||||
|
Check.ExceptionEasy(true, " expression error ", "导航查询出错,比如.Count要改成 .Count()");
|
||||||
|
}
|
||||||
|
var pk = this.ProPertyEntity.Columns.First(it => it.IsPrimarykey == true).DbColumnName;
|
||||||
|
var name = this.EntityInfo.Columns.First(it => it.PropertyName == Navigat.Name).DbColumnName;
|
||||||
|
var selectName = this.ProPertyEntity.Columns.First(it => it.PropertyName ==MemberName).DbColumnName;
|
||||||
|
MapperSql mapper = new MapperSql();
|
||||||
|
var queryable = this.context.Queryable<object>();
|
||||||
|
pk = queryable.QueryBuilder.Builder.GetTranslationColumnName(pk);
|
||||||
|
name = queryable.QueryBuilder.Builder.GetTranslationColumnName(name);
|
||||||
|
selectName = queryable.QueryBuilder.Builder.GetTranslationColumnName(selectName);
|
||||||
|
mapper.Sql = queryable
|
||||||
|
.AS(this.ProPertyEntity.DbTableName)
|
||||||
|
.Where($" {ShorName}.{name}={pk} ").Select(selectName).ToSql().Key;
|
||||||
|
mapper.Sql = $" ({mapper.Sql}) ";
|
||||||
|
return mapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,148 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
internal class OneToManyNavgateExpression
|
||||||
|
{
|
||||||
|
private SqlSugarProvider context;
|
||||||
|
private EntityInfo EntityInfo;
|
||||||
|
private EntityInfo ProPertyEntity;
|
||||||
|
private Navigat Navigat;
|
||||||
|
public string ShorName;
|
||||||
|
private string MemberName;
|
||||||
|
private string MethodName;
|
||||||
|
private string whereSql;
|
||||||
|
private MethodCallExpressionResolve methodCallExpressionResolve;
|
||||||
|
public OneToManyNavgateExpression(SqlSugarProvider context, MethodCallExpressionResolve methodCallExpressionResolve)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
this.methodCallExpressionResolve = methodCallExpressionResolve;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool IsNavgate(Expression expression)
|
||||||
|
{
|
||||||
|
var result = false;
|
||||||
|
var exp = expression;
|
||||||
|
if (exp is UnaryExpression)
|
||||||
|
{
|
||||||
|
exp = (exp as UnaryExpression).Operand;
|
||||||
|
}
|
||||||
|
if (exp is MethodCallExpression)
|
||||||
|
{
|
||||||
|
var memberExp=exp as MethodCallExpression;
|
||||||
|
MethodName = memberExp.Method.Name;
|
||||||
|
if (memberExp.Method.Name.IsIn("Any","Count") && memberExp.Arguments.Count>0 && memberExp.Arguments[0] is MemberExpression )
|
||||||
|
{
|
||||||
|
result = ValidateNav(result, memberExp.Arguments[0] as MemberExpression, memberExp.Arguments[0]);
|
||||||
|
if (memberExp.Arguments.Count > 1)
|
||||||
|
{
|
||||||
|
whereSql = GetWhereSql(memberExp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetWhereSql(MethodCallExpression memberExp)
|
||||||
|
{
|
||||||
|
var whereExp = memberExp.Arguments[1];
|
||||||
|
var result= this.methodCallExpressionResolve.GetNewExpressionValue(whereExp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateNav(bool result, MemberExpression memberExp, Expression childExpression)
|
||||||
|
{
|
||||||
|
if (childExpression != null && childExpression is MemberExpression)
|
||||||
|
{
|
||||||
|
var child2Expression = (childExpression as MemberExpression).Expression;
|
||||||
|
if (child2Expression.Type.IsClass() && child2Expression is ParameterExpression)
|
||||||
|
{
|
||||||
|
var rootType = child2Expression.Type;
|
||||||
|
var rootEntity = this.context.EntityMaintenance.GetEntityInfo(rootType);
|
||||||
|
var type= childExpression.Type.GetGenericArguments()[0];
|
||||||
|
var entity = this.context.EntityMaintenance.GetEntityInfo(type);
|
||||||
|
if (rootEntity.Columns.Any(x => x.PropertyName == (childExpression as MemberExpression).Member.Name && x.Navigat != null))
|
||||||
|
{
|
||||||
|
EntityInfo = rootEntity;
|
||||||
|
ShorName = child2Expression.ToString();
|
||||||
|
MemberName = memberExp.Member.Name;
|
||||||
|
ProPertyEntity = entity;
|
||||||
|
Navigat = rootEntity.Columns.FirstOrDefault(x => x.PropertyName == (childExpression as MemberExpression).Member.Name).Navigat;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
internal MapperSql GetSql()
|
||||||
|
{
|
||||||
|
if (Navigat.NavigatType == NavigatType.OneToMany)
|
||||||
|
{
|
||||||
|
return GetOneToManySql();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GetManyToManySql();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private MapperSql GetManyToManySql()
|
||||||
|
{
|
||||||
|
|
||||||
|
var bPk = this.ProPertyEntity.Columns.First(it => it.IsPrimarykey == true).DbColumnName;
|
||||||
|
var aPk = this.EntityInfo.Columns.First(it => it.IsPrimarykey == true).DbColumnName;
|
||||||
|
MapperSql mapper = new MapperSql();
|
||||||
|
var queryable = this.context.Queryable<object>();
|
||||||
|
bPk = queryable.QueryBuilder.Builder.GetTranslationColumnName(bPk);
|
||||||
|
aPk = queryable.QueryBuilder.Builder.GetTranslationColumnName(aPk);
|
||||||
|
var mappingType = Navigat.MappingType;
|
||||||
|
var mappingEntity = this.context.EntityMaintenance.GetEntityInfo(mappingType);
|
||||||
|
var mappingTableName=queryable.QueryBuilder.Builder.GetTranslationTableName(mappingEntity.DbTableName);
|
||||||
|
var mappingA = mappingEntity.Columns.First(it => it.PropertyName == Navigat.MappingAId).DbColumnName;
|
||||||
|
var mappingB = mappingEntity.Columns.First(it => it.PropertyName == Navigat.MappingBId).DbColumnName;
|
||||||
|
mappingA = queryable.QueryBuilder.Builder.GetTranslationColumnName(mappingA);
|
||||||
|
mappingB = queryable.QueryBuilder.Builder.GetTranslationColumnName(mappingB);
|
||||||
|
var bTableName = queryable.QueryBuilder.Builder.GetTranslationTableName(this.ProPertyEntity.DbTableName);
|
||||||
|
mapper.Sql = $" (select count(1) from {bTableName} {this.ProPertyEntity.DbTableName}_1 where {this.ProPertyEntity.DbTableName}_1.{bPk} in (select {mappingA} from {mappingTableName} where {mappingB} = {ShorName}.{aPk} )) ";
|
||||||
|
if (this.whereSql.HasValue())
|
||||||
|
mapper.Sql = mapper.Sql + " AND " + this.whereSql;
|
||||||
|
mapper.Sql = $" ({mapper.Sql}) ";
|
||||||
|
mapper.Sql = GetMethodSql(mapper.Sql);
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
private MapperSql GetOneToManySql()
|
||||||
|
{
|
||||||
|
var pk = this.EntityInfo.Columns.First(it => it.IsPrimarykey == true).DbColumnName;
|
||||||
|
var name = this.ProPertyEntity.Columns.First(it => it.PropertyName == Navigat.Name).DbColumnName;
|
||||||
|
//var selectName = this.ProPertyEntity.Columns.First(it => it.PropertyName == MemberName).DbColumnName;
|
||||||
|
MapperSql mapper = new MapperSql();
|
||||||
|
var queryable = this.context.Queryable<object>();
|
||||||
|
pk = queryable.QueryBuilder.Builder.GetTranslationColumnName(pk);
|
||||||
|
name = queryable.QueryBuilder.Builder.GetTranslationColumnName(name);
|
||||||
|
//selectName = queryable.QueryBuilder.Builder.GetTranslationColumnName(selectName);
|
||||||
|
mapper.Sql = queryable
|
||||||
|
.AS(this.ProPertyEntity.DbTableName)
|
||||||
|
.WhereIF(!string.IsNullOrEmpty(whereSql), whereSql)
|
||||||
|
.Where($" {name}={ShorName}.{pk} ").Select(" COUNT(1) ").ToSql().Key;
|
||||||
|
mapper.Sql = $" ({mapper.Sql}) ";
|
||||||
|
mapper.Sql = GetMethodSql(mapper.Sql);
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetMethodSql(string sql)
|
||||||
|
{
|
||||||
|
if (MethodName == "Any")
|
||||||
|
{
|
||||||
|
return $" ({sql}>0 ) ";
|
||||||
|
}
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -28,6 +28,7 @@ namespace SqlSugar
|
|||||||
Action RefreshMapping { get; set; }
|
Action RefreshMapping { get; set; }
|
||||||
bool PgSqlIsAutoToLower { get; set; }
|
bool PgSqlIsAutoToLower { get; set; }
|
||||||
Expression RootExpression { get; set; }
|
Expression RootExpression { get; set; }
|
||||||
|
ExpressionOutParameter SugarContext { get; set; }
|
||||||
bool? TableEnumIsString { get; set; }
|
bool? TableEnumIsString { get; set; }
|
||||||
|
|
||||||
string GetAsString(string fieldName, string fieldValue);
|
string GetAsString(string fieldName, string fieldValue);
|
||||||
|
@@ -109,7 +109,9 @@ namespace SqlSugar
|
|||||||
ISugarQueryable<T> Select(string select);
|
ISugarQueryable<T> Select(string select);
|
||||||
ISugarQueryable<T> MergeTable();
|
ISugarQueryable<T> MergeTable();
|
||||||
void ForEach(Action<T> action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
|
void ForEach(Action<T> action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
|
||||||
|
Task ForEachAsync(Action<T> action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
|
||||||
void ForEachByPage(Action<T> action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
|
void ForEachByPage(Action<T> action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
|
||||||
|
Task ForEachByPageAsync(Action<T> action, int pageIndex, int pageSize, RefAsync<int> totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
|
||||||
int Count();
|
int Count();
|
||||||
Task<int> CountAsync();
|
Task<int> CountAsync();
|
||||||
int Count(Expression<Func<T, bool>> expression);
|
int Count(Expression<Func<T, bool>> expression);
|
||||||
@@ -173,6 +175,7 @@ namespace SqlSugar
|
|||||||
List<T> ToPageList(int pageNumber, int pageSize, ref int totalNumber);
|
List<T> ToPageList(int pageNumber, int pageSize, ref int totalNumber);
|
||||||
List<T> ToPageList(int pageNumber, int pageSize, ref int totalNumber,ref int totalPage);
|
List<T> ToPageList(int pageNumber, int pageSize, ref int totalNumber,ref int totalPage);
|
||||||
Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber);
|
Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber);
|
||||||
|
Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber, RefAsync<int> totalPage);
|
||||||
ISugarQueryable<T> WithCache(string cacheKey,int cacheDurationInSeconds = int.MaxValue);
|
ISugarQueryable<T> WithCache(string cacheKey,int cacheDurationInSeconds = int.MaxValue);
|
||||||
ISugarQueryable<T> WithCache(int cacheDurationInSeconds = int.MaxValue);
|
ISugarQueryable<T> WithCache(int cacheDurationInSeconds = int.MaxValue);
|
||||||
ISugarQueryable<T> WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue);
|
ISugarQueryable<T> WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue);
|
||||||
|
Reference in New Issue
Block a user