mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-07-16 16:50:41 +08:00
Update Core
This commit is contained in:
parent
8305650f4a
commit
8d67a9f28f
@ -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; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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>;
|
||||
|
@ -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;
|
||||
|
@ -221,6 +221,7 @@ namespace SqlSugar
|
||||
this.MappingType = MappingTableType;
|
||||
this.MappingAId = typeAiD;
|
||||
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
|
||||
|
||||
#region Properties
|
||||
public ExpressionOutParameter SugarContext { get; set; }
|
||||
public IDbMethods DbMehtods
|
||||
{
|
||||
get
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
bool PgSqlIsAutoToLower { get; set; }
|
||||
Expression RootExpression { get; set; }
|
||||
ExpressionOutParameter SugarContext { get; set; }
|
||||
bool? TableEnumIsString { get; set; }
|
||||
|
||||
string GetAsString(string fieldName, string fieldValue);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user