protected override Expression VisitCreateTable(SqlCreateTableExpression createTableExpression)
        {
            var autoIncrementColumn = createTableExpression
                                      .ColumnDefinitionExpressions
                                      .SingleOrDefault(c => c.ConstraintExpressions.Any(d => (d.ConstraintType & ConstraintType.AutoIncrement) != 0));

            if (autoIncrementColumn != null)
            {
                var primaryKeyConstraint = createTableExpression
                                           .TableConstraints
                                           .SingleOrDefault(c => (c.ConstraintType & ConstraintType.PrimaryKey) != 0);

                if (primaryKeyConstraint != null)
                {
                    if (!primaryKeyConstraint.ColumnNames.Contains(autoIncrementColumn.ColumnName))
                    {
                        var newPrimaryKeyConstraint = new SqlConstraintExpression(ConstraintType.PrimaryKey, /* TODO: name */ null, new [] { autoIncrementColumn.ColumnName }.ToReadOnlyCollection());
                        var newUniqueConstraint     = new SqlConstraintExpression(ConstraintType.Unique, /* TODO: name */ null, primaryKeyConstraint.ColumnNames.Concat(autoIncrementColumn.ColumnName).ToReadOnlyCollection());

                        return(createTableExpression.ChangeConstraints(createTableExpression.TableConstraints.Where(c => c != primaryKeyConstraint).Concat(newPrimaryKeyConstraint).Concat(newUniqueConstraint).ToReadOnlyCollection()));
                    }
                }
                else
                {
                    var newPrimaryKeyConstraint = new SqlConstraintExpression(ConstraintType.PrimaryKey, /* TODO: name */ null, new[] { autoIncrementColumn.ColumnName }.ToReadOnlyCollection());

                    return(createTableExpression.ChangeConstraints(new [] { newPrimaryKeyConstraint }.ToReadOnlyCollection()));
                }
            }

            return(base.VisitCreateTable(createTableExpression));
        }
        protected override Expression VisitConstraint(SqlConstraintExpression expression)
        {
            base.VisitConstraint(expression);

            if (!expression.AutoIncrement)
            {
                return(expression);
            }

            var constraintOptions = expression.ConstraintOptions;

            if (constraintOptions != null && constraintOptions.Length == 2 && (constraintOptions[0] as long?) > 0)
            {
                if (constraintOptions[1] as long? == 0)
                {
                    constraintOptions[1] = 1L;
                }

                Write("(");
                WriteDeliminatedListOfItems(constraintOptions, Write);
                Write(")");
            }

            return(expression);
        }
        protected override Expression VisitConstraint(SqlConstraintExpression expression)
        {
            if (this.currentIsPrimaryKey && (expression.ConstraintType & ConstraintType.AutoIncrement) != 0)
            {
                return(null);
            }

            return(base.VisitConstraint(expression));
        }
        protected override Expression VisitConstraint(SqlConstraintExpression expression)
        {
            if (expression.ConstraintType == ConstraintType.DefaultValue && expression.ConstraintName != null)
            {
                return(expression.ChangeConstraintName(null));
            }

            return(base.VisitConstraint(expression));
        }
        protected override Expression VisitConstraint(SqlConstraintExpression expression)
        {
            if (expression.PrimaryKey && this.makeUnclustered)
            {
                return(expression.ChangeKeyOptions((expression.KeyOptions ?? new object[0]).Concat("NONCLUSTERED").ToArray()));
            }

            return(base.VisitConstraint(expression));
        }
        private IEnumerable <SqlColumnDefinitionExpression> BuildForeignKeyColumnDefinitions(PropertyDescriptor referencingProperty, ColumnInfo[] columnInfos)
        {
            var relatedPropertyTypeDescriptor = this.model.GetTypeDescriptor(referencingProperty.PropertyType);
            var referencedTableName           = relatedPropertyTypeDescriptor.PersistedName;

            var valueRequired = (referencingProperty.ValueRequiredAttribute != null && referencingProperty.ValueRequiredAttribute.Required) ||
                                referencingProperty.IsPrimaryKey;
            var supportsInlineForeignKeys = this.sqlDialect.SupportsCapability(SqlCapability.InlineForeignKeys);

            var foreignObjectConstraintAttribute = referencingProperty.ForeignObjectConstraintAttribute;

            foreach (var foreignKeyColumn in columnInfos)
            {
                var retval = this.BuildColumnDefinition(foreignKeyColumn);

                if (columnInfos.Length == 1 && supportsInlineForeignKeys && !(referencingProperty.ForeignObjectConstraintAttribute?.Disabled ?? false))
                {
                    var names          = new[] { foreignKeyColumn.DefinitionProperty.PersistedName };
                    var newConstraints = new List <SqlConstraintExpression>(retval.ConstraintExpressions);

                    var referencesColumnExpression = new SqlReferencesExpression
                                                     (
                        new SqlTableExpression(referencedTableName),
                        SqlColumnReferenceDeferrability.InitiallyDeferred,
                        names, this.FixAction(foreignObjectConstraintAttribute != null && this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnDeleteAction) != null ? this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnDeleteAction).Value : (valueRequired ? SqlColumnReferenceAction.Restrict : SqlColumnReferenceAction.SetNull)), this.FixAction((foreignObjectConstraintAttribute != null && this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnDeleteAction) != null) ? this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnUpdateAction).Value : SqlColumnReferenceAction.NoAction)
                                                     );

                    newConstraints.Add(new SqlConstraintExpression(referencesColumnExpression, this.formatterManager.GetForeignKeyConstraintName(referencingProperty)));

                    retval = new SqlColumnDefinitionExpression(retval.ColumnName, retval.ColumnType, newConstraints);
                }

                yield return(retval);
            }

            if ((columnInfos.Length > 1 || !supportsInlineForeignKeys) && !(referencingProperty.ForeignObjectConstraintAttribute?.Disabled ?? false))
            {
                var currentTableColumnNames    = columnInfos.Select(c => c.ColumnName).ToList();
                var referencedTableColumnNames = columnInfos.Select(c => c.GetTailColumnName());

                var referencesExpression = new SqlReferencesExpression
                                           (
                    new SqlTableExpression(referencedTableName),
                    SqlColumnReferenceDeferrability.InitiallyDeferred,
                    referencedTableColumnNames, this.FixAction((foreignObjectConstraintAttribute != null && this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnDeleteAction) != null) ? this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnDeleteAction).Value : (valueRequired ? SqlColumnReferenceAction.Restrict : SqlColumnReferenceAction.SetNull)), this.FixAction((foreignObjectConstraintAttribute != null && this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnDeleteAction) != null) ? this.ToSqlColumnReferenceAction(foreignObjectConstraintAttribute.OnUpdateAction).Value : SqlColumnReferenceAction.NoAction)
                                           );

                var foreignKeyConstraint = new SqlConstraintExpression(referencesExpression, this.formatterManager.GetForeignKeyConstraintName(referencingProperty), currentTableColumnNames);

                this.currentTableConstraints.Add(foreignKeyConstraint);
            }
        }
        protected virtual Expression VisitConstraint(SqlConstraintExpression expression)
        {
            var referencesExpression = (SqlReferencesExpression)Visit(expression.ReferencesExpression);

            if (referencesExpression != expression.ReferencesExpression)
            {
                return(expression.ChangeReferences(referencesExpression));
            }
            else
            {
                return(expression);
            }
        }
Exemple #8
0
        protected override Expression VisitConstraint(SqlConstraintExpression expression)
        {
            if (expression.ReferencesExpression == null)
            {
                return(expression);
            }

            var action             = new SqlConstraintActionExpression(SqlConstraintActionType.Add, expression);
            var amendmentEpression = new SqlAlterTableExpression(this.currentTable.Table, action);

            this.amendments.Add(amendmentEpression);

            return(null);
        }
        protected override Expression VisitConstraint(SqlConstraintExpression constraintExpression)
        {
            string primaryKeyName;

            if (constraintExpression.ReferencesExpression == null || constraintExpression.ColumnNames == null)
            {
                return(base.VisitConstraint(constraintExpression));
            }

            if (this.primaryKeyNameByTablesWithReducedPrimaryKeyName.TryGetValue(constraintExpression.ReferencesExpression.ReferencedTable.Name, out primaryKeyName))
            {
                var index = constraintExpression.ReferencesExpression.ReferencedColumnNames.IndexOf(primaryKeyName);

                var newColumnNames           = constraintExpression.ColumnNames.Where((c, i) => i == index);
                var newReferencedColumnNames = constraintExpression.ReferencesExpression.ReferencedColumnNames.Where((c, i) => i == index);

                return(constraintExpression
                       .ChangeColumnNames(newColumnNames.ToReadOnlyCollection())
                       .ChangeReferences(constraintExpression.ReferencesExpression.ChangeReferencedColumnNames(newReferencedColumnNames)));
            }

            return(base.VisitConstraint(constraintExpression));
        }
        protected override Expression VisitCreateTable(SqlCreateTableExpression createTableExpression)
        {
            var primaryKeyConstraint = createTableExpression
                                       .TableConstraints
                                       .SingleOrDefault(c => c.PrimaryKey);

            if (primaryKeyConstraint != null)
            {
                var autoIncrementColumns = createTableExpression
                                           .ColumnDefinitionExpressions
                                           .SelectMany(c => c.ConstraintExpressions.Select(d => new { Constraint = d, ColumnDefinition = c }))
                                           .Where(c => c.Constraint.AutoIncrement)
                                           .ToList();

                if (autoIncrementColumns.Count > 1)
                {
                    throw new UnsupportedDataAccessModelDefinitionException();
                }

                if (autoIncrementColumns.Count > 0)
                {
                    var autoIncrementColumn = autoIncrementColumns.Single();

                    var newTableConstraints = createTableExpression
                                              .TableConstraints
                                              .Where(c => c != primaryKeyConstraint);

                    if (primaryKeyConstraint.ColumnNames.Count > 1 ||
                        autoIncrementColumn.ColumnDefinition.ConstraintExpressions.All(c => !c.PrimaryKey))
                    {
                        var uniqueConstraint = new SqlConstraintExpression(ConstraintType.Unique, /* TODO: name */ null, primaryKeyConstraint.ColumnNames);

                        newTableConstraints = newTableConstraints.Concat(uniqueConstraint);
                    }

                    this.primaryKeyNameByTablesWithReducedPrimaryKeyName[createTableExpression.Table.Name] = autoIncrementColumn.ColumnDefinition.ColumnName;

                    this.columnsToMakeNotNull.Clear();

                    primaryKeyConstraint
                    .ColumnNames
                    .Where(c => c != autoIncrementColumn.ColumnDefinition.ColumnName)
                    .ForEach(c => this.columnsToMakeNotNull.Add(c));

                    createTableExpression = new SqlCreateTableExpression
                                            (
                        createTableExpression.Table,
                        createTableExpression.IfNotExist,
                        this.VisitExpressionList(createTableExpression.ColumnDefinitionExpressions),
                        newTableConstraints.ToReadOnlyCollection(),
                        null
                                            );

                    this.columnsToMakeNotNull.Clear();

                    return(createTableExpression);
                }
            }

            return(base.VisitCreateTable(createTableExpression));
        }
        private Expression BuildCreateTableExpression(TypeDescriptor typeDescriptor)
        {
            var columnExpressions = new List <SqlColumnDefinitionExpression>();

            this.currentTableConstraints = new List <SqlConstraintExpression>();

            var columnInfos = QueryBinder.GetColumnInfos
                              (
                this.model.TypeDescriptorProvider,
                typeDescriptor.PersistedProperties,
                (c, d) => c.IsPrimaryKey && !c.PropertyType.IsDataAccessObjectType(),
                (c, d) => c.IsPrimaryKey
                              );

            foreach (var columnInfo in columnInfos)
            {
                columnExpressions.Add(this.BuildColumnDefinition(columnInfo));
            }

            columnInfos = QueryBinder.GetColumnInfos
                          (
                this.model.TypeDescriptorProvider,
                typeDescriptor.PersistedPropertiesWithoutBackreferences.Where(c => !c.PropertyType.IsDataAccessObjectType()),
                (c, d) => d == 0 ? !c.IsPrimaryKey : c.IsPrimaryKey,
                (c, d) => d == 0 ? !c.IsPrimaryKey : c.IsPrimaryKey
                          );

            foreach (var columnInfo in columnInfos)
            {
                columnExpressions.Add(this.BuildColumnDefinition(columnInfo));
            }

            foreach (var property in typeDescriptor.PersistedPropertiesWithoutBackreferences
                     .Where(c => c.PropertyType.IsDataAccessObjectType()))
            {
                columnInfos = QueryBinder.GetColumnInfos
                              (
                    this.model.TypeDescriptorProvider,
                    new [] { property },
                    (c, d) => d == 0 || c.IsPrimaryKey,
                    (c, d) => c.IsPrimaryKey
                              );

                columnExpressions.AddRange(this.BuildForeignKeyColumnDefinitions(property, columnInfos));
            }

            columnExpressions.AddRange(this.BuildRelatedColumnDefinitions(typeDescriptor));

            var tableName = typeDescriptor.PersistedName;

            var primaryKeys = QueryBinder.GetPrimaryKeyColumnInfos(this.model.TypeDescriptorProvider, typeDescriptor);

            if (primaryKeys.Length > 0)
            {
                var columnNames = primaryKeys.Select(c => c.ColumnName);
                var compositePrimaryKeyConstraint = new SqlConstraintExpression(ConstraintType.PrimaryKey, this.formatterManager.GetPrimaryKeyConstraintName(typeDescriptor, typeDescriptor.PrimaryKeyProperties.ToArray()), columnNames.ToReadOnlyCollection());

                this.currentTableConstraints.Add(compositePrimaryKeyConstraint);
            }

            SqlOrganizationIndexExpression organizationIndex = null;

            var organizationAttributes = typeDescriptor
                                         .PersistedProperties
                                         .Where(c => c.OrganizationIndexAttribute != null)
                                         .Where(c => c.OrganizationIndexAttribute.IncludeOnly == false)
                                         .Select(c => new Tuple <OrganizationIndexAttribute, PropertyDescriptor>(c.OrganizationIndexAttribute, c))
                                         .OrderBy(c => c.Item1.CompositeOrder)
                                         .ToArray();

            if (organizationAttributes.Length > 0)
            {
                var organizationIndexName = this.formatterManager.GetIndexConstraintName(organizationAttributes.Select(c => c.Item2));

                organizationIndex = this.BuildOrganizationIndexExpression(organizationIndexName, organizationAttributes);
            }

            return(new SqlCreateTableExpression(new SqlTableExpression(tableName), false, columnExpressions, this.currentTableConstraints, organizationIndex));
        }