Example #1
0
        public override Expression GetDeleteExpression(MappingEntity entity, Expression instance, LambdaExpression deleteCheck)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count < 2)
            {
                return base.GetDeleteExpression(entity, instance, deleteCheck);
            }

            var commands = new List<Expression>();
            foreach (var table in this.GetDependencyOrderedTables(entity).Reverse())
            {
                TableExpression tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(table));
                var where = this.GetIdentityCheck(tex, entity, instance);
                commands.Add(new DeleteCommand(tex, where));
            }

            Expression block = new BlockCommand(commands);

            if (deleteCheck != null)
            {
                var test = this.GetEntityStateTest(entity, instance, deleteCheck);
                return new IFCommand(test, block, null);
            }

            return block;
        }
Example #2
0
        protected override Expression VisitTable(TableExpression table)
        {
            var columns = CurrentScope.Keys.Where(ce => ce.Alias == table.Alias).ToList();

            CurrentScope.SetRange(columns, columns.Cast<Expression>());

            return table;
        }
Example #3
0
        public override Expression GetDeleteExpression(MappingEntity entity, Expression instance, LambdaExpression deleteCheck)
        {
            TableExpression table = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(entity));
            Expression where = null;

            if (instance != null)
            {
                where = this.GetIdentityCheck(table, entity, instance);
            }

            if (deleteCheck != null)
            {
                Expression row = this.GetEntityExpression(table, entity);
                Expression pred = DbExpressionReplacer.Replace(deleteCheck.Body, deleteCheck.Parameters[0], row);
                where = (where != null) ? where.And(pred) : pred;
            }

            return new DeleteCommand(table, where);
        }
Example #4
0
        public SqlStatement TranslateNonQuery(DynamicLinqCommand command)
        {
            var translCtx = new TranslationContext(_dbModel, command);

            // convert lambda params into an initial set of ExternalValueExpression objects;
            foreach (var prm in command.Lambda.Parameters)
            {
                var inpParam = new ExternalValueExpression(prm);
                translCtx.ExternalValues.Add(inpParam);
            }
            //Analyze/transform base select query
            var selectExpr  = TranslateSelectExpression(command, translCtx);
            var targetEnt   = command.UpdateEntity;
            var targetTable = _dbModel.GetTable(targetEnt.EntityType);
            var nonQueryCmd = new NonQueryLinqCommand(command, targetTable, selectExpr);
            // Analyze base query output expression
            var targetTableExpr = new TableExpression(targetTable);
            var readerBody      = selectExpr.RowReaderLambda.Body;

            switch (nonQueryCmd.Operation)
            {
            case LinqOperation.Update:
            case LinqOperation.Insert:
                Util.Check(readerBody.NodeType == ExpressionType.New,
                           "Query for LINQ {0} command must return New object", nonQueryCmd.Operation);
                var newExpr   = readerBody as NewExpression;
                var outValues = selectExpr.Operands.ToList();
                for (int i = 0; i < newExpr.Members.Count; i++)
                {
                    var memberName = newExpr.Members[i].Name;
                    var memberInfo = targetEnt.GetMember(memberName);
                    Util.Check(memberInfo != null, "Member {0} not found in entity {1}.", memberName, targetEnt, targetEnt.EntityType);
                    switch (memberInfo.Kind)
                    {
                    case EntityMemberKind.Column:
                        var col = _translator.CreateColumnForMember(targetTableExpr, memberInfo, translCtx);
                        nonQueryCmd.TargetColumns.Add(col.ColumnInfo);
                        nonQueryCmd.SelectOutputValues.Add(outValues[i]);
                        break;

                    case EntityMemberKind.EntityRef:
                        var fromKey = memberInfo.ReferenceInfo.FromKey;
                        Util.Check(fromKey.ExpandedKeyMembers.Count == 1,
                                   "References with composite keys are not supported in LINQ non-query operations. Reference: ", memberName);
                        var pkMember = fromKey.ExpandedKeyMembers[0].Member;
                        var col2     = _translator.CreateColumnForMember(targetTableExpr, pkMember, translCtx);
                        nonQueryCmd.TargetColumns.Add(col2.ColumnInfo);
                        nonQueryCmd.SelectOutputValues.Add(outValues[i]);
                        break;

                    default:
                        Util.Throw("Property cannot be used in the context: {0}.", memberName);
                        break;
                    }
                }
                break;

            case LinqOperation.Delete:
                nonQueryCmd.SelectOutputValues.Add(readerBody); //should return single value - primary key
                break;
            }
            // Build SQL
            var sqlBuilder = _dbModel.Driver.CreateLinqNonQuerySqlBuilder(_dbModel, nonQueryCmd);
            var stmt       = sqlBuilder.BuildLinqNonQuerySql();

            return(stmt);
        } //method
Example #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);
        }
Example #6
0
 protected override Expression VisitTable(TableExpression table)
 {
     if (aliasMap.ContainsKey(table.Alias))
         return new TableExpression(aliasMap[table.Alias], table.Table);
     return table;
 }
Example #7
0
        protected virtual Expression GetInsertResult(MappingEntity entity, Expression instance, LambdaExpression selector, Dictionary<MemberInfo, Expression> map)
        {
            var tableAlias = new TableAlias();
            var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));
            var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable<>).MakeGenericType(selector.Body.Type));

            Expression where;
            DeclarationCommand genIdCommand = null;
            var generatedIds = this.mapping.GetMappedMembers(entity).Where(m => this.mapping.IsPrimaryKey(entity, m) && this.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 = this.GetGeneratedIdCommand(entity, generatedIds.ToList(), localMap);
                    map = localMap;
                }

                // is this just a retrieval of one generated id member?
                var mex = selector.Body as MemberExpression;
                if (mex != null && this.mapping.IsPrimaryKey(entity, mex.Member) && this.mapping.IsGenerated(entity, mex.Member))
                {
                    if (genIdCommand != null)
                    {
                        // just use the select from the genIdCommand
                        return new ProjectionExpression(
                            genIdCommand.Source,
                            new ColumnExpression(mex.Type, genIdCommand.Variables[0].QueryType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                            aggregator
                            );
                    }
                    else
                    {
                        TableAlias alias = new TableAlias();
                        var colType = this.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) =>
                    this.GetMemberExpression(tex, entity, m).Equal(map[m])
                    ).Aggregate((x, y) => x.And(y));
            }
            else
            {
                where = this.GetIdentityCheck(tex, entity, instance);
            }

            Expression typeProjector = this.GetEntityExpression(tex, entity);
            Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
            TableAlias newAlias = new TableAlias();
            var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, selection, null, newAlias, tableAlias);
            var pe = new ProjectionExpression(
                new SelectExpression(newAlias, pc.Columns, tex, where),
                pc.Projector,
                aggregator
                );

            if (genIdCommand != null)
            {
                return new BlockCommand(genIdCommand, pe);
            }
            return pe;
        }
Example #8
0
 protected abstract Expression VisitTable(TableExpression tableExpression);
        private SelectExpression GetCountSelectExpression(SelectExpression select)
        {
            BinaryExpression binaryExpression = select.Where as BinaryExpression;

            if (binaryExpression != null)
            {
                ScalarExpression scalarExpression = binaryExpression.Left as ScalarExpression;

                if (scalarExpression != null)
                {
                    SelectExpression selectCount = scalarExpression.Select as SelectExpression;

                    if (selectCount != null && selectCount.Columns.Count == 1)
                    {
                        AggregateExpression aggregateExpression = (AggregateExpression)selectCount.Columns[0].Expression;

                        if (aggregateExpression != null && aggregateExpression.AggregateName == "Count")
                        {
                            BinaryExpression where = selectCount.Where as BinaryExpression;

                            if (where != null)
                            {
                                ColumnExpression columnExpression = where.Left as ColumnExpression;

                                if (columnExpression != null)
                                {
                                    TableAlias      tableAlias      = new TableAlias();
                                    TableExpression tableExpression = (TableExpression)select.From;
                                    tableExpression = new TableExpression(tableAlias, tableExpression.Entity, tableExpression.Name);

                                    columnExpression = new ColumnExpression(columnExpression.Type, columnExpression.QueryType, tableAlias, columnExpression.Name);
                                    ColumnDeclaration columnDeclaration = new ColumnDeclaration(string.Empty, columnExpression, columnExpression.QueryType);

                                    BinaryExpression where2 = Expression.MakeBinary(where.NodeType, where.Left, columnExpression);
                                    selectCount = new SelectExpression(selectCount.Alias, selectCount.Columns, selectCount.From, where2);

                                    List <ColumnDeclaration> columns = new List <ColumnDeclaration> {
                                        new ColumnDeclaration("CountValue", new ScalarExpression(selectCount.Columns[0].Expression.Type, selectCount), selectCount.Columns[0].QueryType),
                                        columnDeclaration
                                    };

                                    selectCount = new SelectExpression(tableAlias,
                                                                       columns.ToReadOnly(),
                                                                       tableExpression,
                                                                       null,
                                                                       selectCount.OrderBy,
                                                                       null,
                                                                       selectCount.IsDistinct,
                                                                       selectCount.Skip,
                                                                       selectCount.Take,
                                                                       selectCount.IsReverse);

                                    ColumnExpression countValueColumnExpression = new ColumnExpression(selectCount.Columns[0].Expression.Type,
                                                                                                       selectCount.Columns[0].QueryType,
                                                                                                       tableAlias,
                                                                                                       "CountValue");

                                    SelectExpression newSelect = new SelectExpression(select.Alias,
                                                                                      select.Columns,
                                                                                      select.From,
                                                                                      null,
                                                                                      select.OrderBy,
                                                                                      select.GroupBy,
                                                                                      select.IsDistinct,
                                                                                      select.Skip,
                                                                                      select.Take,
                                                                                      select.IsReverse);

                                    JoinExpression joinExpression = new JoinExpression(JoinType.InnerJoin,
                                                                                       newSelect, selectCount,
                                                                                       Expression.MakeBinary(ExpressionType.Equal, columnExpression, where.Right));

                                    select = new SelectExpression(newSelect.Alias,
                                                                  newSelect.Columns,
                                                                  joinExpression,
                                                                  Expression.MakeBinary(binaryExpression.NodeType, countValueColumnExpression, binaryExpression.Right),
                                                                  newSelect.OrderBy,
                                                                  newSelect.GroupBy,
                                                                  newSelect.IsDistinct,
                                                                  newSelect.Skip,
                                                                  newSelect.Take,
                                                                  newSelect.IsReverse);

                                    return(select);
                                }
                            }
                        }
                    }
                }
            }

            return(null);
        }
 public Expression VisitTable(TableExpression expression)
 {
     TableVisited = true;
     return(expression);
 }
        public bool SetConfig(DBSourceConfig dbSourceConfig)
        {
            this.FinishControl = true;
            this.LastControl   = true;
            this.SelectStep    = false;

            if (dbSourceConfig.ConnString == this.lastConnectionString)
            {
                return(true);
            }

            ClearAllSetting();

            AvaliableConnecton = new OleDbConnection(dbSourceConfig.ConnString);

            Webb.Utilities.WaitingForm.SetWaitingMessage("Connecting database and reading data, Please wait..");

            try
            {
                AvaliableConnecton.Open();

                DataTable schemaTable = AvaliableConnecton.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

                foreach (DataRow dr in schemaTable.Rows)
                {
                    string tableName = dr["TABLE_NAME"].ToString();

                    TableExpression expresstion = new TableExpression(tableName);

                    expresstion.IsExpression = false;

                    this.checkedListTable.Items.Add(expresstion);
                }

                schemaTable.Dispose();

                foreach (TableExpression expression in this.checkedListTable.Items)
                {
                    schemaTable = AvaliableConnecton.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, expression.TableName, null });

                    expression.Fields.Clear();

                    foreach (DataRow dr in schemaTable.Rows)
                    {
                        string strName = dr["COLUMN_NAME"].ToString();

                        if (strName == null || strName == string.Empty)
                        {
                            continue;
                        }

                        if (!strName.StartsWith(expression.TableName + "."))
                        {
                            strName = expression.TableName + "." + strName;
                        }

                        ColumnExpression column = new ColumnExpression(strName);

                        expression.Fields.Add(column);
                    }

                    schemaTable.Dispose();
                }


                lastConnectionString = dbSourceConfig.ConnString;

                return(true);
            }
            catch (System.Exception ex)
            {
                Webb.Utilities.MessageBoxEx.ShowError("Failed to connect datatbase.\n" + ex.Message);

                return(false);
            }
        }
Example #12
0
        private void IncludeCollection(IQuerySource querySource, Type resultType, Expression accessorLambda, INavigation navigation)
        {
            var selectExpression = QueryCompilationContext.FindSelectExpression(querySource);

            var primaryKeyProperties = navigation.EntityType.GetPrimaryKey().Properties;

            foreach (var property in primaryKeyProperties)
            {
                selectExpression
                .AddToOrderBy(
                    QueryCompilationContext.GetColumnName(property),
                    property,
                    querySource,
                    OrderingDirection.Asc);
            }

            var targetEntityType = navigation.GetTargetType();
            var targetTableName  = QueryCompilationContext.GetTableName(targetEntityType);

            var targetSelectExpression = new SelectExpression();

            var targetTableAlias
                = CreateUniqueAlias(selectExpression, targetTableName.First().ToString().ToLower());

            var targetTableExpression
                = new TableExpression(
                      targetTableName,
                      QueryCompilationContext.GetSchema(targetEntityType),
                      targetTableAlias,
                      querySource);

            targetSelectExpression.AddTable(targetTableExpression);

            foreach (var property in targetEntityType.Properties)
            {
                targetSelectExpression
                .AddToProjection(
                    QueryCompilationContext.GetColumnName(property),
                    property,
                    querySource);
            }

            var innerJoinSelectExpression
                = selectExpression.Clone(
                      ((ColumnExpression)selectExpression.OrderBy.First().Expression).TableAlias);

            innerJoinSelectExpression.IsDistinct = true;
            innerJoinSelectExpression.ClearProjection();

            foreach (var columnExpression
                     in innerJoinSelectExpression.OrderBy
                     .Select(o => o.Expression)
                     .Cast <ColumnExpression>())
            {
                innerJoinSelectExpression.AddToProjection(columnExpression);
            }

            innerJoinSelectExpression.ClearOrderBy();

            var innerJoinExpression
                = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression);

            targetSelectExpression.AddToOrderBy(selectExpression.OrderBy);

            innerJoinExpression.Predicate
                = BuildJoinEqualityExpression(navigation, primaryKeyProperties, targetTableExpression, innerJoinExpression);

            var readerParameter = Expression.Parameter(typeof(DbDataReader));

            Expression
                = Expression.Call(
                      QueryCompilationContext.QueryMethodProvider.IncludeCollectionMethod
                      .MakeGenericMethod(resultType),
                      QueryContextParameter,
                      Expression,
                      Expression.Constant(navigation),
                      Expression.Call(
                          QueryCompilationContext.QueryMethodProvider.QueryMethod
                          .MakeGenericMethod(typeof(IValueReader)),
                          QueryContextParameter,
                          Expression.Constant(new CommandBuilder(targetSelectExpression, QueryCompilationContext)),
                          Expression.Lambda(
                              Expression.Call(
                                  _createValueReaderForIncludeMethodInfo,
                                  QueryContextParameter,
                                  readerParameter,
                                  Expression.Constant(targetEntityType)),
                              readerParameter)),
                      accessorLambda);
        }
Example #13
0
 public TableExpressionIdSet(TableExpression te)
 {
     TE = te;
 }
Example #14
0
 protected override Expression VisitTable(TableExpression tableExpression)
 {
     Sql.Append(_sqlGenerationHelper.DelimitIdentifier(tableExpression.Name, tableExpression.Schema));
     return(tableExpression);
 }
Example #15
0
        public object VisitTable(TableExpression tableExpression, SearchOptions context)
        {
            const string referenceSourceTableAlias         = "refSource";
            const string referenceTargetResourceTableAlias = "refTarget";

            switch (tableExpression.Kind)
            {
            case TableExpressionKind.Normal:

                if (tableExpression.ChainLevel == 0)
                {
                    StringBuilder.Append("SELECT ").Append(VLatest.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid1")
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table);
                }
                else
                {
                    StringBuilder.Append("SELECT Sid1, ").Append(VLatest.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid2")
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table)
                    .Append("INNER JOIN ").AppendLine(TableExpressionName(FindRestrictingPredecessorTableExpressionIndex()));

                    using (var delimited = StringBuilder.BeginDelimitedOnClause())
                    {
                        delimited.BeginDelimitedElement().Append(VLatest.Resource.ResourceSurrogateId, null).Append(" = ").Append("Sid2");
                    }
                }

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    AppendHistoryClause(delimited);

                    if (tableExpression.ChainLevel == 0)
                    {
                        // if chainLevel > 0, the intersection is already handled in the JOIN
                        AppendIntersectionWithPredecessor(delimited, tableExpression);
                    }

                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                    }

                    if (tableExpression.NormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.NormalizedPredicate.AcceptVisitor(tableExpression.SearchParameterQueryGenerator, GetContext());
                    }
                }

                break;

            case TableExpressionKind.Concatenation:
                StringBuilder.Append("SELECT * FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1));
                StringBuilder.AppendLine("UNION ALL");

                goto case TableExpressionKind.Normal;

            case TableExpressionKind.All:
                StringBuilder.Append("SELECT ").Append(VLatest.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid1")
                .Append("FROM ").AppendLine(VLatest.Resource);

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    AppendHistoryClause(delimited);
                    AppendDeletedClause(delimited);
                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                    }
                }

                break;

            case TableExpressionKind.NotExists:
                StringBuilder.Append("SELECT Sid1 FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1));
                StringBuilder.AppendLine("WHERE Sid1 NOT IN").AppendLine("(");

                using (StringBuilder.Indent())
                {
                    StringBuilder.Append("SELECT ").AppendLine(VLatest.Resource.ResourceSurrogateId, null)
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table);
                    using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                    {
                        AppendHistoryClause(delimited);

                        if (tableExpression.DenormalizedPredicate != null)
                        {
                            delimited.BeginDelimitedElement();
                            tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                        }

                        delimited.BeginDelimitedElement();
                        tableExpression.NormalizedPredicate.AcceptVisitor(tableExpression.SearchParameterQueryGenerator, GetContext());
                    }
                }

                StringBuilder.AppendLine(")");
                break;

            case TableExpressionKind.Top:
                var(paramInfo, sortOrder) = context.GetFirstSupportedSortParam();
                var tableExpressionName = TableExpressionName(_tableExpressionCounter - 1);
                var sortExpression      = (paramInfo == null || paramInfo.Name == KnownQueryParameterNames.LastUpdated) ? null : $"{tableExpressionName}.SortValue";

                // Everything in the top expression is considered a match
                StringBuilder.Append("SELECT DISTINCT TOP (").Append(Parameters.AddParameter(context.MaxItemCount + 1)).Append(") Sid1, 1 AS IsMatch, 0 AS IsPartial ")
                .AppendLine(sortExpression == null ? string.Empty : $", {sortExpression}")
                .Append("FROM ").AppendLine(tableExpressionName)
                .AppendLine($"ORDER BY {(sortExpression == null ? string.Empty : $"{sortExpression} {(sortOrder == SortOrder.Ascending ? "ASC" : "DESC")}, ")} Sid1 {((sortExpression != null || sortOrder == SortOrder.Ascending) ? "ASC" : "DESC")}");

                // For any includes, the source of the resource surrogate ids to join on is saved
                _cteMainSelect = TableExpressionName(_tableExpressionCounter);

                break;
Example #16
0
        private static IEnumerable <ColumnAssignment> GetAssignmentsForPrimaryKeys(ISyntaxProvider syntax, TableExpression table, ParameterExpression parExp, IEntity entity)
        {
            var entityType  = parExp != null ? parExp.Type : entity.EntityType;
            var assignments = new List <ColumnAssignment>();

            foreach (var p in PropertyUnity.GetPrimaryProperties(entityType))
            {
                var pvExp = GetPrimaryValueExpression(syntax, table, parExp, entity, p);

                if (pvExp != null)
                {
                    var columnExp = (ColumnExpression)GetMemberExpression(table, p);
                    assignments.Add(new ColumnAssignment(columnExp, pvExp));
                }
            }

            return(assignments);
        }
Example #17
0
        private IEnumerable <Expression> CreateIncludeRelatedValuesStrategyFactories(
            IQuerySource querySource,
            IEnumerable <INavigation> navigationPath)
        {
            var selectExpression
                = _queryCompilationContext.FindSelectExpression(querySource);

            var targetTableExpression
                = selectExpression.GetTableForQuerySource(querySource);

            var canProduceInnerJoin = true;
            var navigationCount     = 0;

            foreach (var navigation in navigationPath)
            {
                var queryIndex = _queryIndexes[navigationCount];
                navigationCount++;

                var targetEntityType = navigation.GetTargetType();
                var targetTableName  = _relationalAnnotationProvider.For(targetEntityType).TableName;
                var targetTableAlias = targetTableName[0].ToString().ToLower();

                if (!navigation.IsCollection())
                {
                    var joinedTableExpression
                        = new TableExpression(
                              targetTableName,
                              _relationalAnnotationProvider.For(targetEntityType).Schema,
                              targetTableAlias,
                              querySource);

                    var valueBufferOffset = selectExpression.Projection.Count;

                    canProduceInnerJoin
                        = canProduceInnerJoin && navigation.ForeignKey.IsRequired && navigation.IsDependentToPrincipal();

                    var joinExpression
                        = canProduceInnerJoin
                            ? selectExpression
                          .AddInnerJoin(joinedTableExpression)
                            : selectExpression
                          .AddOuterJoin(joinedTableExpression);

                    var oldPredicate = selectExpression.Predicate;

                    var materializer
                        = _materializerFactory
                          .CreateMaterializer(
                              targetEntityType,
                              selectExpression,
                              (p, se) => se.AddToProjection(
                                  new AliasExpression(
                                      new ColumnExpression(
                                          _relationalAnnotationProvider.For(p).ColumnName,
                                          p,
                                          joinedTableExpression))) - valueBufferOffset,
                              querySource: null);

                    if (selectExpression.Predicate != oldPredicate)
                    {
                        var newJoinExpression = AdjustJoinExpression(selectExpression, joinExpression);

                        selectExpression.Predicate = oldPredicate;
                        selectExpression.RemoveTable(joinExpression);
                        selectExpression.AddTable(newJoinExpression);
                        joinExpression = newJoinExpression;
                    }

                    joinExpression.Predicate
                        = BuildJoinEqualityExpression(
                              navigation,
                              navigation.IsDependentToPrincipal() ? targetTableExpression : joinExpression,
                              navigation.IsDependentToPrincipal() ? joinExpression : targetTableExpression,
                              querySource);

                    targetTableExpression = joinedTableExpression;

                    yield return
                        (Expression.Lambda(
                             Expression.Call(
                                 _queryCompilationContext.QueryMethodProvider
                                 .CreateReferenceIncludeRelatedValuesStrategyMethod,
                                 Expression.Convert(
                                     EntityQueryModelVisitor.QueryContextParameter,
                                     typeof(RelationalQueryContext)),
                                 Expression.Constant(valueBufferOffset),
                                 Expression.Constant(queryIndex),
                                 materializer)));
                }
                else
                {
                    var principalTable
                        = (selectExpression.Tables.Count == 1) &&
                          selectExpression.Tables.OfType <SelectExpression>().Any(s => s.Tables.Any(t => t.QuerySource == querySource))
                          // true when select is wrapped e.g. when RowNumber paging is enabled
                            ? selectExpression.Tables[0]
                            : selectExpression.Tables.Last(t => t.QuerySource == querySource);

                    foreach (var property in navigation.ForeignKey.PrincipalKey.Properties)
                    {
                        selectExpression
                        .AddToOrderBy(
                            _relationalAnnotationProvider.For(property).ColumnName,
                            property,
                            principalTable,
                            OrderingDirection.Asc);
                    }

                    var targetSelectExpression = _selectExpressionFactory.Create();

                    targetTableExpression
                        = new TableExpression(
                              targetTableName,
                              _relationalAnnotationProvider.For(targetEntityType).Schema,
                              targetTableAlias,
                              querySource);

                    targetSelectExpression.AddTable(targetTableExpression);

                    var materializer
                        = _materializerFactory
                          .CreateMaterializer(
                              targetEntityType,
                              targetSelectExpression,
                              (p, se) => se.AddToProjection(
                                  _relationalAnnotationProvider.For(p).ColumnName,
                                  p,
                                  querySource),
                              querySource: null);

                    var innerJoinSelectExpression
                        = selectExpression.Clone(
                              selectExpression.OrderBy
                              .Select(o => o.Expression)
                              .Last(o => o.IsAliasWithColumnExpression())
                              .TryGetColumnExpression().TableAlias);

                    innerJoinSelectExpression.ClearProjection();

                    var innerJoinExpression = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression);

                    LiftOrderBy(innerJoinSelectExpression, targetSelectExpression, innerJoinExpression);

                    innerJoinSelectExpression.IsDistinct = true;

                    innerJoinExpression.Predicate
                        = BuildJoinEqualityExpression(
                              navigation,
                              targetTableExpression,
                              innerJoinExpression,
                              querySource);

                    selectExpression = targetSelectExpression;

                    yield return
                        (Expression.Lambda(
                             Expression.Call(
                                 _queryCompilationContext.QueryMethodProvider
                                 .CreateCollectionIncludeRelatedValuesStrategyMethod,
                                 Expression.Call(
                                     _queryCompilationContext.QueryMethodProvider.QueryMethod,
                                     EntityQueryModelVisitor.QueryContextParameter,
                                     Expression.Constant(
                                         _shaperCommandContextFactory.Create(
                                             () => _querySqlGeneratorFactory
                                             .CreateDefault(targetSelectExpression))),
                                     Expression.Constant(queryIndex, typeof(int?))),
                                 materializer)));
                }
            }
        }
Example #18
0
 protected DeleteCommand UpdateDelete(DeleteCommand delete, TableExpression table, Expression where)
 {
     if (table != delete.Table || where != delete.Where)
     {
         return new DeleteCommand(table, where,delete.Instance, delete.SupportsVersionCheck);
     }
     return delete;
 }
Example #19
0
        protected override Expression VisitTable(TableExpression table)
        {
            if (gatheredKeys != null)
                gatheredKeys.Add(table.GetIdExpression());

            return table;
        }
Example #20
0
 public virtual string GetColumnName(TableExpression tableExpression, MemberInfo memberInfo, DataContext dataContext)
 {
     return(GetColumnName(tableExpression.Type, memberInfo, dataContext));
 }
Example #21
0
        public override ProjectionExpression GetQueryExpression(MappingEntity entity)
        {
            var tableAlias = new TableAlias();
            var selectAlias = new TableAlias();
            var table = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));

            Expression projector = this.GetEntityExpression(table, entity);
            var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, projector, null, selectAlias, tableAlias);

            var proj = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, table, null),
                pc.Projector
                );

            return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType);
        }
Example #22
0
        public object VisitTable(TableExpression tableExpression, SearchOptions context)
        {
            string referenceTableAlias = "ref";
            string resourceTableAlias  = "r";

            switch (tableExpression.Kind)
            {
            case TableExpressionKind.Normal:

                if (tableExpression.ChainLevel == 0)
                {
                    StringBuilder.Append("SELECT ").Append(VLatest.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid1")
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table);
                }
                else
                {
                    StringBuilder.Append("SELECT Sid1, ").Append(VLatest.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid2")
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table)
                    .Append("INNER JOIN ").AppendLine(TableExpressionName(FindRestrictingPredecessorTableExpressionIndex()));

                    using (var delimited = StringBuilder.BeginDelimitedOnClause())
                    {
                        delimited.BeginDelimitedElement().Append(VLatest.Resource.ResourceSurrogateId, null).Append(" = ").Append("Sid2");
                    }
                }

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    AppendHistoryClause(delimited);

                    if (tableExpression.ChainLevel == 0)
                    {
                        // if chainLevel > 0, the intersection is already handled in the JOIN
                        AppendIntersectionWithPredecessor(delimited, tableExpression);
                    }

                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                    }

                    if (tableExpression.NormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.NormalizedPredicate.AcceptVisitor(tableExpression.SearchParameterQueryGenerator, GetContext());
                    }
                }

                break;

            case TableExpressionKind.Concatenation:
                StringBuilder.Append("SELECT * FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1));
                StringBuilder.AppendLine("UNION ALL");

                goto case TableExpressionKind.Normal;

            case TableExpressionKind.All:
                StringBuilder.Append("SELECT ").Append(VLatest.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid1")
                .Append("FROM ").AppendLine(VLatest.Resource);

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    AppendHistoryClause(delimited);
                    AppendDeletedClause(delimited);
                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                    }
                }

                break;

            case TableExpressionKind.NotExists:
                StringBuilder.Append("SELECT Sid1 FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1));
                StringBuilder.AppendLine("WHERE Sid1 NOT IN").AppendLine("(");

                using (StringBuilder.Indent())
                {
                    StringBuilder.Append("SELECT ").AppendLine(VLatest.Resource.ResourceSurrogateId, null)
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table);
                    using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                    {
                        AppendHistoryClause(delimited);

                        if (tableExpression.DenormalizedPredicate != null)
                        {
                            delimited.BeginDelimitedElement();
                            tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                        }

                        delimited.BeginDelimitedElement();
                        tableExpression.NormalizedPredicate.AcceptVisitor(tableExpression.SearchParameterQueryGenerator, GetContext());
                    }
                }

                StringBuilder.AppendLine(")");
                break;

            case TableExpressionKind.Top:
                // Everything in the top expression is considered a match
                StringBuilder.Append("SELECT DISTINCT TOP (").Append(Parameters.AddParameter(context.MaxItemCount + 1)).AppendLine(") Sid1, 1 AS IsMatch ")
                .Append("FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1))
                .AppendLine("ORDER BY Sid1 ASC");

                // For any includes, the source of the resource surrogate ids to join on is saved
                _cteMainSelect = TableExpressionName(_tableExpressionCounter);

                break;

            case TableExpressionKind.Chain:
                var    chainedExpression   = (ChainedExpression)tableExpression.NormalizedPredicate;
                string resourceTableAlias2 = "r2";

                StringBuilder.Append("SELECT ");
                if (tableExpression.ChainLevel == 1)
                {
                    StringBuilder.Append(VLatest.ReferenceSearchParam.ResourceSurrogateId, referenceTableAlias).Append(" AS ").Append(chainedExpression.Reversed ? "Sid2" : "Sid1").Append(", ");
                }
                else
                {
                    StringBuilder.Append("Sid1, ");
                }

                StringBuilder.Append(VLatest.Resource.ResourceSurrogateId, chainedExpression.Reversed && tableExpression.ChainLevel > 1 ? referenceTableAlias : resourceTableAlias).Append(" AS ").AppendLine(chainedExpression.Reversed && tableExpression.ChainLevel == 1 ? "Sid1 " : "Sid2 ")
                .Append("FROM ").Append(VLatest.ReferenceSearchParam).Append(' ').AppendLine(referenceTableAlias)
                .Append("INNER JOIN ").Append(VLatest.Resource).Append(' ').AppendLine(resourceTableAlias);

                using (var delimited = StringBuilder.BeginDelimitedOnClause())
                {
                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ReferenceResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(VLatest.Resource.ResourceTypeId, resourceTableAlias);

                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ReferenceResourceId, referenceTableAlias)
                    .Append(" = ").Append(VLatest.Resource.ResourceId, resourceTableAlias);
                }

                // Denormalized predicates on reverse chains need to be applied via a join to the resource table
                if (tableExpression.DenormalizedPredicate != null && chainedExpression.Reversed)
                {
                    StringBuilder.Append("INNER JOIN ").Append(VLatest.Resource).Append(' ').AppendLine(resourceTableAlias2);

                    using (var delimited = StringBuilder.BeginDelimitedOnClause())
                    {
                        delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ResourceSurrogateId, referenceTableAlias)
                        .Append(" = ").Append(VLatest.Resource.ResourceSurrogateId, resourceTableAlias2);

                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext(resourceTableAlias2));
                    }
                }

                if (tableExpression.ChainLevel > 1)
                {
                    StringBuilder.Append("INNER JOIN ").AppendLine(TableExpressionName(FindRestrictingPredecessorTableExpressionIndex()));

                    using (var delimited = StringBuilder.BeginDelimitedOnClause())
                    {
                        delimited.BeginDelimitedElement().Append(VLatest.Resource.ResourceSurrogateId, chainedExpression.Reversed ? resourceTableAlias : referenceTableAlias).Append(" = ").Append("Sid2");
                    }
                }

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.SearchParamId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(VLatest.ReferenceSearchParam.SearchParamId, Model.GetSearchParamId(chainedExpression.ReferenceSearchParameter.Url)));

                    AppendHistoryClause(delimited, resourceTableAlias);
                    AppendHistoryClause(delimited, referenceTableAlias);

                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(VLatest.ReferenceSearchParam.ResourceTypeId, Model.GetResourceTypeId(chainedExpression.ResourceType)));

                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ReferenceResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(VLatest.ReferenceSearchParam.ReferenceResourceTypeId, Model.GetResourceTypeId(chainedExpression.TargetResourceType)));

                    if (tableExpression.ChainLevel == 1)
                    {
                        // if > 1, the intersection is handled by the JOIN
                        AppendIntersectionWithPredecessor(delimited, tableExpression, chainedExpression.Reversed ? resourceTableAlias : referenceTableAlias);
                    }

                    if (tableExpression.DenormalizedPredicate != null && !chainedExpression.Reversed)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext(resourceTableAlias));
                    }
                }

                break;

            case TableExpressionKind.Include:
                var includeExpression = (IncludeExpression)tableExpression.NormalizedPredicate;

                StringBuilder.Append("SELECT DISTINCT ");
                StringBuilder.Append(VLatest.Resource.ResourceSurrogateId, resourceTableAlias).AppendLine(" AS Sid1, 0 AS IsMatch")
                .Append("FROM ").Append(VLatest.ReferenceSearchParam).Append(' ').AppendLine(referenceTableAlias)
                .Append("INNER JOIN ").Append(VLatest.Resource).Append(' ').AppendLine(resourceTableAlias);

                using (var delimited = StringBuilder.BeginDelimitedOnClause())
                {
                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ReferenceResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(VLatest.Resource.ResourceTypeId, resourceTableAlias);

                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ReferenceResourceId, referenceTableAlias)
                    .Append(" = ").Append(VLatest.Resource.ResourceId, resourceTableAlias);
                }

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    if (!includeExpression.WildCard)
                    {
                        delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.SearchParamId, referenceTableAlias)
                        .Append(" = ").Append(Parameters.AddParameter(VLatest.ReferenceSearchParam.SearchParamId, Model.GetSearchParamId(includeExpression.ReferenceSearchParameter.Url)));

                        if (includeExpression.TargetResourceType != null)
                        {
                            delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ReferenceResourceTypeId, referenceTableAlias)
                            .Append(" = ").Append(Parameters.AddParameter(VLatest.ReferenceSearchParam.ReferenceResourceTypeId, Model.GetResourceTypeId(includeExpression.TargetResourceType)));
                        }
                    }

                    AppendHistoryClause(delimited, resourceTableAlias);
                    AppendHistoryClause(delimited, referenceTableAlias);

                    delimited.BeginDelimitedElement().Append(VLatest.ReferenceSearchParam.ResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(VLatest.ReferenceSearchParam.ResourceTypeId, Model.GetResourceTypeId(includeExpression.ResourceType)));

                    // Limit the join to the main select CTE.
                    // The main select will have max+1 items in the result set to account for paging, so we only want to join using the max amount.
                    delimited.BeginDelimitedElement().Append(VLatest.Resource.ResourceSurrogateId, referenceTableAlias)
                    .Append(" IN (SELECT TOP(")
                    .Append(Parameters.AddParameter(context.MaxItemCount))
                    .Append(") Sid1 FROM ").Append(_cteMainSelect).Append(")");
                }

                if (_includeCtes == null)
                {
                    _includeCtes = new List <string>();
                }

                _includeCtes.Add(TableExpressionName(_tableExpressionCounter));
                break;

            case TableExpressionKind.IncludeUnionAll:
                StringBuilder.AppendLine("SELECT Sid1, IsMatch");
                StringBuilder.Append("FROM ").AppendLine(_cteMainSelect);

                foreach (var includeCte in _includeCtes)
                {
                    StringBuilder.AppendLine("UNION ALL");
                    StringBuilder.AppendLine("SELECT Sid1, IsMatch ");
                    StringBuilder.Append("FROM ").AppendLine(includeCte);
                }

                break;

            default:
                throw new ArgumentOutOfRangeException(tableExpression.Kind.ToString());
            }

            return(null);
        }
 protected virtual bool CompareTable(TableExpression a, TableExpression b)
 {
     return a.Name == b.Name;
 }
Example #24
0
 public JoinExpressionViewModel(HermesViewModel parent, TableExpression model) : base(parent, model)
 {
     //this.Filter = new BooleanExpressionViewModel(this, "ON");
 }
Example #25
0
 protected internal override Expression VisitTable(TableExpression table)
 {
     this.aliases.Add(table.Alias);
     return base.VisitTable(table);
 }
 protected override Expression VisitTable(TableExpression tableExpression)
 => tableExpression;
Example #27
0
        // make a variable declaration / initialization for dependent generated values
        private CommandExpression GetDependentGeneratedVariableDeclaration(MappingEntity entity, MappingTable table, List<MemberInfo> members, Expression instance, Dictionary<MemberInfo, Expression> map)
        {
            // first make command that retrieves the generated ids if any
            DeclarationCommand genIdCommand = null;
            var generatedIds = this.mapping.GetMappedMembers(entity).Where(m => this.mapping.IsPrimaryKey(entity, m) && this.mapping.IsGenerated(entity, m)).ToList();
            if (generatedIds.Count > 0)
            {
                genIdCommand = this.GetGeneratedIdCommand(entity, members, map);

                // if that's all there is then just return the generated ids
                if (members.Count == generatedIds.Count)
                {
                    return genIdCommand;
                }
            }

            // next make command that retrieves the generated members
            // only consider members that were not generated ids
            members = members.Except(generatedIds).ToList();

            var tableAlias = new TableAlias();
            var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(table));

            Expression where = null;
            if (generatedIds.Count > 0)
            {
                where = generatedIds.Select((m, i) =>
                    this.GetMemberExpression(tex, entity, m).Equal(map[m])
                    ).Aggregate((x, y) => x.And(y));
            }
            else
            {
                where = this.GetIdentityCheck(tex, entity, instance);
            }

            TableAlias selectAlias = new TableAlias();
            var columns = new List<ColumnDeclaration>();
            var variables = new List<VariableDeclaration>();
            foreach (var mi in members)
            {
                ColumnExpression col = (ColumnExpression)this.GetMemberExpression(tex, entity, mi);
                columns.Add(new ColumnDeclaration(this.mapping.GetColumnName(entity, mi), col, col.QueryType));
                ColumnExpression vcol = new ColumnExpression(col.Type, col.QueryType, selectAlias, col.Name);
                variables.Add(new VariableDeclaration(mi.Name, col.QueryType, vcol));
                map.Add(mi, new VariableExpression(mi.Name, col.Type, col.QueryType));
            }

            var genMembersCommand = new DeclarationCommand(variables, new SelectExpression(selectAlias, columns, tex, where));

            if (genIdCommand != null)
            {
                return new BlockCommand(genIdCommand, genMembersCommand);
            }

            return genMembersCommand;
        }
 /// <summary>
 /// Format a table expression
 /// </summary>
 /// <param name="tableExpression">the table expression to be formatted</param>
 /// <returns>table expression unchanged</returns>
 protected override Expression VisitTable(TableExpression tableExpression)
 {
     this.Builder.Append(tableExpression.Name);
     return(tableExpression);
 }
Example #29
0
 protected override Expression VisitTable(TableExpression table)
 {
     TableAlias newAlias = new TableAlias();
     this.map[table.Alias] = newAlias;
     return new TableExpression(newAlias, table.Entity, table.Name);
 }
Example #30
0
            public static Expression Replace(Expression where, Expression expression, TableExpression table, IEnumerable <ColumnDeclaration> columns)
            {
                var visitor = new PolicyConditionReplacer {
                    where = where, columns = columns
                };

                visitor.Visit(PartialEvaluator.Eval(expression));
                return(visitor.where);
            }
Example #31
0
        /// <summary>
        /// 返回插入具体实体时的 <see cref="ColumnAssignment"/> 集合。
        /// </summary>
        /// <param name="syntax"></param>
        /// <param name="table"></param>
        /// <param name="parExp"></param>
        /// <returns></returns>
        private static IEnumerable <ColumnAssignment> GetInsertArguments(ISyntaxProvider syntax, TableExpression table, ParameterExpression parExp)
        {
            IEnumerable <IProperty> properties    = null;
            List <string>           modifiedNames = null;

            if ((modifiedNames = GetReferenceModifiedProperties()) != null)
            {
                properties = GetModifiedProperties(table.Type, modifiedNames);
            }

            var assignments = properties
                              .Select(m => new ColumnAssignment(
                                          (ColumnExpression)GetMemberExpression(table, m),
                                          Expression.MakeMemberAccess(parExp, m.Info.ReflectionInfo)
                                          )).ToList();

            assignments.AddRange(GetAssignmentsForPrimaryKeys(syntax, table, parExp, null));

            return(assignments);
        }
 public Expression VisitTable(TableExpression tableExpression, object context)
 {
     throw new InvalidOperationException();
 }
        /// <summary>
        /// Registers an association
        /// </summary>
        /// <param name="tableExpression">The table holding the member, to become the joinedTable</param>
        /// <param name="tableMemberInfo"></param>
        /// <param name="otherType"></param>
        /// <param name="builderContext"></param>
        /// <returns></returns>
        public virtual TableExpression RegisterAssociation(TableExpression tableExpression, MemberInfo tableMemberInfo,
                                                           Type otherType, BuilderContext builderContext)
        {
            IList <MemberInfo> otherKeys;
            TableJoinType      joinType;
            string             joinID;
            var theseKeys = DataMapper.GetAssociation(tableExpression, tableMemberInfo, otherType, out otherKeys,
                                                      out joinType, out joinID, builderContext.QueryContext.DataContext);

            // if the memberInfo has no corresponding association, we get a null, that we propagate
            if (theseKeys == null)
            {
                return(null);
            }

            // the current table has the foreign key, the other table the referenced (usually primary) key
            if (theseKeys.Count != otherKeys.Count)
            {
                throw Error.BadArgument("S0128: Association arguments (FK and ref'd PK) don't match");
            }

            // we first create the table, with the JoinID, and we MUST complete the table later, with the Join() method
            var otherTableExpression = new TableExpression(otherType, DataMapper.GetTableName(otherType, builderContext.QueryContext.DataContext), joinID);

            Expression joinExpression = null;

            var createdColumns = new List <ColumnExpression>();

            for (int keyIndex = 0; keyIndex < theseKeys.Count; keyIndex++)
            {
                // joinedKey is registered, even if unused by final select (required columns will be filtered anyway)
                Expression otherKey = RegisterColumn(otherTableExpression, otherKeys[keyIndex], builderContext);
                // foreign is created, we will store it later if this assocation is registered too
                Expression thisKey = CreateColumn(tableExpression, theseKeys[keyIndex], builderContext);
                createdColumns.Add((ColumnExpression)thisKey);

                // if the key is nullable, then convert it
                // TODO: this will probably need to be changed
                if (otherKey.Type.IsNullable())
                {
                    otherKey = Expression.Convert(otherKey, otherKey.Type.GetNullableType());
                }
                if (thisKey.Type.IsNullable())
                {
                    thisKey = Expression.Convert(thisKey, thisKey.Type.GetNullableType());
                }
                // the other key is set as left operand, this must be this way
                // since some vendors (SQL Server) don't support the opposite
                var referenceExpression = Expression.Equal(otherKey, thisKey);

                // if we already have a join expression, then we have a double condition here, so "AND" it
                if (joinExpression != null)
                {
                    joinExpression = Expression.And(joinExpression, referenceExpression);
                }
                else
                {
                    joinExpression = referenceExpression;
                }
            }
            // we complete the table here, now that we have all join information
            otherTableExpression.Join(joinType, tableExpression, joinExpression);

            // our table is created, with the expressions
            // now check if we didn't register exactly the same
            var existingTable = (from t in builderContext.EnumerateScopeTables() where t.IsEqualTo(otherTableExpression) select t).SingleOrDefault();

            if (existingTable != null)
            {
                return(existingTable);
            }

            builderContext.CurrentSelect.Tables.Add(otherTableExpression);
            foreach (var createdColumn in createdColumns)
            {
                builderContext.CurrentSelect.Columns.Add(createdColumn);
            }
            return(otherTableExpression);
        }
Example #34
0
        public BinaryExpression ToEqualExpression(object obj, TableExpression table = null)
        {
            var value = GetValue(obj);

            return(Expression.MakeBinary(ExpressionType.Equal, ToColumnExpression(table), Expression.Constant(value)));
        }
        private IEnumerable <Expression> CreateIncludeRelatedValuesStrategyFactories(
            IQuerySource querySource,
            IEnumerable <INavigation> navigationPath)
        {
            var selectExpression
                = _queryCompilationContext.FindSelectExpression(querySource);

            var targetTableExpression
                = selectExpression.FindTableForQuerySource(querySource);

            var readerIndex         = 0;
            var canProduceInnerJoin = true;

            foreach (var navigation in navigationPath)
            {
                var targetEntityType = navigation.GetTargetType();
                var targetTableName  = _queryCompilationContext.GetTableName(targetEntityType);
                var targetTableAlias = targetTableName[0].ToString().ToLower();

                if (!navigation.IsCollection())
                {
                    var joinedTableExpression
                        = new TableExpression(
                              targetTableName,
                              _queryCompilationContext.GetSchema(targetEntityType),
                              targetTableAlias,
                              querySource);

                    var valueBufferOffset = selectExpression.Projection.Count;

                    canProduceInnerJoin
                        = canProduceInnerJoin &&
                          (navigation.ForeignKey.IsRequired &&
                           navigation.PointsToPrincipal());

                    var joinExpression
                        = canProduceInnerJoin
                            ? selectExpression
                          .AddInnerJoin(joinedTableExpression)
                            : selectExpression
                          .AddOuterJoin(joinedTableExpression);

                    var materializer
                        = new MaterializerFactory(
                              _queryCompilationContext.EntityMaterializerSource)
                          .CreateMaterializer(
                              targetEntityType,
                              selectExpression,
                              projectionAdder:
                              (p, se) => se.AddToProjection(
                                  new AliasExpression(
                                      new ColumnExpression(
                                          _queryCompilationContext.GetColumnName(p),
                                          p,
                                          joinedTableExpression))) - valueBufferOffset,
                              querySource: null);

                    joinExpression.Predicate
                        = BuildJoinEqualityExpression(
                              navigation,
                              (navigation.PointsToPrincipal()
                                ? targetEntityType
                                : navigation.EntityType)
                              .GetPrimaryKey().Properties,
                              navigation.PointsToPrincipal() ? targetTableExpression : joinExpression,
                              navigation.PointsToPrincipal() ? joinExpression : targetTableExpression);

                    targetTableExpression = joinedTableExpression;

                    yield return
                        (Expression.Lambda(
                             Expression.Call(
                                 _queryCompilationContext.QueryMethodProvider
                                 .CreateReferenceIncludeRelatedValuesStrategyMethod,
                                 Expression.Convert(
                                     EntityQueryModelVisitor.QueryContextParameter,
                                     typeof(RelationalQueryContext)),
                                 Expression.Constant(valueBufferOffset),
                                 Expression.Constant(readerIndex),
                                 materializer)));
                }
                else
                {
                    var principalTable
                        = selectExpression.Tables.Last(t => t.QuerySource == querySource);

                    foreach (var property in navigation.EntityType.GetPrimaryKey().Properties)
                    {
                        selectExpression
                        .AddToOrderBy(
                            _queryCompilationContext.GetColumnName(property),
                            property,
                            principalTable,
                            OrderingDirection.Asc);
                    }

                    var targetSelectExpression = new SelectExpression();

                    targetTableExpression
                        = new TableExpression(
                              targetTableName,
                              _queryCompilationContext.GetSchema(targetEntityType),
                              targetTableAlias,
                              querySource);

                    targetSelectExpression.AddTable(targetTableExpression);

                    var materializer
                        = new MaterializerFactory(
                              _queryCompilationContext.EntityMaterializerSource)
                          .CreateMaterializer(
                              targetEntityType,
                              targetSelectExpression,
                              (p, se) => se.AddToProjection(
                                  _queryCompilationContext.GetColumnName(p),
                                  p,
                                  querySource),
                              querySource: null);

                    var innerJoinSelectExpression
                        = selectExpression.Clone(
                              selectExpression.OrderBy.Select(o => o.Expression).Last(o => o.IsAliasWithColumnExpression())
                              .TryGetColumnExpression().TableAlias);

                    innerJoinSelectExpression.IsDistinct = true;
                    innerJoinSelectExpression.ClearProjection();

                    foreach (var expression
                             in innerJoinSelectExpression.OrderBy
                             .Select(o => o.Expression))
                    {
                        innerJoinSelectExpression.AddToProjection(expression);
                    }

                    innerJoinSelectExpression.ClearOrderBy();

                    var primaryKeyProperties = navigation.EntityType.GetPrimaryKey().Properties;

                    var innerJoinExpression
                        = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression);

                    targetSelectExpression.UpdateOrderByColumnBinding(selectExpression.OrderBy, innerJoinExpression);

                    innerJoinExpression.Predicate
                        = BuildJoinEqualityExpression(
                              navigation,
                              primaryKeyProperties,
                              targetTableExpression,
                              innerJoinExpression);

                    selectExpression = targetSelectExpression;
                    readerIndex++;

                    yield return
                        (Expression.Lambda(
                             Expression.Call(
                                 _queryCompilationContext.QueryMethodProvider
                                 .CreateCollectionIncludeRelatedValuesStrategyMethod,
                                 Expression.Call(
                                     _queryCompilationContext.QueryMethodProvider.QueryMethod,
                                     EntityQueryModelVisitor.QueryContextParameter,
                                     Expression.Constant(
                                         new CommandBuilder(
                                             () => _queryCompilationContext.CreateSqlQueryGenerator(targetSelectExpression),
                                             _queryCompilationContext.ValueBufferFactoryFactory))),
                                 materializer)));
                }
            }
        }
Example #36
0
        public virtual Expression GetDeleteExpression(IEntityMapping mapping, Expression instance, LambdaExpression deleteCheck)
        {
            TableExpression table = new TableExpression(new TableAlias(), mapping);
            Expression where = null;

            if (instance != null)
                where = this.GetIdentityCheck(table, mapping, instance);

            if (deleteCheck != null)
            {
                Expression row = this.GetEntityExpression(table, mapping);
                Expression pred = DbExpressionReplacer.Replace(deleteCheck.Body, deleteCheck.Parameters[0], row);
                where = (where != null) ? where.And(pred) : pred;
            }

            bool supportsVersionCheck = false;
            if (mapping.Version != null && instance != null)
            {

                //var versionValue = GetVersionValue(entity, instance);
                //var versionCheck = GetMemberExpression(table, entity, entity.Version).Equal(Expression.Constant(versionValue));
                //where = (where != null) ? where.And(versionCheck) : versionCheck;

                var version = mapping.Version;
                var versionValue = GetVersionValue(mapping, instance);
                var versionExp = Expression.Constant(versionValue, version.MemberType);
                var memberExpression = GetMemberExpression(table, mapping, mapping.Version);
                if (version.MemberType.IsNullable())
                {

                    var versionCheck = versionValue == null ? (Expression)memberExpression.Equal(Expression.Constant(null, version.MemberType))
                        : memberExpression.Equal(versionExp);
                    where = (where != null) ? where.And(versionCheck) : versionCheck;
                }
                else
                {
                    var versionCheck = memberExpression.Equal(versionExp);
                    where = (where != null) ? where.And(versionCheck) : versionCheck;
                }

                supportsVersionCheck = true;
            }

            object o = null;
            var c = instance as ConstantExpression;
            if (c != null)
                o = c.Value;
            return new DeleteCommand(table, where, o, supportsVersionCheck);
        }
Example #37
0
 protected override Expression VisitTable(TableExpression table)
 {
     this.aliases.Add(table.Alias);
     return(table);
 }
Example #38
0
        public virtual Expression GetInsertExpression(IEntityMapping mapping, Expression instance, LambdaExpression selector)
        {
            var tableAlias = new TableAlias();
            var table = new TableExpression(tableAlias, mapping);
            var assignments = this.GetInsertColumnAssignments(table, instance, mapping, m => !m.IsGenerated && !m.IsVersion).ToArray();

            object o = null;
            var c = instance as ConstantExpression;
            if (c != null)
                o = c.Value;

            if (selector != null)
            {
                return new BlockCommand(
                    new InsertCommand(table, assignments, o),
                    this.GetInsertResult(mapping, instance, selector, null)
                    );
            }

            return new InsertCommand(table, assignments, o);
        }
Example #39
0
 private GroupByExpression(TableExpression tableExpression)
     : base(ExpressionType, tableExpression)
 {
     Table = tableExpression;
 }
Example #40
0
        public virtual ProjectionExpression GetQueryExpression(IEntityMapping mapping)
        {
            Expression projector;
            TableAlias selectAlias;
            ProjectedColumns pc;
            ProjectionExpression proj;

            var tableAlias = new TableAlias();
            selectAlias = new TableAlias();
            var table = new TableExpression(tableAlias, mapping);

            projector = this.GetEntityExpression(table, mapping);
            pc = ColumnProjector.ProjectColumns(projector, null, selectAlias, tableAlias);

            proj = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, table, null),
                pc.Projector
                );

            return (ProjectionExpression)ApplyPolicy(proj, mapping.EntityType);
        }
Example #41
0
        /// <summary>
        /// Get a query expression that selects all entities from a table
        /// </summary>
        /// <param name="rowType"></param>
        /// <returns></returns>
        public virtual ProjectionExpression GetTableQuery(Type rowType)
        {
            var tableAlias = new TableAlias();
            var selectAlias = new TableAlias();
            var table = new TableExpression(tableAlias, this.GetTableName(rowType));

            Expression projector = this.GetTypeProjection(table, rowType);
            var pc = ColumnProjector.ProjectColumns(this.Language.CanBeColumn, projector, null, selectAlias, tableAlias);

            return new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, table, null),
                pc.Projector
                );
        }
Example #42
0
        public virtual Expression GetUpdateExpression(IEntityMapping mapping, Expression instance, LambdaExpression updateCheck, LambdaExpression selector, Expression @else)
        {
            var tableAlias = new TableAlias();
            var table = new TableExpression(tableAlias, mapping);

            var where = this.GetIdentityCheck(table, mapping, instance);
            if (updateCheck != null)
            {
                Expression typeProjector = this.GetEntityExpression(table, mapping);
                Expression pred = DbExpressionReplacer.Replace(updateCheck.Body, updateCheck.Parameters[0], typeProjector);
                where = where != null ? where.And(pred) : pred;
            }

            var assignments = this.GetColumnAssignments(table, instance, mapping, m => m.IsUpdatable && !m.IsVersion);

            var version = mapping.Version;
            bool supportsVersionCheck = false;

            if (version != null)
            {
                var versionValue = GetVersionValue(mapping, instance);
                var versionExp = Expression.Constant(versionValue, version.MemberType);
                var memberExpression = GetMemberExpression(table, mapping, mapping.Version);
                var versionCheck = memberExpression.Equal(versionExp);
                where = (where != null) ? where.And(versionCheck) : versionCheck;

                if (version.MemberType.IsNullable())
                {
                    var versionAssignment = new ColumnAssignment(
                           memberExpression as ColumnExpression,
                           versionValue == null ?
                                                (Expression)Expression.Constant(1, version.MemberType)
                                                : Expression.Add(memberExpression, Expression.Constant(1, version.MemberType))
                           );
                    assignments.Add(versionAssignment);
                    supportsVersionCheck = true;
                }
                else
                {
                    var versionAssignment = new ColumnAssignment(
                         memberExpression as ColumnExpression,
                          Expression.Add(memberExpression, Expression.Constant(1, version.MemberType))
                         );
                    assignments.Add(versionAssignment);
                    supportsVersionCheck = true;
                }
            }

            object o = null;
            var c = instance as ConstantExpression;
            if (c != null)
                o = c.Value;
            Expression update = new UpdateCommand(table, where, o, supportsVersionCheck, assignments);

            if (selector != null)
            {
                return new BlockCommand(
                    update,
                    new IFCommand(
                        this.GetRowsAffectedExpression(update).GreaterThan(Expression.Constant(0)),
                        this.GetUpdateResult(mapping, instance, selector),
                        @else
                        )
                    );
            }
            else if (@else != null)
            {
                return new BlockCommand(
                    update,
                    new IFCommand(
                        this.GetRowsAffectedExpression(update).LessThanOrEqual(Expression.Constant(0)),
                        @else,
                        null
                        )
                    );
            }
            else
            {
                return update;
            }
        }
Example #43
0
        public override Expression GetInsertExpression(MappingEntity entity, Expression instance, LambdaExpression selector)
        {
            var tableAlias = new TableAlias();
            var table = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));
            var assignments = this.GetColumnAssignments(table, instance, entity, (e, m) => !this.mapping.IsGenerated(e, m));

            if (selector != null)
            {
                return new BlockCommand(
                    new InsertCommand(table, assignments),
                    this.GetInsertResult(entity, instance, selector, null)
                    );
            }

            return new InsertCommand(table, assignments);
        }
Example #44
0
 protected abstract Expression VisitTable([NotNull] TableExpression tableExpression);
Example #45
0
        public override Expression GetUpdateExpression(MappingEntity entity, Expression instance, LambdaExpression updateCheck, LambdaExpression selector, Expression @else)
        {
            var tableAlias = new TableAlias();
            var table = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));

            var where = this.GetIdentityCheck(table, entity, instance);
            if (updateCheck != null)
            {
                Expression typeProjector = this.GetEntityExpression(table, entity);
                Expression pred = DbExpressionReplacer.Replace(updateCheck.Body, updateCheck.Parameters[0], typeProjector);
                where = where.And(pred);
            }

            var assignments = this.GetColumnAssignments(table, instance, entity, (e, m) => this.mapping.IsUpdatable(e, m));

            Expression update = new UpdateCommand(table, where, assignments);

            if (selector != null)
            {
                return new BlockCommand(
                    update,
                    new IFCommand(
                        this.translator.Linguist.Language.GetRowsAffectedExpression(update).GreaterThan(Expression.Constant(0)),
                        this.GetUpdateResult(entity, instance, selector),
                        @else
                        )
                    );
            }
            else if (@else != null)
            {
                return new BlockCommand(
                    update,
                    new IFCommand(
                        this.translator.Linguist.Language.GetRowsAffectedExpression(update).LessThanOrEqual(Expression.Constant(0)),
                        @else,
                        null
                        )
                    );
            }
            else
            {
                return update;
            }
        }
Example #46
0
        protected override Expression VisitTable(TableExpression tableExpression)
        {
            Check.NotNull(tableExpression, nameof(tableExpression));

            return(tableExpression);
        }
 protected virtual Expression VisitTable(TableExpression table)
 {
     return table;
 }
Example #48
0
        /// <summary>
        /// Visits the table.
        /// </summary>
        /// <param name="tableExpression">The table expression.</param>
        /// <returns>
        /// Expression
        /// </returns>
        public virtual Expression VisitTable(TableExpression tableExpression)
        {
            _sqlBuilder.AppendFormat(" {0} {1}", TableExpression.FromStatement, tableExpression.TablePart);

            return(tableExpression);
        }
 private static IEnumerable<ColumnExpression> KeysTable(TableExpression table)
 {
     yield return new ColumnExpression(typeof(int), table.Alias, SqlBuilder.PrimaryKeyName) ; 
 }
Example #50
0
        public object VisitTable(TableExpression tableExpression, SearchOptions context)
        {
            switch (tableExpression.Kind)
            {
            case TableExpressionKind.Normal:

                if (tableExpression.ChainLevel == 0)
                {
                    StringBuilder.Append("SELECT ").Append(V1.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid1")
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table);
                }
                else
                {
                    StringBuilder.Append("SELECT Sid1, ").Append(V1.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid2")
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table)
                    .Append("INNER JOIN ").AppendLine(TableExpressionName(FindRestrictingPredecessorTableExpressionIndex()));

                    using (var delimited = StringBuilder.BeginDelimitedOnClause())
                    {
                        delimited.BeginDelimitedElement().Append(V1.Resource.ResourceSurrogateId, null).Append(" = ").Append("Sid2");
                    }
                }

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    AppendHistoryClause(delimited);

                    if (tableExpression.ChainLevel == 0)
                    {
                        // if chainLevel > 0, the intersection is already handled in the JOIN
                        AppendIntersectionWithPredecessor(delimited, tableExpression);
                    }

                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                    }

                    if (tableExpression.NormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.NormalizedPredicate.AcceptVisitor(tableExpression.SearchParameterQueryGenerator, GetContext());
                    }
                }

                break;

            case TableExpressionKind.Concatenation:
                StringBuilder.Append("SELECT * FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1));
                StringBuilder.AppendLine("UNION ALL");

                goto case TableExpressionKind.Normal;

            case TableExpressionKind.All:
                StringBuilder.Append("SELECT ").Append(V1.Resource.ResourceSurrogateId, null).AppendLine(" AS Sid1")
                .Append("FROM ").AppendLine(V1.Resource);

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    AppendHistoryClause(delimited);
                    AppendDeletedClause(delimited);
                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                    }
                }

                break;

            case TableExpressionKind.NotExists:
                StringBuilder.Append("SELECT Sid1 FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1));
                StringBuilder.AppendLine("WHERE Sid1 NOT IN").AppendLine("(");

                using (StringBuilder.Indent())
                {
                    StringBuilder.Append("SELECT ").AppendLine(V1.Resource.ResourceSurrogateId, null)
                    .Append("FROM ").AppendLine(tableExpression.SearchParameterQueryGenerator.Table);
                    using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                    {
                        AppendHistoryClause(delimited);

                        if (tableExpression.DenormalizedPredicate != null)
                        {
                            delimited.BeginDelimitedElement();
                            tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext());
                        }

                        delimited.BeginDelimitedElement();
                        tableExpression.NormalizedPredicate.AcceptVisitor(tableExpression.SearchParameterQueryGenerator, GetContext());
                    }
                }

                StringBuilder.AppendLine(")");
                break;

            case TableExpressionKind.Top:
                StringBuilder.Append("SELECT DISTINCT TOP (").Append(Parameters.AddParameter(context.MaxItemCount + 1)).AppendLine(") Sid1 ")
                .Append("FROM ").AppendLine(TableExpressionName(_tableExpressionCounter - 1))
                .AppendLine("ORDER BY Sid1 ASC");

                break;

            case TableExpressionKind.Chain:
                var chainedExpression = (ChainedExpression)tableExpression.NormalizedPredicate;

                string referenceTableAlias = "ref";
                string resourceTableAlias  = "r";

                StringBuilder.Append("SELECT ");
                if (tableExpression.ChainLevel == 1)
                {
                    StringBuilder.Append(V1.ReferenceSearchParam.ResourceSurrogateId, referenceTableAlias).Append(" AS Sid1, ");
                }
                else
                {
                    StringBuilder.Append("Sid1, ");
                }

                StringBuilder.Append(V1.Resource.ResourceSurrogateId, resourceTableAlias).AppendLine(" AS Sid2")
                .Append("FROM ").Append(V1.ReferenceSearchParam).Append(' ').AppendLine(referenceTableAlias)
                .Append("INNER JOIN ").Append(V1.Resource).Append(' ').AppendLine(resourceTableAlias);

                using (var delimited = StringBuilder.BeginDelimitedOnClause())
                {
                    delimited.BeginDelimitedElement().Append(V1.ReferenceSearchParam.ReferenceResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(V1.Resource.ResourceTypeId, resourceTableAlias);

                    delimited.BeginDelimitedElement().Append(V1.ReferenceSearchParam.ReferenceResourceId, referenceTableAlias)
                    .Append(" = ").Append(V1.Resource.ResourceId, resourceTableAlias);
                }

                if (tableExpression.ChainLevel > 1)
                {
                    StringBuilder.Append("INNER JOIN ").AppendLine(TableExpressionName(FindRestrictingPredecessorTableExpressionIndex()));

                    using (var delimited = StringBuilder.BeginDelimitedOnClause())
                    {
                        delimited.BeginDelimitedElement().Append(V1.Resource.ResourceSurrogateId, referenceTableAlias).Append(" = ").Append("Sid2");
                    }
                }

                using (var delimited = StringBuilder.BeginDelimitedWhereClause())
                {
                    delimited.BeginDelimitedElement().Append(V1.ReferenceSearchParam.SearchParamId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(V1.ReferenceSearchParam.SearchParamId, Model.GetSearchParamId(chainedExpression.ReferenceSearchParameter.Url)));

                    AppendHistoryClause(delimited, resourceTableAlias);
                    AppendHistoryClause(delimited, referenceTableAlias);

                    delimited.BeginDelimitedElement().Append(V1.ReferenceSearchParam.ResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(V1.ReferenceSearchParam.ResourceTypeId, Model.GetResourceTypeId(chainedExpression.ResourceType)));

                    delimited.BeginDelimitedElement().Append(V1.ReferenceSearchParam.ReferenceResourceTypeId, referenceTableAlias)
                    .Append(" = ").Append(Parameters.AddParameter(V1.ReferenceSearchParam.ReferenceResourceTypeId, Model.GetResourceTypeId(chainedExpression.TargetResourceType)));

                    if (tableExpression.ChainLevel == 1)
                    {
                        // if > 1, the intersection is handled by the JOIN
                        AppendIntersectionWithPredecessor(delimited, tableExpression, referenceTableAlias);
                    }

                    if (tableExpression.DenormalizedPredicate != null)
                    {
                        delimited.BeginDelimitedElement();
                        tableExpression.DenormalizedPredicate?.AcceptVisitor(DispatchingDenormalizedSearchParameterQueryGenerator.Instance, GetContext(resourceTableAlias));
                    }
                }

                break;

            default:
                throw new ArgumentOutOfRangeException(tableExpression.Kind.ToString());
            }

            return(null);
        }
Example #51
0
        private void AppendIntersectionWithPredecessor(IndentedStringBuilder.DelimitedScope delimited, TableExpression tableExpression, string tableAlias = null)
        {
            int predecessorIndex = FindRestrictingPredecessorTableExpressionIndex();

            if (predecessorIndex >= 0)
            {
                delimited.BeginDelimitedElement();

                string columnToSelect = (tableExpression.Kind == TableExpressionKind.Chain ? tableExpression.ChainLevel - 1 : tableExpression.ChainLevel) == 0 ? "Sid1" : "Sid2";

                StringBuilder.Append(V1.Resource.ResourceSurrogateId, tableAlias).Append(" IN (SELECT ").Append(columnToSelect)
                .Append(" FROM ").Append(TableExpressionName(predecessorIndex)).Append(")");
            }
        }
Example #52
0
 protected InsertCommand UpdateInsert(InsertCommand insert, TableExpression table, IEnumerable<ColumnAssignment> assignments)
 {
     if (table != insert.Table || assignments != insert.Assignments)
     {
         return new InsertCommand(table, assignments);
     }
     return insert;
 }
Example #53
0
        public override Expression GetUpdateExpression(MappingEntity entity, Expression instance, LambdaExpression updateCheck, LambdaExpression selector, Expression @else)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count < 2)
            {
                return base.GetUpdateExpression(entity, instance, updateCheck, selector, @else);
            }

            var commands = new List<Expression>();
            foreach (var table in this.GetDependencyOrderedTables(entity))
            {
                TableExpression tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(table));
                var assignments = this.GetColumnAssignments(tex, instance, entity, (e, m) => this.mapping.GetAlias(e, m) == this.mapping.GetAlias(table) && this.mapping.IsUpdatable(e, m), null);
                var where = this.GetIdentityCheck(tex, entity, instance);
                commands.Add(new UpdateCommand(tex, where, assignments));
            }

            if (selector != null)
            {
                commands.Add(
                    new IFCommand(
                        this.Translator.Linguist.Language.GetRowsAffectedExpression(commands[commands.Count-1]).GreaterThan(Expression.Constant(0)),
                        this.GetUpdateResult(entity, instance, selector),
                        @else
                        )
                    );
            }
            else if (@else != null)
            {
                commands.Add(
                    new IFCommand(
                        this.Translator.Linguist.Language.GetRowsAffectedExpression(commands[commands.Count-1]).LessThanOrEqual(Expression.Constant(0)),
                        @else,
                        null
                        )
                    );
            }

            Expression block = new BlockCommand(commands);

            if (updateCheck != null)
            {
                var test = this.GetEntityStateTest(entity, instance, updateCheck);
                return new IFCommand(test, block, null);
            }

            return block;
        }
Example #54
0
 protected UpdateCommand UpdateUpdate(UpdateCommand update, TableExpression table, Expression where, IEnumerable<ColumnAssignment> assignments)
 {
     if (table != update.Table || where != update.Where || assignments != update.Assignments)
     {
         return new UpdateCommand(table, where, assignments);
     }
     return update;
 }
Example #55
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);
            }
        }
Example #56
0
 protected DeleteCommand UpdateDelete(DeleteCommand delete, TableExpression table, Expression where)
 {
     if (table != delete.Table || where != delete.Where)
     {
         return new DeleteCommand(table, where);
     }
     return delete;
 }
Example #57
0
        public override Expression GetInsertExpression(MappingEntity entity, Expression instance, LambdaExpression selector)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count < 2)
            {
                return base.GetInsertExpression(entity, instance, selector);
            }

            var commands = new List<Expression>();

            var map = this.GetDependentGeneratedColumns(entity);
            var vexMap = new Dictionary<MemberInfo, Expression>();

            foreach (var table in this.GetDependencyOrderedTables(entity))
            {
                var tableAlias = new TableAlias();
                var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(table));
                var assignments = this.GetColumnAssignments(tex, instance, entity,
                    (e, m) => this.mapping.GetAlias(e, m) == this.mapping.GetAlias(table) && !this.mapping.IsGenerated(e, m),
                    vexMap
                    );
                var totalAssignments = assignments.Concat(
                    this.GetRelatedColumnAssignments(tex, entity, table, vexMap)
                    );
                commands.Add(new InsertCommand(tex, totalAssignments));

                List<MemberInfo> members;
                if (map.TryGetValue(this.mapping.GetAlias(table), out members))
                {
                    var d = this.GetDependentGeneratedVariableDeclaration(entity, table, members, instance, vexMap);
                    commands.Add(d);
                }
            }

            if (selector != null)
            {
                commands.Add(this.GetInsertResult(entity, instance, selector, vexMap));
            }

            return new BlockCommand(commands);
        }
Example #58
0
        /// <summary>
        /// 返回插入具体实体时的 <see cref="ColumnAssignment"/> 集合。
        /// </summary>
        /// <param name="syntax"></param>
        /// <param name="table"></param>
        /// <param name="entity">具体的实体。</param>
        /// <returns></returns>
        private static IEnumerable <ColumnAssignment> GetInsertArguments(ISyntaxProvider syntax, TableExpression table, IEntity entity)
        {
            var properties = GetModifiedProperties(entity);

            var assignments = properties
                              .Select(m => new ColumnAssignment(
                                          (ColumnExpression)GetMemberExpression(table, m),
                                          Expression.Constant(GetConvertableValue(entity, m))
                                          )).ToList();

            assignments.AddRange(GetAssignmentsForPrimaryKeys(syntax, table, null, entity));

            return(assignments);
        }
 protected override Expression VisitTable(TableExpression table)
 {
     this.aliases.Add(table.Alias);
     return table;
 }
Example #60
0
        private NewArrayExpression CreateRelatedEntitiesLoaders <TRelatedEntitiesLoader>(
            IQuerySource querySource, IEnumerable <INavigation> navigationPath)
        {
            var queryContextParameter = Expression.Parameter(typeof(QueryContext));

            var relatedEntitiesLoaders = new List <Expression <Func <QueryContext, TRelatedEntitiesLoader> > >();

            var selectExpression
                = _queryCompilationContext.FindSelectExpression(querySource);

            var compositePredicateExpressionVisitor
                = _compositePredicateExpressionVisitorFactory.Create();

            var targetTableExpression
                = selectExpression.GetTableForQuerySource(querySource);

            var canProduceInnerJoin = true;
            var navigationCount     = 0;

            foreach (var navigation in navigationPath)
            {
                var queryIndex = _queryIndexes[navigationCount];
                navigationCount++;

                var targetEntityType = navigation.GetTargetType();
                var targetTableName  = _relationalAnnotationProvider.For(targetEntityType).TableName;
                var targetTableAlias
                    = _queryCompilationContext
                      .CreateUniqueTableAlias(targetTableName[0].ToString().ToLowerInvariant());

                if (!navigation.IsCollection())
                {
                    var joinedTableExpression
                        = new TableExpression(
                              targetTableName,
                              _relationalAnnotationProvider.For(targetEntityType).Schema,
                              targetTableAlias,
                              querySource);

                    var valueBufferOffset = selectExpression.Projection.Count;

                    canProduceInnerJoin
                        = canProduceInnerJoin &&
                          navigation.ForeignKey.IsRequired &&
                          navigation.IsDependentToPrincipal();

                    var joinExpression
                        = canProduceInnerJoin
                            ? selectExpression.AddInnerJoin(joinedTableExpression)
                            : selectExpression.AddLeftOuterJoin(joinedTableExpression);

                    var oldPredicate = selectExpression.Predicate;

                    Dictionary <Type, int []> _;
                    var materializer
                        = _materializerFactory
                          .CreateMaterializer(
                              targetEntityType,
                              selectExpression,
                              (p, se) => se.AddToProjection(
                                  new AliasExpression(
                                      new ColumnExpression(
                                          _relationalAnnotationProvider.For(p).ColumnName,
                                          p,
                                          joinedTableExpression))) - valueBufferOffset,
                              /*querySource:*/ null,
                              out _);

                    if (selectExpression.Predicate != oldPredicate)
                    {
                        compositePredicateExpressionVisitor.Visit(selectExpression);

                        var newJoinExpression = AdjustJoinExpression(selectExpression, joinExpression);

                        selectExpression.Predicate = oldPredicate;
                        selectExpression.RemoveTable(joinExpression);
                        selectExpression.AddTable(newJoinExpression);
                        joinExpression = newJoinExpression;
                    }

                    joinExpression.Predicate
                        = BuildJoinEqualityExpression(
                              navigation,
                              navigation.IsDependentToPrincipal() ? targetTableExpression : joinExpression,
                              navigation.IsDependentToPrincipal() ? joinExpression : targetTableExpression,
                              querySource);

                    targetTableExpression = joinedTableExpression;

                    relatedEntitiesLoaders.Add(
                        Expression.Lambda <Func <QueryContext, TRelatedEntitiesLoader> >(
                            Expression.Call(
                                _queryCompilationContext.QueryMethodProvider
                                .CreateReferenceRelatedEntitiesLoaderMethod,
                                Expression.Constant(valueBufferOffset),
                                Expression.Constant(queryIndex),
                                materializer
                                ),
                            queryContextParameter));
                }
                else
                {
                    var principalTable
                        = selectExpression.Tables.Count == 1 &&
                          selectExpression.Tables
                          .OfType <SelectExpression>()
                          .Any(s => s.Tables.Any(t => t.QuerySource == querySource))
                          // true when select is wrapped e.g. when RowNumber paging is enabled
                            ? selectExpression.Tables[0]
                            : selectExpression.Tables.Last(t => t.QuerySource == querySource);

                    var canGenerateExists
                        = selectExpression.Offset == null &&
                          selectExpression.Limit == null &&
                          !IsOrderingOnNonPrincipalKeyProperties(
                              selectExpression.OrderBy,
                              navigation.ForeignKey.PrincipalKey.Properties);

                    foreach (var property in navigation.ForeignKey.PrincipalKey.Properties)
                    {
                        selectExpression
                        .AddToOrderBy(
                            _relationalAnnotationProvider.For(property).ColumnName,
                            property,
                            principalTable,
                            OrderingDirection.Asc);
                    }

                    var targetSelectExpression = _selectExpressionFactory.Create(_queryCompilationContext);

                    targetTableExpression
                        = new TableExpression(
                              targetTableName,
                              _relationalAnnotationProvider.For(targetEntityType).Schema,
                              targetTableAlias,
                              querySource);

                    targetSelectExpression.AddTable(targetTableExpression);

                    Dictionary <Type, int[]> _;
                    var materializer
                        = _materializerFactory
                          .CreateMaterializer(
                              targetEntityType,
                              targetSelectExpression,
                              (p, se) => se.AddToProjection(
                                  _relationalAnnotationProvider.For(p).ColumnName,
                                  p,
                                  querySource),
                              /*querySource:*/ null,
                              out _);

                    if (canGenerateExists)
                    {
                        var subqueryExpression = selectExpression.Clone();
                        subqueryExpression.ClearProjection();
                        subqueryExpression.ClearOrderBy();
                        subqueryExpression.IsProjectStar = false;

                        var subqueryTable
                            = subqueryExpression.Tables.Count == 1 &&
                              subqueryExpression.Tables
                              .OfType <SelectExpression>()
                              .Any(s => s.Tables.Any(t => t.QuerySource == querySource))
                              // true when select is wrapped e.g. when RowNumber paging is enabled
                                ? subqueryExpression.Tables[0]
                                : subqueryExpression.Tables.Last(t => t.QuerySource == querySource);

                        var existsPredicateExpression = new ExistsExpression(subqueryExpression);

                        AddToPredicate(targetSelectExpression, existsPredicateExpression);

                        AddToPredicate(
                            subqueryExpression,
                            BuildJoinEqualityExpression(navigation, targetTableExpression, subqueryTable, querySource));

                        compositePredicateExpressionVisitor.Visit(subqueryExpression);

                        var pkPropertiesToFkPropertiesMap = navigation.ForeignKey.PrincipalKey.Properties
                                                            .Zip(navigation.ForeignKey.Properties, (k, v) => new { PkProperty = k, FkProperty = v })
                                                            .ToDictionary(x => x.PkProperty, x => x.FkProperty);

                        foreach (var ordering in selectExpression.OrderBy)
                        {
                            // ReSharper disable once PossibleNullReferenceException
                            var principalKeyProperty
                                = ((ordering.Expression as AliasExpression)?.Expression as ColumnExpression).Property;

                            var referencedForeignKeyProperty = pkPropertiesToFkPropertiesMap[principalKeyProperty];

                            targetSelectExpression
                            .AddToOrderBy(
                                _relationalAnnotationProvider.For(referencedForeignKeyProperty).ColumnName,
                                referencedForeignKeyProperty,
                                targetTableExpression,
                                ordering.OrderingDirection);
                        }
                    }
                    else
                    {
                        var innerJoinSelectExpression
                            = selectExpression.Clone(
                                  selectExpression.OrderBy
                                  .Select(o => o.Expression)
                                  .Last(o => o.IsAliasWithColumnExpression())
                                  .TryGetColumnExpression().TableAlias);

                        innerJoinSelectExpression.ClearProjection();

                        var innerJoinExpression = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression);

                        LiftOrderBy(innerJoinSelectExpression, targetSelectExpression, innerJoinExpression);

                        innerJoinSelectExpression.IsDistinct = true;

                        innerJoinExpression.Predicate
                            = BuildJoinEqualityExpression(
                                  navigation,
                                  targetTableExpression,
                                  innerJoinExpression,
                                  querySource);
                    }

                    compositePredicateExpressionVisitor.Visit(targetSelectExpression);

                    selectExpression = targetSelectExpression;

                    relatedEntitiesLoaders.Add(
                        Expression.Lambda <Func <QueryContext, TRelatedEntitiesLoader> >(
                            Expression.Call(
                                _queryCompilationContext.QueryMethodProvider
                                .CreateCollectionRelatedEntitiesLoaderMethod,
                                queryContextParameter,
                                Expression.Constant(
                                    _shaperCommandContextFactory.Create(() =>
                                                                        SelectExpressionDependencies.QuerySqlGeneratorFactory.CreateDefault(targetSelectExpression))),
                                Expression.Constant(queryIndex),
                                materializer
                                ),
                            queryContextParameter));
                }
            }

            return(Expression.NewArrayInit(
                       typeof(Func <QueryContext, TRelatedEntitiesLoader>),
                       relatedEntitiesLoaders));
        }