public static IDbSelect Map(
            IDbSelect dbSelect, Type returnType,
            IModelInfoProvider infoProvider, IDbObjectFactory dbFactory, UniqueNameGenerator nameGenerator)
        {
            // If the select returns specified columns, it means there is a constructor in Select,
            // e.g (.Select(d => new { A = d.ABC }))
            // In this case we do not need to add alias to the end result as where will be one in the select
            if (dbSelect.Selection.Any(s => !(s is IDbRefColumn)))
            {
                return(dbSelect);
            }

            var entityInfo = infoProvider.FindEntityInfo(returnType);

            if (!entityInfo.RequirePropertyNameMapping())
            {
                return(dbSelect);
            }

            var alias        = nameGenerator.GenerateAlias(dbSelect, TranslationConstants.SubSelectPrefix, true);
            var newSelectRef = dbFactory.BuildRef(dbSelect, alias);
            var newSelect    = dbFactory.BuildSelect(newSelectRef);

            foreach (var fieldInfo in entityInfo.Columns)
            {
                var column = dbFactory.BuildColumn(
                    newSelectRef, fieldInfo.DbName, fieldInfo.ValType, fieldInfo.PropertyName);

                newSelect.Selection.Add(column);
            }

            return(newSelect);
        }
예제 #2
0
        protected override Expression VisitConstant(ConstantExpression c)
        {
            var entityInfo = _infoProvider.FindEntityInfo(c.Type);

            if (entityInfo != null)
            {
                var dbTable = _dbFactory.BuildTable(entityInfo);
                var dbRef   = _dbFactory.BuildRef(dbTable);

                var dbSelect = _dbFactory.BuildSelect(dbRef);
                dbRef.Alias = _nameGenerator.GenerateAlias(dbSelect, dbTable.TableName);

                _state.ResultStack.Push(dbSelect);
            }
            else if (!c.Type.IsAnonymouse())
            {
                var dbConstant = _dbFactory.BuildConstant(c.Value, true);
                _state.ResultStack.Push(dbConstant);
            }

            return(c);
        }
예제 #3
0
        public static LambdaExpression Make(MemberExpression memberExpr, IModelInfoProvider infoProvider)
        {
            /** for example
             * relation: b => b.posts
             * fill func:
             * Action<IEnumerable<Blog>, IEnumerable<Post>> x = (bs, ps) =>
             * {
             *  var dict = ps.GroupBy(p => p.BlogId).ToDictionary(g => g.Key);
             *  foreach (var blog in bs)
             *  {
             *      if (dict.ContainsKey(blog.BlogId))
             *      {
             *          var posts = dict[blog.BlogId];
             *          blog.Posts.AddRange(posts);
             *
             *          foreach (var post in posts)
             *              post.Blog = blog;
             *      }
             *  }
             * };
             */
            var fromEntity = infoProvider.FindEntityInfo(memberExpr.Expression.Type);
            var relation   = fromEntity.GetRelation(memberExpr.Member.Name);
            var toEntity   = relation.ToEntity;

            var fromKey = relation.FromKeys.Single();
            var toKey   = relation.ToKeys.Single();

            var fromProp = relation.FromProperty;
            var toProp   = relation.ToProperty;

            var fromEnumType = typeof(IEnumerable <>).MakeGenericType(fromEntity.Type);
            var toEnumType   = typeof(IEnumerable <>).MakeGenericType(toEntity.Type);

            // we need to invert the from and to for parent relation as the expression
            // was designed for child relation
            return(toEnumType.IsAssignableFrom(memberExpr.Type)
                ? MakeFillerFunc(memberExpr, fromEnumType, toEnumType, fromEntity, toEntity, fromKey, toKey, fromProp, toProp)
                : MakeFillerFunc(memberExpr, toEnumType, fromEnumType, toEntity, fromEntity, toKey, fromKey, toProp, fromProp));
        }