Update Core

This commit is contained in:
sunkaixuan 2022-04-13 22:57:18 +08:00
parent 8305650f4a
commit 8d67a9f28f
14 changed files with 436 additions and 56 deletions

View File

@ -25,6 +25,7 @@ namespace SqlSugar
private List<Expression> _preExpressionList = new List<Expression>();
private List<object> _preList = new List<object>();
private List<Expression> _ListCallFunc;
//private Expression[] _expressions;
//private List<T> _list;
//private EntityInfo _entityInfo;
@ -40,7 +41,7 @@ namespace SqlSugar
private void ExecuteByLay(int i, Expression item)
{
_ListCallFunc = GetWhereExpression(ref item);
if (i == 1)
{
ExecuteByLay(item, RootList.Select(it => it as object).ToList(), SelectR1);
@ -88,6 +89,7 @@ namespace SqlSugar
_preList = list.ToList();
}
_preExpressionList.Add(item);
_ListCallFunc = new List<Expression>();
}
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)
{
var bEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0];
@ -159,7 +178,8 @@ namespace SqlSugar
FieldValue = String.Join(",", abids.Select(it => it.Bid).ToArray()),
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())
{
foreach (var listItem in list)
@ -187,7 +207,7 @@ namespace SqlSugar
var navType = navObjectNamePropety.PropertyType;
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navType);
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();
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
@ -212,17 +232,18 @@ namespace SqlSugar
var navColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
//var navType = navObjectNamePropety.PropertyType;
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();
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
FieldName = navObjectNameColumnInfo.Navigat.Name,
FieldName = navColumn.DbColumnName,
FieldValue = String.Join(",", ids),
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())
{
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; }
}
}
}

View File

@ -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)
{
int count = this.Clone().Count();
@ -1457,6 +1477,43 @@ namespace SqlSugar
}
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)
{
@ -1769,6 +1826,12 @@ namespace SqlSugar
this.Context.MappingTables = oldMapping;
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()
{
if (IsCache)
@ -2248,6 +2311,10 @@ namespace SqlSugar
if (this.QueryBuilder.Includes != null)
{
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)
{
var manager = it as NavigatManager<TResult>;

View File

@ -242,6 +242,7 @@ namespace SqlSugar
{
resolveExpress.PgSqlIsAutoToLower = true;
}
resolveExpress.SugarContext = new ExpressionOutParameter() { Context = this.Context };
resolveExpress.RootExpression = expression;
resolveExpress.JoinQueryInfos = Builder.QueryBuilder.JoinQueryInfos;
resolveExpress.IsSingle = IsSingle()&& resolveType!= ResolveExpressType.WhereMultiple;

View File

@ -221,6 +221,7 @@ namespace SqlSugar
this.MappingType = MappingTableType;
this.MappingAId = typeAiD;
this.MappingBId = typeBId;
this.NavigatType = NavigatType.ManyToMany;
}
}

View File

@ -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; }
}
}

View File

@ -19,6 +19,7 @@ namespace SqlSugar
#endregion
#region Properties
public ExpressionOutParameter SugarContext { get; set; }
public IDbMethods DbMehtods
{
get

View File

@ -319,7 +319,7 @@ namespace SqlSugar
return methodCallExpressionArgs;
}
protected string GetNewExpressionValue(Expression item)
public string GetNewExpressionValue(Expression item)
{
var newContext = this.Context.GetCopyContextWithMapping();
newContext.Resolve(item, this.Context.IsJoin ? ResolveExpressType.WhereMultiple : ResolveExpressType.WhereSingle);

View File

@ -17,19 +17,6 @@ namespace SqlSugar
public MapperExpressionResolve(Expression expression, InvalidOperationException ex)
{
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.mappers = CallContext.MapperExpression.Value;
Error01();
@ -48,7 +35,7 @@ namespace SqlSugar
{
var methodExpression = expression as MethodCallExpression;
var callName = methodExpression.Method.Name;
var exp= methodExpression.Arguments[0] as MemberExpression;
var exp = methodExpression.Arguments[0] as MemberExpression;
ThrowTrue(exp == null);
var childExpression = exp;
MapperExpression mapper = GetMapperMany(exp);
@ -67,13 +54,13 @@ namespace SqlSugar
ThrowTrue(exp.Expression == null);
var childExpression = exp.Expression;
MapperExpression mapper = GetMapper(exp);
var fillInfo=GetFillInfo(childExpression, mapper);
var fillInfo = GetFillInfo(childExpression, mapper);
var mappingFild1Info = GetMappingFild1Info(childExpression, mapper);
var mappingFild1Info2 = GetMappingFild2Info(childExpression, mapper);
var SelectInfo = GetSelectInfo(expression);
var entity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type);
var isExMapper = mappingFild1Info2!=null;
var isExMapper = mappingFild1Info2 != null;
var isFillFild1SameType = fillInfo.Type == mappingFild1Info.Type;
var isSameProperty = false;
@ -91,11 +78,11 @@ namespace SqlSugar
}
else
{
oneToOne(fillInfo, mappingFild1Info, mappingFild1Info2,SelectInfo);
oneToOne(fillInfo, mappingFild1Info, mappingFild1Info2, SelectInfo);
}
}
private void oneToOne(MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2, MapperExpressionInfo selectInfo)
{
var pkColumn = selectInfo.EntityInfo.Columns.Where(it => it.IsPrimarykey == true).FirstOrDefault();
@ -108,11 +95,11 @@ namespace SqlSugar
var whereRight = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString);
this.sql = this.context.Queryable<object>()
.AS(tableName)
.Where(string.Format(" {0}={1} ",whereLeft , whereRight))
.Where(string.Format(" {0}={1} ", whereLeft, whereRight))
.Select(sqlBuilder.GetTranslationColumnName(selectInfo.FieldName)).ToSql().Key;
}
private void oneToMany(MethodCallExpression methodCallExpression,string methodName,EntityInfo mainEntity,string shortName,MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2)
private void oneToMany(MethodCallExpression methodCallExpression, string methodName, EntityInfo mainEntity, string shortName, MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2)
{
var pkColumn = mainEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true);
if (pkColumn == null)
@ -145,14 +132,14 @@ namespace SqlSugar
{
if (methodCallExpression.Arguments.Count <= 1)
return null;
var exp= methodCallExpression.Arguments[1];
var querybuiler=InstanceFactory.GetQueryBuilder(this.context.CurrentConnectionConfig);
var exp = methodCallExpression.Arguments[1];
var querybuiler = InstanceFactory.GetQueryBuilder(this.context.CurrentConnectionConfig);
querybuiler.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.context.CurrentConnectionConfig);
querybuiler.Builder = InstanceFactory.GetSqlbuilder(this.context.CurrentConnectionConfig);
querybuiler.Builder.Context = querybuiler.Context;
querybuiler.Builder.QueryBuilder = querybuiler;
querybuiler.Context = this.context;
var expValue=querybuiler.GetExpressionValue(exp, ResolveExpressType.WhereMultiple);
var expValue = querybuiler.GetExpressionValue(exp, ResolveExpressType.WhereMultiple);
var paramterName = (exp as LambdaExpression).Parameters[0].Name;
var sql = expValue.GetResultString();
sql = sql.Replace(querybuiler.Builder.GetTranslationColumnName(paramterName) + ".", "");
@ -160,7 +147,7 @@ namespace SqlSugar
{
foreach (var item in querybuiler.Parameters)
{
sql = sql.Replace(item.ParameterName,item.Value.ObjToString().ToSqlValue());
sql = sql.Replace(item.ParameterName, item.Value.ObjToString().ToSqlValue());
}
}
return sql;
@ -168,7 +155,7 @@ namespace SqlSugar
private MapperExpressionInfo GetSelectInfo(Expression expression)
{
var field = expression;
if (field is UnaryExpression)
{
@ -183,7 +170,7 @@ namespace SqlSugar
{
Type = type,
FieldName = fieldName,
EntityInfo= entity
EntityInfo = entity
};
}
@ -219,18 +206,18 @@ namespace SqlSugar
}
var type = ((field as MemberExpression).Expression).Type;
this.context.InitMappingInfo(type);
var name =(field as MemberExpression).Member.Name;
var name = (field as MemberExpression).Member.Name;
var entity = this.context.EntityMaintenance.GetEntityInfo(type);
var fieldName=entity.Columns.First(it => it.PropertyName == name).DbColumnName;
var fieldName = entity.Columns.First(it => it.PropertyName == name).DbColumnName;
var array = (field as MemberExpression).ToString().Split('.').ToList();
array[array.Count()-1] = fieldName;
array[array.Count() - 1] = fieldName;
var filedString = string.Join(".", array);
return new MapperExpressionInfo()
{
Type=type,
FieldName = fieldName,
FieldString= filedString,
EntityInfo= entity
Type = type,
FieldName = fieldName,
FieldString = filedString,
EntityInfo = entity
};
}
@ -244,14 +231,15 @@ namespace SqlSugar
this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString();
}
this.context.InitMappingInfo(childExpression.Type);
return new MapperExpressionInfo() {
EntityInfo=this.context.EntityMaintenance.GetEntityInfo(childExpression.Type)
return new MapperExpressionInfo()
{
EntityInfo = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type)
};
}
private MapperExpression GetMapper(MemberExpression exp)
{
var mapper= mappers.Where(it => it.Type == MapperExpressionType.oneToOne)
var mapper = mappers.Where(it => it.Type == MapperExpressionType.oneToOne)
.Reverse()
.Where(it => (it.FillExpression as LambdaExpression).Body.ToString() == exp.Expression.ToString()).FirstOrDefault();
ThrowTrue(mapper == null);
@ -263,7 +251,7 @@ namespace SqlSugar
return "";
}
private void ExtMapper(MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2, MapperExpressionInfo selectInfo)
private void ExtMapper(MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2, MapperExpressionInfo selectInfo)
{
var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName);
var whereLeft = sqlBuilder.GetTranslationColumnName(mappingFild1Info2.FieldName);
@ -334,7 +322,7 @@ namespace SqlSugar
}
void ThrowTrue(bool isError)
{
Check.Exception(isError, ErrorMessage.GetThrowMessage(expression.ToString() + "no support", "不支持表达式" + expression.ToString()+ " 1.检查当前表达式中的别名是否与Mapper中的一致 2.目前只支持 1对1 Mapper下的 Where "));
Check.Exception(isError, ErrorMessage.GetThrowMessage(expression.ToString() + "no support", "不支持表达式" + expression.ToString() + " 1.检查当前表达式中的别名是否与Mapper中的一致 2.目前只支持 1对1 Mapper下的 Where "));
}
}
@ -347,7 +335,7 @@ namespace SqlSugar
{
public Type Type { get; set; }
public EntityInfo EntityInfo { get; set; }
public string FieldName { get; set; }
public string FieldString { get; set; }
public string FieldName { get; set; }
public string FieldString { get; set; }
}
}

View File

@ -58,7 +58,24 @@ namespace SqlSugar
}
else if (isMemberValue)
{
ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression);
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);
}
}
else if (fieldIsBool && !isField && !isSelectField)
{

View File

@ -244,6 +244,15 @@ namespace SqlSugar
{
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);
if (constValue is MapperSql)
{

View File

@ -7,32 +7,82 @@ using System.Threading.Tasks;
namespace SqlSugar
{
internal class NavgateExpression
internal class OneToOneNavgateExpression
{
private SqlSugarProvider context;
public NavgateExpression(SqlSugarProvider context)
private EntityInfo EntityInfo;
private EntityInfo ProPertyEntity;
private Navigat Navigat;
public string ShorName;
private string MemberName;
public OneToOneNavgateExpression(SqlSugarProvider context)
{
this.context = context;
}
internal bool IsNavgate(Expression expression)
{
var result = false;
var exp = expression;
if (exp is UnaryExpression)
{
exp = (exp as UnaryExpression).Operand;
}
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 false;
return result;
}
internal void Execute(MapperExpressionResolve mapperExpressionResolve)
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;
}
if (child2Expression.Type.IsClass() && child2Expression is ParameterExpression)
{
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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -28,6 +28,7 @@ namespace SqlSugar
Action RefreshMapping { get; set; }
bool PgSqlIsAutoToLower { get; set; }
Expression RootExpression { get; set; }
ExpressionOutParameter SugarContext { get; set; }
bool? TableEnumIsString { get; set; }
string GetAsString(string fieldName, string fieldValue);

View File

@ -109,7 +109,9 @@ namespace SqlSugar
ISugarQueryable<T> Select(string select);
ISugarQueryable<T> MergeTable();
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);
Task ForEachByPageAsync(Action<T> action, int pageIndex, int pageSize, RefAsync<int> totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null);
int Count();
Task<int> CountAsync();
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,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, RefAsync<int> totalPage);
ISugarQueryable<T> WithCache(string cacheKey,int cacheDurationInSeconds = int.MaxValue);
ISugarQueryable<T> WithCache(int cacheDurationInSeconds = int.MaxValue);
ISugarQueryable<T> WithCacheIF(bool isCache, int cacheDurationInSeconds = int.MaxValue);