Exemplo n.º 1
0
        /// <summary>
        /// 访问 <see cref="SelectExpression"/>。
        /// </summary>
        /// <param name="select">要访问的表达式。</param>
        /// <returns></returns>
        protected override Expression VisitSelect(SelectExpression select)
        {
            if (select.From != null && select.From.NodeType == (ExpressionType)DbExpressionType.Table)
            {
                var table = (TableExpression)select.From;
                //首先要找到具有假删除标记的列表达式
                foreach (var column in select.Columns)
                {
                    base.Visit(column.Expression);
                }

                if (fakeColumn != null && fakeColumn.Alias.Equals(table.Alias))
                {
                    var where = select.Where;

                    var condExp = fakeColumn.Equal(Expression.Constant(0.ToType(fakeColumn.Type)));
                    return(select.Update(select.From,
                                         where != null ? Expression.And(where, condExp) : condExp,
                                         select.OrderBy, select.GroupBy, select.Skip, select.Take,
                                         select.Segment, select.IsDistinct, select.Columns, select.Having, select.IsReverse));
                }
            }
            else if (select.From != null)
            {
                var from = base.Visit(select.From);
                return(select.Update(from, select.Where, select.OrderBy, select.GroupBy, select.Skip, select.Take,
                                     select.Segment, select.IsDistinct, select.Columns, select.Having, select.IsReverse));
            }

            return(select);
        }
Exemplo n.º 2
0
        public override ProjectionExpression GetQueryExpression(MappingEntity entity)
        {
            var tables = this.mapping.GetTables(entity);

            if (tables.Count <= 1)
            {
                return(base.GetQueryExpression(entity));
            }

            var          aliases   = new Dictionary <string, TableAlias>();
            MappingTable rootTable = tables.Single(ta => !this.mapping.IsExtensionTable(ta));
            var          tex       = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(rootTable));

            aliases.Add(this.mapping.GetAlias(rootTable), tex.Alias);
            Expression source = tex;

            foreach (MappingTable table in tables.Where(t => this.mapping.IsExtensionTable(t)))
            {
                TableAlias joinedTableAlias = new TableAlias();
                string     extensionAlias   = this.mapping.GetAlias(table);
                aliases.Add(extensionAlias, joinedTableAlias);

                List <string>     keyColumns     = this.mapping.GetExtensionKeyColumnNames(table).ToList();
                List <MemberInfo> relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToList();
                string            relatedAlias   = this.mapping.GetExtensionRelatedAlias(table);

                TableAlias relatedTableAlias;
                aliases.TryGetValue(relatedAlias, out relatedTableAlias);

                TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, this.mapping.GetTableName(table));

                Expression cond = null;
                for (int i = 0, n = keyColumns.Count; i < n; i++)
                {
                    var memberType    = TypeHelper.GetMemberType(relatedMembers[i]);
                    var colType       = this.GetColumnType(entity, relatedMembers[i]);
                    var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias, this.mapping.GetColumnName(entity, relatedMembers[i]));
                    var joinedColumn  = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]);
                    var eq            = joinedColumn.Equal(relatedColumn);
                    cond = (cond != null) ? cond.And(eq) : eq;
                }

                source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond);
            }

            var columns = new List <ColumnDeclaration>();

            this.GetColumns(entity, aliases, columns);
            SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null);
            var existingAliases   = aliases.Values.ToArray();

            Expression projector   = this.GetEntityExpression(root, entity);
            var        selectAlias = new TableAlias();
            var        pc          = ColumnProjector.ProjectColumns(this.Translator.Linguist.Language, projector, null, selectAlias, root.Alias);
            var        proj        = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, root, null),
                pc.Projector);

            return((ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType));
        }
Exemplo n.º 3
0
        private Expression GetIdentityCheck(TableExpression root, MappingEntity entity, Expression instance, MappingTable table)
        {
            if (this.mapping.IsExtensionTable(table))
            {
                var keyColNames    = this.mapping.GetExtensionKeyColumnNames(table).ToArray();
                var relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToArray();

                Expression where = null;
                for (int i = 0, n = keyColNames.Length; i < n; i++)
                {
                    var relatedMember = relatedMembers[i];
                    var cex           = new ColumnExpression(TypeHelper.GetMemberType(relatedMember), this.GetColumnType(entity, relatedMember), root.Alias, keyColNames[n]);
                    var nex           = this.GetMemberExpression(instance, entity, relatedMember);
                    var eq            = cex.Equal(nex);
                    where = (where != null) ? where.And(eq) : where;
                }

                return(where);
            }
            else
            {
                return(base.GetIdentityCheck(root, entity, instance));
            }
        }
Exemplo n.º 4
0
        private Expression GetIdentityCheck(TableExpression root, MappingEntity entity, Expression instance, MappingTable table)
        {
            if (this.mapping.IsExtensionTable(table))
            {
                var keyColNames = this.mapping.GetExtensionKeyColumnNames(table).ToArray();
                var relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToArray();

                Expression where = null;
                for (int i = 0, n = keyColNames.Length; i < n; i++)
                {
                    var relatedMember = relatedMembers[i];
                    var cex = new ColumnExpression(TypeHelper.GetMemberType(relatedMember), this.GetColumnType(entity, relatedMember), root.Alias, keyColNames[n]);
                    var nex = this.GetMemberExpression(instance, entity, relatedMember);
                    var eq = cex.Equal(nex);
                    where = (where != null) ? where.And(eq) : where;
                }
                return where;
            }
            else
            {
                return base.GetIdentityCheck(root, entity, instance);
            }
        }
Exemplo n.º 5
0
        public override ProjectionExpression GetQueryExpression(MappingEntity entity)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count <= 1)
            {
                return base.GetQueryExpression(entity);
            }

            var aliases = new Dictionary<string, TableAlias>();
            MappingTable rootTable = tables.Single(ta => !this.mapping.IsExtensionTable(ta));
            var tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(rootTable));
            aliases.Add(this.mapping.GetAlias(rootTable), tex.Alias);
            Expression source = tex;

            foreach (MappingTable table in tables.Where(t => this.mapping.IsExtensionTable(t)))
            {
                TableAlias joinedTableAlias = new TableAlias();
                string extensionAlias = this.mapping.GetAlias(table);
                aliases.Add(extensionAlias, joinedTableAlias);

                List<string> keyColumns = this.mapping.GetExtensionKeyColumnNames(table).ToList();
                List<MemberInfo> relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToList();
                string relatedAlias = this.mapping.GetExtensionRelatedAlias(table);

                TableAlias relatedTableAlias;
                aliases.TryGetValue(relatedAlias, out relatedTableAlias);

                TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, this.mapping.GetTableName(table));

                Expression cond = null;
                for (int i = 0, n = keyColumns.Count; i < n; i++)
                {
                    var memberType = TypeHelper.GetMemberType(relatedMembers[i]);
                    var colType = this.GetColumnType(entity, relatedMembers[i]);
                    var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias, this.mapping.GetColumnName(entity, relatedMembers[i]));
                    var joinedColumn = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]);
                    var eq = joinedColumn.Equal(relatedColumn);
                    cond = (cond != null) ? cond.And(eq) : eq;
                }

                source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond);
            }

            var columns = new List<ColumnDeclaration>();
            this.GetColumns(entity, aliases, columns);
            SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null);
            var existingAliases = aliases.Values.ToArray();

            Expression projector = this.GetEntityExpression(root, entity);
            var selectAlias = new TableAlias();
            var pc = ColumnProjector.ProjectColumns(this.Translator.Linguist.Language, projector, null, selectAlias, root.Alias);
            var proj = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, root, null),
                pc.Projector
                );

            return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType);
        }
 private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot)
 {
     bool isAll = method.Name == "All";
     ConstantExpression constSource = source as ConstantExpression;
     if (constSource != null && !IsQuery(constSource))
     {
         System.Diagnostics.Debug.Assert(!isRoot);
         Expression where = null;
         foreach (object value in (IEnumerable)constSource.Value)
         {
             Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type));
             if (where == null)
             {
                 where = expr;
             }
             else if (isAll)
             {
                 where = where.And(expr);
             }
             else
             {
                 where = where.Or(expr);
             }
         }
         return this.Visit(where);
     }
     else
     {
         if (isAll)
         {
             predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray());
         }
         if (predicate != null)
         {
             source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate);
         }
         ProjectionExpression projection = this.VisitSequence(source);
         Expression result = new ExistsExpression(projection.Select);
         if (isAll)
         {
             result = Expression.Not(result);
         }
         if (isRoot)
         {
             if (this.language.AllowSubqueryInSelectWithoutFrom)
             {
                 return GetSingletonSequence(result, "SingleOrDefault");
             }
             else
             {
                 // use count aggregate instead of exists
                 var colType = this.language.TypeSystem.GetColumnType(typeof(int));
                 var newSelect = projection.Select.SetColumns(
                     new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false), colType) }
                     );
                 var colx = new ColumnExpression(typeof(int), colType, newSelect.Alias, "value");
                 var exp = isAll
                     ? colx.Equal(Expression.Constant(0))
                     : colx.GreaterThan(Expression.Constant(0));
                 return new ProjectionExpression(
                     newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable<bool>))
                     );
             }
         }
         return result;
     }
 }
Exemplo n.º 7
0
 protected override Expression GetInsertResult(MappingEntity entity, Expression instance,
                                               LambdaExpression selector, Dictionary<MemberInfo, Expression> map)
 {
     var tables = _mapping.GetTables(entity);
     if (tables.Count <= 1)
     {
         return base.GetInsertResult(entity, instance, selector, map);
     }
     var aliases = new Dictionary<string, TableAlias>();
     MappingTable rootTable = tables.Single(ta => !_mapping.IsExtensionTable(ta));
     var tableExpression = new TableExpression(new TableAlias(), entity, _mapping.GetTableName(rootTable));
     var aggregator = Aggregator.GetAggregator(selector.Body.Type,
                                               typeof (IEnumerable<>).MakeGenericType(selector.Body.Type));
     aliases.Add(_mapping.GetAlias(rootTable), tableExpression.Alias);
     Expression source = tableExpression;
     foreach (MappingTable table in tables.Where(t => _mapping.IsExtensionTable(t)))
     {
         TableAlias joinedTableAlias = new TableAlias();
         string extensionAlias = _mapping.GetAlias(table);
         aliases.Add(extensionAlias, joinedTableAlias);
         List<string> keyColumns = _mapping.GetExtensionKeyColumnNames(table).ToList();
         List<MemberInfo> relatedMembers = _mapping.GetExtensionRelatedMembers(table).ToList();
         string relatedAlias = _mapping.GetExtensionRelatedAlias(table);
         TableAlias relatedTableAlias;
         aliases.TryGetValue(relatedAlias, out relatedTableAlias);
         TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, _mapping.GetTableName(table));
         Expression cond = null;
         for (int i = 0, n = keyColumns.Count; i < n; i++)
         {
             var memberType = TypeHelper.GetMemberType(relatedMembers[i]);
             var colType = GetColumnType(entity, relatedMembers[i]);
             var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias,
                                                      _mapping.GetColumnName(entity, relatedMembers[i]));
             var joinedColumn = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]);
             var eq = joinedColumn.Equal(relatedColumn);
             cond = (cond != null) ? cond.And(eq) : eq;
         }
         source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond);
     }
     Expression where;
     DeclarationCommand genIdCommand = null;
     var generatedIds =
         _mapping.GetMappedMembers(entity).Where(
             m => _mapping.IsPrimaryKey(entity, m) && _mapping.IsGenerated(entity, m)).ToList();
     if (generatedIds.Count > 0)
     {
         if (map == null || !generatedIds.Any(m => map.ContainsKey(m)))
         {
             var localMap = new Dictionary<MemberInfo, Expression>();
             genIdCommand = GetGeneratedIdCommand(entity, generatedIds.ToList(), localMap);
             map = localMap;
         }
         var mex = selector.Body as MemberExpression;
         if (mex != null && _mapping.IsPrimaryKey(entity, mex.Member) && _mapping.IsGenerated(entity, mex.Member))
         {
             if (genIdCommand != null)
             {
                 return new ProjectionExpression(
                     genIdCommand.Source,
                     new ColumnExpression(mex.Type, genIdCommand.Variables[0].QueryType,
                                          genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                     aggregator
                     );
             }
             TableAlias alias = new TableAlias();
             var colType = GetColumnType(entity, mex.Member);
             return new ProjectionExpression(
                 new SelectExpression(alias, new[] {new ColumnDeclaration("", map[mex.Member], colType)},
                                      null, null),
                 new ColumnExpression(TypeHelper.GetMemberType(mex.Member), colType, alias, ""),
                 aggregator
                 );
         }
         where = generatedIds.Select((m, i) =>
                                     GetMemberExpression(source, entity, m).Equal(map[m])
             ).Aggregate((x, y) => x.And(y));
     }
     else
     {
         where = GetIdentityCheck(tableExpression, entity, instance);
     }
     var columns = new List<ColumnDeclaration>();
     GetColumns(entity, aliases, columns);
     SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null);
     Expression typeProjector = GetEntityExpression(tableExpression, entity);
     Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
     TableAlias newAlias = new TableAlias();
     var pc = ColumnProjector.ProjectColumns(Translator.Linguist.Language, selection, null, newAlias,
                                             tableExpression.Alias);
     var pe = new ProjectionExpression(
         new SelectExpression(newAlias, pc.Columns, root, where),
         pc.Projector,
         aggregator
         );
     if (genIdCommand != null)
     {
         return new BlockCommand(genIdCommand, pe);
     }
     return pe;
 }
Exemplo n.º 8
0
        private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot)
        {
            bool isAll = method.Name.Equals("All", StringComparison.InvariantCultureIgnoreCase);
            ConstantExpression constSource = source as ConstantExpression;

            if (constSource != null && !IsQuery(constSource))
            {
                System.Diagnostics.Debug.Assert(!isRoot);
                Expression where = null;
                foreach (object value in (IEnumerable)constSource.Value)
                {
                    Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type));
                    if (where == null)
                    {
                        where = expr;
                    }
                    else if (isAll)
                    {
                        where = where.And(expr);
                    }
                    else
                    {
                        where = where.Or(expr);
                    }
                }
                return(this.Visit(where));
            }
            else
            {
                if (isAll)
                {
                    predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray());
                }
                if (predicate != null)
                {
                    source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate);
                }
                ProjectionExpression projection = this.VisitSequence(source);
                Expression           result     = new ExistsExpression(projection.Select);
                if (isAll)
                {
                    result = Expression.Not(result);
                }
                if (isRoot)
                {
                    if (this.language.AllowSubqueryInSelectWithoutFrom)
                    {
                        return(GetSingletonSequence(result, "SingleOrDefault"));
                    }
                    else
                    {
                        // use count aggregate instead of exists
                        //var colType = this.language.TypeSystem.GetColumnType(typeof(int));
                        var newSelect = projection.Select.SetColumns(new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false)) });
                        var colx      = new ColumnExpression(typeof(int), newSelect.Alias, "value");
                        var exp       = isAll ? colx.Equal(Expression.Constant(0)) : colx.GreaterThan(Expression.Constant(0)); return(new ProjectionExpression(newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable <bool>))));
                    }
                }
                return(result);
            }
        }