private void GenerateDiscriminators(DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(databaseMapping != null);

            foreach (var entitySetMapping in databaseMapping.GetEntitySetMappings())
            {
                if (entitySetMapping.EntityTypeMappings.Count == 1)
                {
                    continue;
                }

                var discriminatorColumn
                    = entitySetMapping
                        .EntityTypeMappings
                        .First()
                        .TypeMappingFragments
                        .Single()
                        .Table
                        .AddColumn(DiscriminatorColumnName);

                InitializeDefaultDiscriminatorColumn(discriminatorColumn);

                foreach (var entityTypeMapping in entitySetMapping.EntityTypeMappings)
                {
                    var entityTypeMappingFragment = entityTypeMapping.TypeMappingFragments.Single();

                    entityTypeMappingFragment.SetDefaultDiscriminator(discriminatorColumn);

                    entityTypeMappingFragment
                        .AddDiscriminatorCondition(discriminatorColumn, entityTypeMapping.EntityType.Name);
                }
            }
        }
        private static bool RemapsInheritedProperties(
            DbDatabaseMapping databaseMapping, DbEntityTypeMapping entityTypeMapping)
        {
            var inheritedProperties = entityTypeMapping.EntityType.Properties
                .Except(entityTypeMapping.EntityType.DeclaredProperties)
                .Except(entityTypeMapping.EntityType.GetKeyProperties());

            foreach (var property in inheritedProperties)
            {
                var fragment = GetFragmentForPropertyMapping(entityTypeMapping, property);

                if (fragment != null)
                {
                    // find if this inherited property is mapped to another table by a base type
                    var baseType = entityTypeMapping.EntityType.BaseType;
                    while (baseType != null)
                    {
                        if (databaseMapping.GetEntityTypeMappings(baseType)
                            .Select(baseTypeMapping => GetFragmentForPropertyMapping(baseTypeMapping, property))
                            .Any(
                                baseFragment => baseFragment != null
                                                && baseFragment.Table != fragment.Table))
                        {
                            return true;
                        }
                        baseType = baseType.BaseType;
                    }
                }
            }
            return false;
        }
        public void Initialize_should_add_default_entity_container_mapping()
        {
            var databaseMapping = new DbDatabaseMapping()
                .Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata());

            Assert.Equal(1, databaseMapping.EntityContainerMappings.Count);
        }
예제 #4
0
        public void Serialize(DbDatabaseMapping databaseMapping, DbProviderInfo providerInfo, XmlWriter xmlWriter)
        {
            //Contract.Requires(xmlWriter != null);
            //Contract.Requires(databaseMapping != null);
            //Contract.Requires(providerInfo != null);
            Contract.Assert(databaseMapping.Model != null);
            Contract.Assert(databaseMapping.Database != null);

            _xmlWriter = xmlWriter;
            _databaseMapping = databaseMapping;
            _version = databaseMapping.Model.Version;
            _providerInfo = providerInfo;
            _namespace = _version == DataModelVersions.Version3 ? EdmXmlNamespaceV3 : EdmXmlNamespaceV2;

            _xmlWriter.WriteStartDocument();

            using (Element("Edmx", "Version", string.Format(CultureInfo.InvariantCulture, "{0:F1}", _version)))
            {
                WriteEdmxRuntime();
                WriteEdmxDesigner();
            }

            _xmlWriter.WriteEndDocument();
            _xmlWriter.Flush();
        }
        public void Configure_should_update_table_name_when_base_type_is_null()
        {
            var entityMappingConfiguration = new EntityMappingConfiguration
                                                 {
                                                     TableName = new DatabaseName("Foo")
                                                 };
            var entityTypeMapping = new DbEntityTypeMapping
                                        {
                                            EntityType = new EdmEntityType()
                                        };
            var table = new DbTableMetadata
                            {
                                Name = "foo"
                            };
            entityTypeMapping.TypeMappingFragments.Add(
                new DbEntityTypeMappingFragment
                    {
                        Table = table
                    });

            var databaseMapping =
                new DbDatabaseMapping().Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata().Initialize());
            databaseMapping.Database.AddTable("foo");
            entityMappingConfiguration.Configure(
                databaseMapping, ProviderRegistry.Sql2008_ProviderManifest, entityTypeMapping.EntityType, ref entityTypeMapping, false, 0, 1);

            Assert.Equal("Foo", table.GetTableName().Name);
        }
        public void Apply_should_introduce_cascade_delete_on_constraints()
        {
            var databaseMapping
                = new DbDatabaseMapping()
                    .Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata().Initialize());

            var foreignKeyConstraint = new DbForeignKeyConstraintMetadata();

            Assert.Equal(DbOperationAction.None, foreignKeyConstraint.DeleteAction);

            var table = new DbTableMetadata();
            table.ForeignKeyConstraints.Add(foreignKeyConstraint);

            var associationType = new EdmAssociationType().Initialize();
            associationType.SourceEnd.EndKind = EdmAssociationEndKind.Many;
            associationType.SourceEnd.EntityType = new EdmEntityType();
            associationType.TargetEnd.EndKind = EdmAssociationEndKind.Many;
            associationType.TargetEnd.EntityType = new EdmEntityType();

            var associationSetMapping = databaseMapping.AddAssociationSetMapping(new EdmAssociationSet { ElementType = associationType });
            associationSetMapping.Table = table;

            ((IDbMappingConvention)new ManyToManyCascadeDeleteConvention()).Apply(databaseMapping);

            Assert.Equal(DbOperationAction.Cascade, foreignKeyConstraint.DeleteAction);
        }
예제 #7
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="DbModel" /> class.
        /// </summary>
        internal DbModel(DbDatabaseMapping databaseMapping, DbModelBuilder modelBuilder)
        {
            Contract.Requires(databaseMapping != null);
            Contract.Requires(modelBuilder != null);

            _databaseMapping = databaseMapping;
            _cachedModelBuilder = modelBuilder;
        }
        public void GetEntitySetMappings_should_return_mappings()
        {
            var databaseMapping = new DbDatabaseMapping()
                .Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata());

            databaseMapping.AddAssociationSetMapping(new EdmAssociationSet());

            Assert.Equal(1, databaseMapping.GetAssociationSetMappings().Count());
        }
 void IDbMappingConvention.Apply(DbDatabaseMapping databaseMapping)
 {
     databaseMapping.EntityContainerMappings
         .SelectMany(ecm => ecm.AssociationSetMappings)
         .Where(
             asm => asm.AssociationSet.ElementType.IsManyToMany()
                    && !asm.AssociationSet.ElementType.IsSelfReferencing())
         .SelectMany(asm => asm.Table.ForeignKeyConstraints)
         .Each(fk => fk.DeleteAction = DbOperationAction.Cascade);
 }
예제 #10
0
        /// <summary>
        ///     Serialize the <see cref="DbModel" /> to the XmlWriter
        /// </summary>
        /// <param name="databaseMapping"> The DbModel to serialize </param>
        /// <param name="xmlWriter"> The XmlWriter to serialize to </param>
        public virtual bool Serialize(DbDatabaseMapping databaseMapping, XmlWriter xmlWriter)
        {
            Contract.Requires(databaseMapping != null);
            Contract.Requires(xmlWriter != null);

            var schemaWriter = new DbModelMslSchemaWriter(xmlWriter, databaseMapping.Model.Version);

            schemaWriter.WriteSchema(databaseMapping);

            return true;
        }
        private static DbDatabaseMapping InitializeDatabaseMapping(EdmModel model)
        {
            //Contract.Requires(model != null);

            var databaseMapping = new DbDatabaseMapping().Initialize(
                model, new DbDatabaseMetadata().Initialize(model.Version));

            databaseMapping.EntityContainerMappings.Single().EntityContainer = model.Containers.Single();

            return databaseMapping;
        }
        public void AddAssociationSetMapping_should_add_mapping()
        {
            var databaseMapping = new DbDatabaseMapping()
                .Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata());
            var associationSet = new EdmAssociationSet();

            var associationSetMapping = databaseMapping.AddAssociationSetMapping(associationSet);

            Assert.NotNull(associationSetMapping);
            Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().AssociationSetMappings.Count());
            Assert.Same(associationSet, associationSetMapping.AssociationSet);
        }
        private void GenerateEntityTypes(EdmModel model, DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(model != null);
            //Contract.Requires(databaseMapping != null);

            foreach (var entityType in model.GetEntityTypes())
            {
                if (!entityType.IsAbstract)
                {
                    new EntityTypeMappingGenerator(_providerManifest).
                        Generate(entityType, databaseMapping);
                }
            }
        }
        /// <summary>
        ///     Builds and stores the workspace based on the given code first configuration.
        /// </summary>
        /// <param name = "databaseMapping">The code first EDM model.</param>
        public CodeFirstCachedMetadataWorkspace(DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(databaseMapping != null);

            _providerInfo = databaseMapping.Database.GetProviderInfo();

            _metadataWorkspace = databaseMapping.ToMetadataWorkspace();

            _assemblies = databaseMapping.Model.GetClrTypes().Select(t => t.Assembly).Distinct().ToList();

            Contract.Assert(
                databaseMapping.Model.Containers.Count() == 1, "Expecting Code First to create only one container.");
            _defaultContainerName = databaseMapping.Model.Containers.First().Name;
        }
 void IDbMappingConvention.Apply(DbDatabaseMapping databaseMapping)
 {
     databaseMapping.EntityContainerMappings
         .SelectMany(ecm => ecm.EntitySetMappings)
         .Each(
             esm =>
                 {
                     foreach (var etm in esm.EntityTypeMappings)
                     {
                         if (RemapsInheritedProperties(databaseMapping, etm)
                             && HasBaseWithIsTypeOf(esm, etm.EntityType))
                         {
                             throw Error.UnsupportedHybridInheritanceMapping(etm.EntityType.Name);
                         }
                     }
                 });
 }
        public void Generate(EdmAssociationType associationType, DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(associationType != null);
            //Contract.Requires(databaseMapping != null);

            if (associationType.Constraint != null)
            {
                GenerateForeignKeyAssociationType(associationType, databaseMapping);
            }
            else if (associationType.IsManyToMany())
            {
                GenerateManyToManyAssociation(associationType, databaseMapping);
            }
            else
            {
                GenerateIndependentAssociationType(associationType, databaseMapping);
            }
        }
        internal void Configure(
            DbDatabaseMapping databaseMapping, DbEntityTypeMappingFragment fragment, EdmEntityType entityType)
        {
            Contract.Requires(fragment != null);

            var edmPropertyPath = EntityMappingConfiguration.PropertyPathToEdmPropertyPath(PropertyPath, entityType);

            if (edmPropertyPath.Count() > 1)
            {
                throw Error.InvalidNotNullCondition(PropertyPath.ToString(), entityType.Name);
            }

            var column
                = fragment.PropertyMappings
                    .Where(pm => pm.PropertyPath.SequenceEqual(edmPropertyPath.Single()))
                    .Select(pm => pm.Column)
                    .SingleOrDefault();

            if (column == null
                || !fragment.Table.Columns.Contains(column))
            {
                throw Error.InvalidNotNullCondition(PropertyPath.ToString(), entityType.Name);
            }

            if (ValueConditionConfiguration.AnyBaseTypeToTableWithoutColumnCondition(
                databaseMapping, entityType, fragment.Table, column))
            {
                column.IsNullable = true;
            }

            // Make the property required
            var newConfiguration = new Properties.Primitive.PrimitivePropertyConfiguration
                {
                    IsNullable = false,
                    OverridableConfigurationParts =
                        OverridableConfigurationParts.OverridableInSSpace
                };

            newConfiguration.Configure(edmPropertyPath.Single().Last());

            fragment.AddNullabilityCondition(column, isNull: false);
        }
        public void Configure_should_configure_default_schema()
        {
            var modelConfiguration
                = new ModelConfiguration
                      {
                          DefaultSchema = "foo"
                      };

            var databaseMapping
                = new DbDatabaseMapping().Initialize(
                    new EdmModel().Initialize(),
                    new DbDatabaseMetadata().Initialize());

            Assert.Equal("dbo", databaseMapping.Database.Schemas.Single().Name);
            Assert.Equal("dbo", databaseMapping.Database.Schemas.Single().DatabaseIdentifier);

            modelConfiguration.Configure(databaseMapping, ProviderRegistry.Sql2008_ProviderManifest);

            Assert.Equal("foo", databaseMapping.Database.Schemas.Single().Name);
            Assert.Equal("foo", databaseMapping.Database.Schemas.Single().DatabaseIdentifier);
        }
        public void Generate(EdmEntityType entityType, DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(entityType != null);
            //Contract.Requires(databaseMapping != null);

            var entitySet = databaseMapping.Model.GetEntitySet(entityType);

            var entitySetMapping
                = databaseMapping.GetEntitySetMapping(entitySet)
                  ?? databaseMapping.AddEntitySetMapping(entitySet);

            var table
                = entitySetMapping.EntityTypeMappings.Any()
                      ? entitySetMapping.EntityTypeMappings.First().TypeMappingFragments.First().Table
                      : databaseMapping.Database.AddTable(entityType.GetRootType().Name);

            var entityTypeMappingFragment = new DbEntityTypeMappingFragment
                {
                    Table = table
                };

            var entityTypeMapping = new DbEntityTypeMapping
                {
                    EntityType = entityType,
                    IsHierarchyMapping = false
                };
            entityTypeMapping.TypeMappingFragments.Add(entityTypeMappingFragment);
            entityTypeMapping.SetClrType(entityType.GetClrType());

            entitySetMapping.EntityTypeMappings.Add(entityTypeMapping);

            new PropertyMappingGenerator(_providerManifest)
                .Generate(
                    entityType,
                    entityType.Properties,
                    entitySetMapping,
                    entityTypeMappingFragment,
                    new List<EdmProperty>(),
                    false);
        }
        public void GetComplexPropertyMappings_should_return_all_complex_property_mappings_for_type()
        {
            var databaseMapping = new DbDatabaseMapping()
                .Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata());
            var entitySet = new EdmEntitySet();
            var entitySetMapping = databaseMapping.AddEntitySetMapping(entitySet);
            var entityTypeMapping = new DbEntityTypeMapping();
            entitySetMapping.EntityTypeMappings.Add(entityTypeMapping);
            var entityTypeMappingFragment = new DbEntityTypeMappingFragment();
            entityTypeMapping.TypeMappingFragments.Add(entityTypeMappingFragment);
            var propertyMapping1 = new DbEdmPropertyMapping();
            var complexType = new EdmComplexType();
            complexType.SetClrType(typeof(object));
            propertyMapping1.PropertyPath.Add(new EdmProperty { PropertyType = new EdmTypeReference { EdmType = complexType } });
            entityTypeMappingFragment.PropertyMappings.Add(propertyMapping1);
            var propertyMapping2 = new DbEdmPropertyMapping();
            propertyMapping2.PropertyPath.Add(new EdmProperty { PropertyType = new EdmTypeReference() });
            propertyMapping2.PropertyPath.Add(new EdmProperty { PropertyType = new EdmTypeReference { EdmType = complexType } });
            entityTypeMappingFragment.PropertyMappings.Add(propertyMapping2);

            Assert.Equal(2, databaseMapping.GetComplexPropertyMappings(typeof(object)).Count());
        }
        private void GenerateManyToManyAssociation(
            EdmAssociationType associationType, DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(associationType != null);
            //Contract.Requires(databaseMapping != null);

            var sourceEntityType = associationType.SourceEnd.EntityType;
            var targetEntityType = associationType.TargetEnd.EntityType;

            var joinTable
                = databaseMapping.Database.AddTable(sourceEntityType.Name + targetEntityType.Name);

            var associationSetMapping
                = GenerateAssociationSetMapping(
                    associationType, databaseMapping, associationType.SourceEnd, associationType.TargetEnd, joinTable);

            GenerateIndependentForeignKeyConstraint(
                databaseMapping,
                sourceEntityType,
                targetEntityType,
                joinTable,
                associationSetMapping,
                associationSetMapping.SourceEndMapping,
                associationType.SourceEnd.Name,
                null,
                isPrimaryKeyColumn: true);

            GenerateIndependentForeignKeyConstraint(
                databaseMapping,
                targetEntityType,
                sourceEntityType,
                joinTable,
                associationSetMapping,
                associationSetMapping.TargetEndMapping,
                associationType.TargetEnd.Name,
                null,
                isPrimaryKeyColumn: true);
        }
        private static void GenerateForeignKeyAssociationType(
            EdmAssociationType associationType, DbDatabaseMapping databaseMapping)
        {
            //Contract.Requires(associationType != null);
            //Contract.Requires(databaseMapping != null);
            Contract.Assert(associationType.Constraint != null);

            var dependentEnd = associationType.Constraint.DependentEnd;
            var principalEnd = associationType.GetOtherEnd(dependentEnd);
            var principalEntityTypeMapping = GetEntityTypeMappingInHierarchy(databaseMapping, principalEnd.EntityType);
            var dependentEntityTypeMapping = GetEntityTypeMappingInHierarchy(databaseMapping, dependentEnd.EntityType);

            var foreignKeyConstraint = new DbForeignKeyConstraintMetadata
                {
                    Name = associationType.Name,
                    PrincipalTable =
                        principalEntityTypeMapping.TypeMappingFragments.Single().Table,
                    DeleteAction = principalEnd.DeleteAction.HasValue
                                       ? (DbOperationAction)principalEnd.DeleteAction.Value
                                       : DbOperationAction.None
                };

            foreach (var dependentProperty in associationType.Constraint.DependentProperties)
            {
                foreignKeyConstraint.DependentColumns.Add(
                    dependentEntityTypeMapping.GetPropertyMapping(dependentProperty).Column);
            }

            foreignKeyConstraint.SetAssociationType(associationType);

            dependentEntityTypeMapping
                .TypeMappingFragments
                .Single()
                .Table
                .ForeignKeyConstraints.Add(foreignKeyConstraint);
        }
        private void ConfigureAssociationMappings(DbDatabaseMapping databaseMapping, EdmEntityType entityType)
        {
            Contract.Requires(databaseMapping != null);

            foreach (var configuration in _navigationPropertyConfigurations)
            {
                var propertyInfo = configuration.Key;
                var navigationPropertyConfiguration = configuration.Value;
                var navigationProperty = entityType.GetNavigationProperty(propertyInfo);

                if (navigationProperty == null)
                {
                    throw Error.NavigationPropertyNotFound(propertyInfo.Name, entityType.Name);
                }

                var associationSetMapping
                    = databaseMapping.GetAssociationSetMappings()
                        .SingleOrDefault(asm => asm.AssociationSet.ElementType == navigationProperty.Association);

                if (associationSetMapping != null)
                {
                    navigationPropertyConfiguration.Configure(associationSetMapping, databaseMapping);
                }
            }
        }
        internal void Configure(
            EdmEntityType entityType,
            DbDatabaseMapping databaseMapping,
            DbProviderManifest providerManifest)
        {
            Contract.Requires(entityType != null);
            Contract.Requires(databaseMapping != null);
            Contract.Requires(providerManifest != null);

            var entityTypeMapping
                = databaseMapping.GetEntityTypeMapping(entityType.GetClrType());

            if (entityTypeMapping != null)
            {
                VerifyAllCSpacePropertiesAreMapped(
                    databaseMapping.GetEntityTypeMappings(entityType),
                    entityTypeMapping.EntityType.DeclaredProperties,
                    new List<EdmProperty>());
            }

            ConfigurePropertyMappings(databaseMapping, entityType, providerManifest);
            ConfigureAssociationMappings(databaseMapping, entityType);
            ConfigureDependentKeys(databaseMapping);
        }
        private void ConfigurePropertyMappings(
            DbDatabaseMapping databaseMapping, EdmEntityType entityType, DbProviderManifest providerManifest,
            bool allowOverride = false)
        {
            Contract.Requires(databaseMapping != null);
            Contract.Requires(entityType != null);
            Contract.Requires(providerManifest != null);

            var entityTypeMappings = databaseMapping.GetEntityTypeMappings(entityType);

            var propertyMappings
                = from etm in entityTypeMappings
                  from etmf in etm.TypeMappingFragments
                  from pm in etmf.PropertyMappings
                  select Tuple.Create(pm, etmf.Table);

            Configure(propertyMappings, providerManifest, allowOverride);

            foreach (
                var derivedEntityType in databaseMapping.Model.GetEntityTypes().Where(et => et.BaseType == entityType))
            {
                ConfigurePropertyMappings(databaseMapping, derivedEntityType, providerManifest, true);
            }
        }
        public void Configure_should_configure_mapping()
        {
            var manyToManyAssociationMappingConfiguration = new ManyToManyAssociationMappingConfiguration();
            manyToManyAssociationMappingConfiguration.ToTable("Foo");

            var navigationPropertyConfiguration = new NavigationPropertyConfiguration(new MockPropertyInfo())
                {
                    AssociationMappingConfiguration = manyToManyAssociationMappingConfiguration
                };

            var databaseMapping = new DbDatabaseMapping().Initialize(new EdmModel().Initialize(), new DbDatabaseMetadata());
            var associationSetMapping = databaseMapping.AddAssociationSetMapping(new EdmAssociationSet { ElementType = new EdmAssociationType() });
            associationSetMapping.Table = new DbTableMetadata();
            associationSetMapping.AssociationSet.ElementType.SetConfiguration(navigationPropertyConfiguration);

            navigationPropertyConfiguration.Configure(associationSetMapping, databaseMapping);

            Assert.Equal("Foo", associationSetMapping.Table.GetTableName().Name);
        }
예제 #27
0
 public EntityMappingService(DbDatabaseMapping databaseMapping)
 {
     Contract.Requires(databaseMapping != null);
     _databaseMapping = databaseMapping;
 }
예제 #28
0
 void IDbMappingConvention.Apply(DbDatabaseMapping databaseMapping)
 {
     Contract.Requires(databaseMapping != null);
 }
        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 static void ConfigureDependentKeys(DbDatabaseMapping databaseMapping)
        {
            Contract.Requires(databaseMapping != null);

            var defaultSchema = databaseMapping.Database.Schemas.Single();

            foreach (var foreignKeyConstraint in defaultSchema.Tables.SelectMany(t => t.ForeignKeyConstraints))
            {
                foreignKeyConstraint
                    .DependentColumns
                    .Each(
                        (c, i) =>
                            {
                                var primitivePropertyConfiguration =
                                    c.GetConfiguration() as PrimitivePropertyConfiguration;

                                if ((primitivePropertyConfiguration != null)
                                    && (primitivePropertyConfiguration.ColumnType != null))
                                {
                                    return;
                                }

                                var principalColumn = foreignKeyConstraint.PrincipalTable.KeyColumns.ElementAt(i);

                                c.TypeName = principalColumn.TypeName;
                                c.Facets.CopyFrom(principalColumn.Facets);
                            });
            }
        }