sqlsugar入门(6)-修改源码支持Mapper多字段映射属性导航


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

 

 

 

 

 

 

 

 

     

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM