From 1ea83c83233119c484dd2ab5dbe28d2a63ea8ae6 Mon Sep 17 00:00:00 2001 From: skx <610262374@qq.com> Date: Sun, 17 Jan 2021 02:35:33 +0800 Subject: [PATCH] Support on to many where( it.xx.count()>0) --- .../SqlServerTest/UnitTest/UQueryable2.cs | 11 +++ .../QueryableProvider/QueryableProvider.cs | 6 ++ .../ResolveItems/MapperExpressionResolve.cs | 91 ++++++++++++++++++- .../MethodCallExpressionResolve.cs | 6 ++ 4 files changed, 110 insertions(+), 4 deletions(-) diff --git a/Src/Asp.Net/SqlServerTest/UnitTest/UQueryable2.cs b/Src/Asp.Net/SqlServerTest/UnitTest/UQueryable2.cs index 2c0061c17..e1fd824d0 100644 --- a/Src/Asp.Net/SqlServerTest/UnitTest/UQueryable2.cs +++ b/Src/Asp.Net/SqlServerTest/UnitTest/UQueryable2.cs @@ -21,6 +21,17 @@ namespace OrmTest .Where(it => it.A.Name == "a") .ToList(); + + var list3 = Db.Queryable() + .Mapper(it => it.Items, it => it.Items.First().OrderId) + .Where(it => it.Items.Count() > 0) + .ToList(); + + var list6 = Db.Queryable() + .Mapper(it => it.Items, it => it.Items.First().OrderId) + .Where(it => it.Items.Any()) + .ToList(); + } } } diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 365ad23f1..61bf2d832 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -129,6 +129,12 @@ namespace SqlSugar } public virtual ISugarQueryable Mapper(Expression>> mapperObject, Expression> mapperField) { + Check.Exception(mapperObject.ReturnType.Name == "IList`1", "Mapper no support IList , Use List"); + if (CallContext.MapperExpression.Value == null) + { + CallContext.MapperExpression.Value = new List(); + } + CallContext.MapperExpression.Value.Add(new MapperExpression() { SqlBuilder = SqlBuilder, QueryBuilder = this.QueryBuilder, Type = MapperExpressionType.oneToN, FillExpression = mapperObject, MappingField1Expression = mapperField,Context = this.Context }); return _Mapper(mapperObject, mapperField); } public virtual ISugarQueryable Mapper(Expression> mapperObject, Expression> mapperField) diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs index 3e6be26da..8a1548d95 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs @@ -33,7 +33,19 @@ namespace SqlSugar private void ResolveList() { - throw new NotImplementedException(); + var methodExpression = expression as MethodCallExpression; + var callName = methodExpression.Method.Name; + var exp= methodExpression.Arguments[0] as MemberExpression; + ThrowTrue(exp == null); + var childExpression = exp; + MapperExpression mapper = GetMapperMany(exp); + var fillInfo = GetFillInfoMany(childExpression, mapper); + var mappingFild1Info = GetMappingFild1ManyInfo(childExpression, mapper); + var mappingFild1Info2 = GetMappingFild2Info(childExpression, mapper); + //var SelectInfo = GetSelectInfo(expression); + this.context.InitMappingInfo(childExpression.Expression.Type); + var entity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Expression.Type); + oneToMany(callName, entity, childExpression.Expression.ToString(), fillInfo, mappingFild1Info, mappingFild1Info2); } private void ResolveMember() @@ -62,7 +74,7 @@ namespace SqlSugar } else if (isFillFild1SameType) { - oneToMany(); + throw new NotSupportedException(expression.ToString()); } else { @@ -87,9 +99,31 @@ namespace SqlSugar .Select(sqlBuilder.GetTranslationColumnName(selectInfo.FieldName)).ToSql().Key; } - private void oneToMany() + private void oneToMany(string methodName,EntityInfo mainEntity,string shortName,MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2) { - throw new NotImplementedException(); + var pkColumn = mainEntity.Columns.FirstOrDefault(it=>it.IsPrimarykey==true); + if (pkColumn == null) + { + pkColumn = mainEntity.Columns.FirstOrDefault(); + } + var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName); + var whereLeft = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString); + var whereRight = sqlBuilder.GetTranslationColumnName(shortName+"."+pkColumn.DbColumnName); + + if (methodName == "Any") + { + this.sql = " ("+this.context.Queryable() + .AS(tableName) + .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .Select("COUNT(1)").ToSql().Key+")>0 "; + } + else + { + this.sql = this.context.Queryable() + .AS(tableName) + .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .Select("COUNT(1)").ToSql().Key; + } } private MapperExpressionInfo GetSelectInfo(Expression expression) @@ -205,6 +239,55 @@ namespace SqlSugar return new MapperSql() { Sql = " (" + this.sql + ") " }; } + private MapperExpression GetMapperMany(MemberExpression exp) + { + var mapper = mappers.Where(it => it.Type == MapperExpressionType.oneToN) + .Reverse() + .Where(it => (it.FillExpression as LambdaExpression).Body.ToString() == exp.ToString()).FirstOrDefault(); + ThrowTrue(mapper == null); + return mapper; + } + private MapperExpressionInfo GetFillInfoMany(Expression childExpression, MapperExpression mapper) + { + this.querybuiler = mapper.QueryBuilder; + this.context = mapper.Context; + this.sqlBuilder = mapper.SqlBuilder; + if (this.querybuiler.TableShortName.IsNullOrEmpty()) + { + this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString(); + } + var type = (childExpression as MemberExpression).Type.GetGenericArguments()[0]; + this.context.InitMappingInfo(type); + return new MapperExpressionInfo() + { + EntityInfo = this.context.EntityMaintenance.GetEntityInfo(type) + }; + } + private MapperExpressionInfo GetMappingFild1ManyInfo(Expression childExpression, MapperExpression mapper) + { + var exp = mapper.MappingField1Expression; + var field = (exp as LambdaExpression).Body; + if (field is UnaryExpression) + { + field = (field as UnaryExpression).Operand; + } + var type = ((field as MemberExpression).Expression).Type; + this.context.InitMappingInfo(type); + 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 array = (field as MemberExpression).ToString().Split('.').ToList(); + //array[array.Count() - 1] = fieldName; + //var filedString = string.Join(".", array); + return new MapperExpressionInfo() + { + Type = type, + FieldName = fieldName, + FieldString = fieldName, + EntityInfo = entity + }; + } + void Error01() { Check.Exception(mappers == null, ErrorMessage.GetThrowMessage(expression.ToString() + "no support", "当前表达式" + expression.ToString() + "必须在Mapper之后使用")); diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs index bf683519a..fe47c16fc 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs @@ -154,6 +154,12 @@ namespace SqlSugar try { var constValue = ExpressionTool.DynamicInvoke(express); + if (constValue is MapperSql) + { + constValue = (constValue as MapperSql).Sql; + base.AppendValue(parameter, isLeft, constValue); + return; + } parameter.BaseParameter.CommonTempData = constValue; var parameterName = base.AppendParameter(constValue); if (parameter.BaseParameter.CommonTempData != null && parameter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Result))