public void Initialize_should_initialize_ends()
        {
            var associationSetMapping = new DbAssociationSetMapping().Initialize();

            Assert.NotNull(associationSetMapping.SourceEndMapping);
            Assert.NotNull(associationSetMapping.TargetEndMapping);
        }
        public void Configure_should_split_key_constraint_when_to_table_configuration()
        {
            var database = new DbDatabaseMetadata().Initialize();
            var sourceTable = database.AddTable("Source");
            var fkColumn = sourceTable.AddColumn("Fk");
            var foreignKeyConstraint = new DbForeignKeyConstraintMetadata();
            foreignKeyConstraint.DependentColumns.Add(fkColumn);
            sourceTable.ForeignKeyConstraints.Add(foreignKeyConstraint);
            var targetTable = database.AddTable("Split");
            var associationSetMapping = new DbAssociationSetMapping().Initialize();
            associationSetMapping.Table = sourceTable;
            associationSetMapping.SourceEndMapping.PropertyMappings.Add(new DbEdmPropertyMapping { Column = fkColumn });

            var independentAssociationMappingConfiguration
                = new ForeignKeyAssociationMappingConfiguration();

            independentAssociationMappingConfiguration.ToTable("Split");

            independentAssociationMappingConfiguration.Configure(associationSetMapping, database);

            Assert.True(targetTable.Columns.Contains(fkColumn));
            Assert.True(targetTable.ForeignKeyConstraints.Contains(foreignKeyConstraint));
            Assert.False(sourceTable.Columns.Contains(fkColumn));
            Assert.False(sourceTable.ForeignKeyConstraints.Contains(foreignKeyConstraint));
            Assert.Same(targetTable, associationSetMapping.Table);
        }
        public void Can_get_and_set_configuration_annotation()
        {
            var associationSetMapping = new DbAssociationSetMapping();

            associationSetMapping.SetConfiguration(42);

            Assert.Equal(42, associationSetMapping.GetConfiguration());
        }
        public void Configure_should_throw_when_incorrect_number_of_columns_configured()
        {
            var database = new DbDatabaseMetadata().Initialize();
            var associationSetMapping = new DbAssociationSetMapping().Initialize();

            var manyToManyAssociationMappingConfiguration
                = new ManyToManyAssociationMappingConfiguration();

            manyToManyAssociationMappingConfiguration.MapLeftKey("Id1", "Id2");

            Assert.Equal(Strings.IncorrectColumnCount("Id1, Id2"), Assert.Throws<InvalidOperationException>(() => manyToManyAssociationMappingConfiguration.Configure(associationSetMapping, database)).Message);
        }
        public void Configure_should_throw_when_configured_table_not_found()
        {
            var independentAssociationMappingConfiguration
                = new ForeignKeyAssociationMappingConfiguration();

            independentAssociationMappingConfiguration.ToTable("Split");

            var associationSetMapping = new DbAssociationSetMapping().Initialize();
            var database = new DbDatabaseMetadata().Initialize();

            Assert.Equal(Strings.TableNotFound("Split"), Assert.Throws<InvalidOperationException>(() => independentAssociationMappingConfiguration.Configure(associationSetMapping, database)).Message);
        }
        public void Configure_should_rename_columns_when_right_keys_configured()
        {
            var database = new DbDatabaseMetadata().Initialize();
            var associationSetMapping = new DbAssociationSetMapping().Initialize();
            var column = new DbTableColumnMetadata();
            associationSetMapping.TargetEndMapping.PropertyMappings.Add(new DbEdmPropertyMapping { Column = column });

            var manyToManyAssociationMappingConfiguration
                = new ManyToManyAssociationMappingConfiguration();

            manyToManyAssociationMappingConfiguration.MapRightKey("NewName");

            manyToManyAssociationMappingConfiguration.Configure(associationSetMapping, database);

            Assert.Equal("NewName", column.Name);
        }
        public void Configure_should_rename_table_when_table_configured()
        {
            var database = new DbDatabaseMetadata().Initialize();
            var table = database.AddTable("OriginalName");
            var associationSetMapping = new DbAssociationSetMapping().Initialize();
            associationSetMapping.Table = table;

            var manyToManyAssociationMappingConfiguration
                = new ManyToManyAssociationMappingConfiguration();

            manyToManyAssociationMappingConfiguration.ToTable("NewName");

            manyToManyAssociationMappingConfiguration.Configure(associationSetMapping, database);

            Assert.Equal("NewName", table.GetTableName().Name);
            Assert.Same(manyToManyAssociationMappingConfiguration, table.GetConfiguration());
        }
        private void WriteAssociationSetMappingElement(DbAssociationSetMapping set)
        {
            _xmlWriter.WriteStartElement(MslConstants.Element_AssociationSetMapping);
            _xmlWriter.WriteAttributeString(MslConstants.Attribute_Name, set.AssociationSet.Name);
            _xmlWriter.WriteAttributeString(
                MslConstants.Attribute_TypeName, _entityTypeNamespace + "." + set.AssociationSet.ElementType.Name);
            _xmlWriter.WriteAttributeString(MslConstants.Attribute_StoreEntitySet, set.Table.Name);
            WriteAssociationEndMappingElement(set.SourceEndMapping);
            WriteAssociationEndMappingElement(set.TargetEndMapping);

            foreach (var conditionColumn in set.ColumnConditions)
            {
                WriteConditionElement(conditionColumn);
            }

            _xmlWriter.WriteEndElement();
        }
        internal override void Configure(DbAssociationSetMapping associationSetMapping, DbDatabaseMetadata database)
        {
            // By convention source end contains the dependent column mappings
            var propertyMappings = associationSetMapping.SourceEndMapping.PropertyMappings;

            if (_tableName != null)
            {
                var targetTable
                    = ((from t in database.Schemas.Single().Tables
                        let n = t.GetTableName()
                        where (n != null && n.Equals(_tableName))
                        select t)
                          .SingleOrDefault())
                      ?? database.Schemas.Single().Tables
                             .SingleOrDefault(
                                 t => string.Equals(t.DatabaseIdentifier, _tableName.Name, StringComparison.Ordinal));

                if (targetTable == null)
                {
                    throw Error.TableNotFound(_tableName);
                }

                var sourceTable = associationSetMapping.Table;

                if (sourceTable != targetTable)
                {
                    var foreignKeyConstraint
                        = sourceTable.ForeignKeyConstraints
                            .Single(fk => fk.DependentColumns.SequenceEqual(propertyMappings.Select(pm => pm.Column)));

                    sourceTable.ForeignKeyConstraints.Remove(foreignKeyConstraint);
                    targetTable.ForeignKeyConstraints.Add(foreignKeyConstraint);

                    foreignKeyConstraint.DependentColumns
                        .Each(
                            c =>
                                {
                                    sourceTable.Columns.Remove(c);
                                    targetTable.Columns.Add(c);
                                });

                    associationSetMapping.Table = targetTable;
                }
            }

            if ((_keyColumnNames.Count > 0)
                && (_keyColumnNames.Count != propertyMappings.Count))
            {
                throw Error.IncorrectColumnCount(string.Join(", ", _keyColumnNames));
            }

            _keyColumnNames.Each((n, i) => propertyMappings[i].Column.Name = n);
        }
        internal static DbAssociationSetMapping AddAssociationSetMapping(
            this DbDatabaseMapping databaseMapping, EdmAssociationSet associationSet)
        {
            Contract.Requires(databaseMapping != null);
            Contract.Requires(associationSet != null);

            var associationSetMapping
                = new DbAssociationSetMapping
                    {
                        AssociationSet = associationSet
                    }.Initialize();

            databaseMapping
                .EntityContainerMappings
                .Single()
                .AssociationSetMappings
                .Add(associationSetMapping);

            return associationSetMapping;
        }
        private void GenerateIndependentForeignKeyColumns(
            EdmEntityType principalEntityType,
            EdmEntityType dependentEntityType,
            DbAssociationSetMapping associationSetMapping,
            DbAssociationEndMapping associationEndMapping,
            DbTableMetadata dependentTable,
            DbForeignKeyConstraintMetadata foreignKeyConstraint,
            bool isPrimaryKeyColumn,
            EdmNavigationProperty principalNavigationProperty)
        {
            //Contract.Requires(principalEntityType != null);
            //Contract.Requires(associationEndMapping != null);
            //Contract.Requires(dependentTable != null);
            //Contract.Requires(foreignKeyConstraint != null);

            foreach (var property in principalEntityType.KeyProperties())
            {
                var foreignKeyColumn
                    = dependentTable.AddColumn(
                        ((principalNavigationProperty != null)
                             ? principalNavigationProperty.Name
                             : principalEntityType.Name)
                        + "_" + property.Name);

                MapTableColumn(property, foreignKeyColumn, false, isPrimaryKeyColumn);

                foreignKeyColumn.IsNullable = (associationEndMapping.AssociationEnd.IsOptional()
                                               ||
                                               (associationEndMapping.AssociationEnd.IsRequired()
                                                && dependentEntityType.BaseType != null));
                foreignKeyColumn.StoreGeneratedPattern = DbStoreGeneratedPattern.None;

                foreignKeyConstraint.DependentColumns.Add(foreignKeyColumn);

                associationEndMapping.PropertyMappings.Add(
                    new DbEdmPropertyMapping
                        {
                            Column = foreignKeyColumn,
                            PropertyPath = new[] { property }
                        });

                if (foreignKeyColumn.IsNullable)
                {
                    associationSetMapping.ColumnConditions.Add(
                        new DbColumnCondition
                            {
                                Column = foreignKeyColumn,
                                IsNull = false
                            });
                }
            }
        }
        internal override void Configure(DbAssociationSetMapping associationSetMapping, DbDatabaseMetadata database)
        {
            var table = associationSetMapping.Table;

            if (_tableName != null)
            {
                table.SetTableName(_tableName);
                table.SetConfiguration(this);
            }

            ConfigureColumnNames(_leftKeyColumnNames, associationSetMapping.SourceEndMapping.PropertyMappings);
            ConfigureColumnNames(_rightKeyColumnNames, associationSetMapping.TargetEndMapping.PropertyMappings);
        }
 internal override void Configure(DbAssociationSetMapping associationSetMapping, DbDatabaseMetadata database)
 {
     Contract.Requires(associationSetMapping != null);
     Contract.Requires(database != null);
 }
 internal abstract void Configure(DbAssociationSetMapping associationSetMapping, DbDatabaseMetadata database);
        private static void MoveAssociationSetMappingDependents(
            DbAssociationSetMapping associationSetMapping,
            DbAssociationEndMapping dependentMapping,
            DbTableMetadata toTable,
            bool useExistingColumns)
        {
            Contract.Requires(associationSetMapping != null);
            Contract.Requires(dependentMapping != null);
            Contract.Requires(toTable != null);

            dependentMapping.PropertyMappings.Each(
                pm =>
                    {
                        var oldColumn = pm.Column;
                        pm.Column = TableOperations.MoveColumnAndAnyConstraints(
                            associationSetMapping.Table, toTable, oldColumn, useExistingColumns);
                        associationSetMapping.ColumnConditions.Where(cc => cc.Column == oldColumn).Each(
                            cc =>
                            cc.Column = pm.Column);
                    });

            associationSetMapping.Table = toTable;
        }
        internal void Configure(DbAssociationSetMapping associationSetMapping, DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(associationSetMapping != null);
            //Contract.Requires(databaseMapping != null);

            // We may apply configuration twice from two different NavigationPropertyConfiguration objects,
            // but that should be okay since they were validated as consistent above.
            // We still apply twice because each object may have different pieces of the full configuration.
            if (AssociationMappingConfiguration != null)
            {
                // This may replace a configuration previously set, but that's okay since we validated
                // consistency when processing the configuration above.
                associationSetMapping.SetConfiguration(this);

                AssociationMappingConfiguration.Configure(associationSetMapping, databaseMapping.Database);
            }
        }
        private void GenerateIndependentForeignKeyConstraint(
            DbDatabaseMapping databaseMapping,
            EdmEntityType principalEntityType,
            EdmEntityType dependentEntityType,
            DbTableMetadata dependentTable,
            DbAssociationSetMapping associationSetMapping,
            DbAssociationEndMapping associationEndMapping,
            string name,
            EdmAssociationEnd principalEnd,
            bool isPrimaryKeyColumn = false)
        {
            //Contract.Requires(databaseMapping != null);
            //Contract.Requires(principalEntityType != null);
            //Contract.Requires(dependentTable != null);
            //Contract.Requires(associationEndMapping != null);
            //Contract.Requires(!string.IsNullOrWhiteSpace(name));

            var principalTable
                = GetEntityTypeMappingInHierarchy(databaseMapping, principalEntityType)
                    .TypeMappingFragments
                    .Single()
                    .Table;

            var foreignKeyConstraint = new DbForeignKeyConstraintMetadata
                {
                    Name = name,
                    PrincipalTable = principalTable,
                    DeleteAction = associationEndMapping.AssociationEnd.DeleteAction.HasValue
                                       ? (DbOperationAction)
                                         associationEndMapping.AssociationEnd.DeleteAction.
                                             Value
                                       : DbOperationAction.None
                };

            var principalNavigationProperty
                = databaseMapping.Model.GetEntityTypes()
                    .SelectMany(e => e.DeclaredNavigationProperties)
                    .SingleOrDefault(n => n.ResultEnd == principalEnd);

            GenerateIndependentForeignKeyColumns(
                principalEntityType,
                dependentEntityType,
                associationSetMapping,
                associationEndMapping,
                dependentTable,
                foreignKeyConstraint,
                isPrimaryKeyColumn,
                principalNavigationProperty);

            dependentTable.ForeignKeyConstraints.Add(foreignKeyConstraint);
        }