1.模仿groupjoin中的方法在ISugarQueryable增加两个接口
ISugarQueryable<T> Mapper<TObject>(Expression<Func<T, TObject>> mapperObject, Expression<Func<T, object>> mainField, Expression<Func<TObject, object>> childField);
ISugarQueryable<T> Mapper<TObject>(Expression<Func<T, List<TObject>>> mapperObject, Expression<Func<T, object>> mainField, Expression<Func<TObject, object>> childField);
效果就是为了写这种语法 var list = ssc.Queryable<School>().Mapper(o => o.StudentList, o => new { o.Id }, p => new { p.SchoolId }).ToList();
2.增加一个_Mapper2 仿照稍作修改 private ISugarQueryable<T> _Mapper<TObject>(Expression mapperObject, Expression mainField, Expression childField)
private ISugarQueryable<T> _Mapper2<TObject>(Expression mapperObject, Expression mainField, Expression childField) { if ((mapperObject as LambdaExpression).Body is UnaryExpression) { mapperObject = ((mapperObject as LambdaExpression).Body as UnaryExpression).Operand; } else { mapperObject = (mapperObject as LambdaExpression).Body; } if ((mainField as LambdaExpression).Body is UnaryExpression) { mainField = ((mainField as LambdaExpression).Body as UnaryExpression).Operand; } else { mainField = (mainField as LambdaExpression).Body; } if ((childField as LambdaExpression).Body is UnaryExpression) { childField = ((childField as LambdaExpression).Body as UnaryExpression).Operand; } else { childField = (childField as LambdaExpression).Body; } var mapperObjectExp = mapperObject as MemberExpression; var objName = mapperObjectExp.Member.Name; bool islist = mapperObjectExp.Type.Name == "List`1"; if (Mappers == null) Mappers = new List<Action<List<T>>>(); if (true) { Action<List<T>> mapper = (entitys) => { if (entitys.IsNullOrEmpty() || !entitys.Any()) return; var entity = entitys.First(); var dic = new Dictionary<string, string>(); var lamResult = QueryBuilder.GetExpressionValue(childField, ResolveExpressType.ArraySingle); var lamResult2 = QueryBuilder.GetExpressionValue(mainField, ResolveExpressType.ArraySingle); var list11 = lamResult.GetResultString().Split(',').ToList(); var list21 = lamResult2.GetResultString().Split(',').ToList(); for (int j = 0; j < list11.Count; j++) { var key = list11[j]; var val = list21[j]; if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(val)) { dic.Add(key, val); } } var list2 = this.Context.Queryable<TObject>().Where(entitys, mainField, childField).ToList(); var cols1 = this.Context.EntityMaintenance.GetEntityInfo<TObject>().Columns; var cols2 = this.Context.EntityMaintenance.GetEntityInfo<T>().Columns; ParameterExpression param1 = Expression.Parameter(typeof(T), "it"); ParameterExpression param = Expression.Parameter(typeof(TObject), "e"); BinaryExpression mainBinaryExpression = null; foreach (var map in dic) { var info = cols1.First(o => o.DbColumnName == this.QueryBuilder.Builder.GetNoTranslationColumnName(map.Key)); var info2 = cols2.First(o => o.DbColumnName == this.QueryBuilder.Builder.GetNoTranslationColumnName(map.Value)); Expression node1 = null, node2 = null; MemberExpression body = Expression.PropertyOrField(param, info.PropertyName); MemberExpression body1 = Expression.PropertyOrField(param1, info2.PropertyName); if (body.Type != body1.Type) { if (body.Type.IsConstructedGenericType) { node1 = Expression.Convert(body, body.Type); node2 = Expression.Convert(body1, body.Type); } else { node1 = Expression.Convert(body, body1.Type); node2 = Expression.Convert(body1, body1.Type); } } else { node1 = body; node2 = body1; } var exp = Expression.Equal(node1, node2); if (mainBinaryExpression == null) { mainBinaryExpression = exp; } else { mainBinaryExpression = Expression.AndAlso(mainBinaryExpression, exp); } } var lambda = Expression.Lambda<Func<TObject, Boolean>>(mainBinaryExpression, new[] { param }); Expression anyExpression = Expression.Call( typeof(Enumerable), "Where", new Type[] { typeof(TObject) }, Expression.Constant(list2), lambda ); Expression tolistExpression = Expression.Call( typeof(Enumerable), islist?"ToList": "FirstOrDefault", new Type[] { typeof(TObject) }, anyExpression ); MemberExpression body2 = Expression.PropertyOrField(param1, objName); var actionExpression = Expression.Assign(body2, tolistExpression); Expression<Action<T>> myAction = Expression.Lambda<Action<T>>(actionExpression, new[] { param1 }); entitys.ForEach(myAction.Compile()); }; Mappers.Add(mapper); } return this; }
3.为以上添加查询方法
private string ToSqlString2() { var vals = this.MapperInfos.Values.ToList(); var groupList = DbColumnInfoList.Where(o=>vals.Contains(Builder.GetTranslationColumnName(o.DbColumnName)) ).GroupBy(it => it.TableId).ToList(); StringBuilder batchInsetrSql = new StringBuilder(); int i = 0; foreach (var columns in groupList) { var isFirst = i == 0; if (!isFirst) { batchInsetrSql.Append(SqlTemplateBatchUnion); } batchInsetrSql.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, FormatValue(it.Value), Builder.GetTranslationColumnName(it.DbColumnName))))); ++i; } var selectstr = $" ({batchInsetrSql}) t2"; var wherestring = string.Join(" and ", this.MapperInfos.Select(o => $" t.{o.Key} = t2.{o.Value}")); return $"SELECT T.* FROM {selectstr},{this.GetTableNameString} t WHERE {wherestring}"; }
以上就是主要修改的代码
Demo地址:https://gitee.com/xuanyun2018/sqlsugardemo.git