private void RediscoverComplexTypes(IEnumerable <IStructuralTypeConfiguration> explicitlyAddedTypes)
        {
            IEnumerable <IEntityTypeConfiguration> misconfiguredEntityTypes = StructuralTypes
                                                                              .Except(explicitlyAddedTypes)
                                                                              .OfType <IEntityTypeConfiguration>()
                                                                              .Where(entity => !entity.Keys.Any())
                                                                              .ToArray();

            IEnumerable <IEntityTypeConfiguration> actualEntityTypes = StructuralTypes
                                                                       .Except(misconfiguredEntityTypes)
                                                                       .OfType <IEntityTypeConfiguration>()
                                                                       .ToArray();

            foreach (IEntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes)
            {
                RemoveStructuralType(misconfiguredEntityType.ClrType);

                foreach (IEntityTypeConfiguration entityToBePatched in actualEntityTypes)
                {
                    NavigationPropertyConfiguration[] propertiesToBeRemoved = entityToBePatched
                                                                              .NavigationProperties
                                                                              .Where(navigationProperty => navigationProperty.RelatedClrType == misconfiguredEntityType.ClrType)
                                                                              .ToArray();
                    foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
                    {
                        entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);
                        entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
                    }
                }

                AddComplexType(misconfiguredEntityType.ClrType);
            }
        }
示例#2
0
        // patch up the base type for all entities that don't have any yet.
        internal void DiscoverInheritanceRelationships()
        {
            Dictionary <Type, EntityTypeConfiguration> entityMap = StructuralTypes.OfType <EntityTypeConfiguration>().ToDictionary(e => e.ClrType);

            foreach (EntityTypeConfiguration entity in StructuralTypes.OfType <EntityTypeConfiguration>().Where(e => !e.BaseTypeConfigured))
            {
                Type baseClrType = entity.ClrType.BaseType;
                while (baseClrType != null)
                {
                    // see if we there is an entity that we know mapping to this clr types base type.
                    EntityTypeConfiguration baseEntityType;
                    if (entityMap.TryGetValue(baseClrType, out baseEntityType))
                    {
                        RemoveBaseTypeProperties(entity, baseEntityType);

                        // disable derived type key check if we are building a model for query composition.
                        if (_isQueryCompositionMode)
                        {
                            // modifying the collection in the iterator, hence the ToArray().
                            foreach (PrimitivePropertyConfiguration keyProperty in entity.Keys.ToArray())
                            {
                                entity.RemoveKey(keyProperty);
                            }
                        }

                        entity.DerivesFrom(baseEntityType);
                        break;
                    }

                    baseClrType = baseClrType.BaseType;
                }
            }
        }
示例#3
0
        private IEdmTypeConfiguration GetStructuralTypeOrNull(Type clrType)
        {
            IEdmTypeConfiguration configuration = StructuralTypes.SingleOrDefault(edmType => edmType.ClrType == clrType);

            if (configuration == null)
            {
                Type type = TypeHelper.GetUnderlyingTypeOrSelf(clrType);
                configuration = EnumTypes.SingleOrDefault(edmType => edmType.ClrType == type);
            }

            return(configuration);
        }
示例#4
0
        private void RediscoverComplexTypes()
        {
            Contract.Assert(_explicitlyAddedTypes != null);

            EntityTypeConfiguration[] misconfiguredEntityTypes = StructuralTypes
                                                                 .Except(_explicitlyAddedTypes)
                                                                 .OfType <EntityTypeConfiguration>()
                                                                 .Where(entity => !entity.Keys().Any())
                                                                 .ToArray();

            ReconfigureEntityTypesAsComplexType(misconfiguredEntityTypes);
        }
示例#5
0
        public override IEdmModel GetEdmModel()
        {
            if (_isModelBeingBuilt)
            {
                throw Error.NotSupported(SRResources.GetEdmModelCalledMoreThanOnce);
            }

            // before we begin, get the set of types the user had added explicitly.
            _explicitlyAddedTypes = new List <IStructuralTypeConfiguration>(StructuralTypes);

            _isModelBeingBuilt = true;

            MapTypes();

            _conventionsBeingApplied = true;

            // Apply type conventions. Note the call to ToArray() is required as the StructuralTypes collection
            // could get modified during ApplyTypeConventions().
            foreach (IStructuralTypeConfiguration edmTypeConfiguration in StructuralTypes.ToArray())
            {
                ApplyTypeConventions(edmTypeConfiguration);
            }

            // Apply property conventions. Note the call to ToArray() is required as the StructuralTypes collection
            // could get modified during ApplyPropertyConventions(). Also, type conventions might have
            // modified this. So, call ToArray() again.
            foreach (IStructuralTypeConfiguration edmTypeConfiguration in StructuralTypes.ToArray())
            {
                ApplyPropertyConventions(edmTypeConfiguration);
            }

            // Don't RediscoverComplexTypes() and treat everything as an entity type if buidling a model for QueryableAttribute.
            if (!_isQueryCompositionMode)
            {
                RediscoverComplexTypes();
            }

            // prune unreachable types
            PruneUnreachableTypes();

            // Apply entity set conventions.
            IEnumerable <IEntitySetConfiguration> explictlyConfiguredEntitySets = new List <IEntitySetConfiguration>(EntitySets);

            foreach (IEntitySetConfiguration entitySet in explictlyConfiguredEntitySets)
            {
                ApplyEntitySetConventions(entitySet);
            }

            return(base.GetEdmModel());
        }
示例#6
0
        private void ReconfigureEntityTypesAsComplexType(EntityTypeConfiguration[] misconfiguredEntityTypes)
        {
            IEnumerable <EntityTypeConfiguration> actualEntityTypes = StructuralTypes
                                                                      .Except(misconfiguredEntityTypes)
                                                                      .OfType <EntityTypeConfiguration>();

            foreach (EntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes)
            {
                RemoveStructuralType(misconfiguredEntityType.ClrType);

                // this is a wrongly inferred type. so just ignore any pending configuration from it.
                AddComplexType(misconfiguredEntityType.ClrType);

                foreach (EntityTypeConfiguration entityToBePatched in actualEntityTypes)
                {
                    NavigationPropertyConfiguration[] propertiesToBeRemoved = entityToBePatched
                                                                              .NavigationProperties
                                                                              .Where(navigationProperty => navigationProperty.RelatedClrType == misconfiguredEntityType.ClrType)
                                                                              .ToArray();
                    foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
                    {
                        string propertyNameAlias = propertyToBeRemoved.Name;
                        PropertyConfiguration propertyConfiguration;

                        entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);

                        if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many)
                        {
                            propertyConfiguration = entityToBePatched.AddCollectionProperty(propertyToBeRemoved.PropertyInfo);
                        }
                        else
                        {
                            propertyConfiguration = entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
                        }

                        Contract.Assert(propertyToBeRemoved.AddedExplicitly == false);

                        // The newly added property must be marked as added implicitly. This can make sure the property
                        // conventions can be re-applied to the new property.
                        propertyConfiguration.AddedExplicitly = false;

                        ReapplyPropertyConvention(propertyConfiguration, entityToBePatched);

                        propertyConfiguration.Name = propertyNameAlias;
                    }
                }
            }
        }
示例#7
0
        // the convention model builder MapTypes() method might have went through deep object graphs and added a bunch of types
        // only to realise after applying the conventions that the user has ignored some of the properties. So, prune the unreachable stuff.
        private void PruneUnreachableTypes()
        {
            Contract.Assert(_explicitlyAddedTypes != null);

            // Do a BFS starting with the types the user has explicitly added to find out the unreachable nodes.
            Queue <IStructuralTypeConfiguration>   reachableTypes = new Queue <IStructuralTypeConfiguration>(_explicitlyAddedTypes);
            HashSet <IStructuralTypeConfiguration> visitedTypes   = new HashSet <IStructuralTypeConfiguration>();

            while (reachableTypes.Count != 0)
            {
                IStructuralTypeConfiguration currentType = reachableTypes.Dequeue();

                // go visit other end of each of this node's edges.
                foreach (PropertyConfiguration property in currentType.Properties.Where(property => property.Kind != PropertyKind.Primitive))
                {
                    if (property.Kind == PropertyKind.Collection)
                    {
                        // if the elementType is primitive we don't need to do anything.
                        CollectionPropertyConfiguration colProperty = property as CollectionPropertyConfiguration;
                        if (EdmLibHelpers.GetEdmPrimitiveTypeOrNull(colProperty.ElementType) != null)
                        {
                            continue;
                        }
                    }

                    IStructuralTypeConfiguration propertyType = GetStructuralTypeOrNull(property.RelatedClrType);
                    Contract.Assert(propertyType != null, "we should already have seen this type");

                    if (!visitedTypes.Contains(propertyType))
                    {
                        reachableTypes.Enqueue(propertyType);
                    }
                }

                visitedTypes.Add(currentType);
            }

            IStructuralTypeConfiguration[] allConfiguredTypes = StructuralTypes.ToArray();
            foreach (IStructuralTypeConfiguration type in allConfiguredTypes)
            {
                if (!visitedTypes.Contains(type))
                {
                    // we don't have to fix up any properties because this type is unreachable and cannot be a property of any reachable type.
                    RemoveStructuralType(type.ClrType);
                }
            }
        }
示例#8
0
        private void ApplyForeignKeyConventions()
        {
            ForeignKeyAttributeConvention     foreignKeyAttributeConvention = new ForeignKeyAttributeConvention();
            ForeignKeyDiscoveryConvention     foreignKeyDiscoveryConvention = new ForeignKeyDiscoveryConvention();
            ActionOnDeleteAttributeConvention actionOnDeleteConvention      = new ActionOnDeleteAttributeConvention();

            foreach (EntityTypeConfiguration edmType in StructuralTypes.OfType <EntityTypeConfiguration>())
            {
                foreach (PropertyConfiguration property in edmType.Properties)
                {
                    // ForeignKeyDiscoveryConvention has to run after ForeignKeyAttributeConvention
                    foreignKeyAttributeConvention.Apply(property, edmType, this);
                    foreignKeyDiscoveryConvention.Apply(property, edmType, this);

                    actionOnDeleteConvention.Apply(property, edmType, this);
                }
            }
        }
示例#9
0
        internal void ReconfigInferedEntityTypeAsComplexType(Type propertyType)
        {
            HashSet <Type> visitedTypes = new HashSet <Type>();

            Queue <Type> typeToBeVisited = new Queue <Type>();

            typeToBeVisited.Enqueue(propertyType);

            IList <EntityTypeConfiguration> foundMappedTypes = new List <EntityTypeConfiguration>();

            while (typeToBeVisited.Count != 0)
            {
                Type currentType = typeToBeVisited.Dequeue();
                visitedTypes.Add(currentType);

                List <Type> derivedTypes;
                if (_allTypesWithDerivedTypeMapping.Value.TryGetValue(currentType, out derivedTypes))
                {
                    foreach (Type derivedType in derivedTypes)
                    {
                        if (!visitedTypes.Contains(derivedType))
                        {
                            StructuralTypeConfiguration structuralType = StructuralTypes.Except(_explicitlyAddedTypes)
                                                                         .FirstOrDefault(c => c.ClrType == derivedType);

                            if (structuralType != null && structuralType.Kind == EdmTypeKind.Entity)
                            {
                                foundMappedTypes.Add((EntityTypeConfiguration)structuralType);
                            }

                            typeToBeVisited.Enqueue(derivedType);
                        }
                    }
                }
            }

            if (foundMappedTypes.Any())
            {
                ReconfigureEntityTypesAsComplexType(foundMappedTypes.ToArray());
            }
        }
示例#10
0
        private void ReconfigureEntityTypesAsComplexType(EntityTypeConfiguration[] misconfiguredEntityTypes)
        {
            IEnumerable <EntityTypeConfiguration> actualEntityTypes = StructuralTypes
                                                                      .Except(misconfiguredEntityTypes)
                                                                      .OfType <EntityTypeConfiguration>();

            foreach (EntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes)
            {
                RemoveStructuralType(misconfiguredEntityType.ClrType);

                // this is a wrongly inferred type. so just ignore any pending configuration from it.
                AddComplexType(misconfiguredEntityType.ClrType);

                foreach (EntityTypeConfiguration entityToBePatched in actualEntityTypes)
                {
                    NavigationPropertyConfiguration[] propertiesToBeRemoved = entityToBePatched
                                                                              .NavigationProperties
                                                                              .Where(navigationProperty => navigationProperty.RelatedClrType == misconfiguredEntityType.ClrType)
                                                                              .ToArray();
                    foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
                    {
                        string propertyNameAlias = propertyToBeRemoved.Name;
                        PropertyConfiguration propertyConfiguration;

                        entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);

                        if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many)
                        {
                            propertyConfiguration = entityToBePatched.AddCollectionProperty(propertyToBeRemoved.PropertyInfo);
                        }
                        else
                        {
                            propertyConfiguration = entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
                        }

                        propertyConfiguration.Name = propertyNameAlias;
                    }
                }
            }
        }
示例#11
0
        private void ReconfigureEntityTypesAsComplexType(IEnumerable <EntityTypeConfiguration> misconfiguredEntityTypes)
        {
            IEnumerable <EntityTypeConfiguration> actualEntityTypes = StructuralTypes
                                                                      .Except(misconfiguredEntityTypes)
                                                                      .OfType <EntityTypeConfiguration>()
                                                                      .ToArray();

            foreach (EntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes)
            {
                RemoveStructuralType(misconfiguredEntityType.ClrType);

                ComplexTypeConfiguration newComplexType = AddComplexType(misconfiguredEntityType.ClrType);
                foreach (PropertyInfo ignoredProperty in misconfiguredEntityType.IgnoredProperties)
                {
                    newComplexType.RemoveProperty(ignoredProperty);
                }

                foreach (EntityTypeConfiguration entityToBePatched in actualEntityTypes)
                {
                    NavigationPropertyConfiguration[] propertiesToBeRemoved = entityToBePatched
                                                                              .NavigationProperties
                                                                              .Where(navigationProperty => navigationProperty.RelatedClrType == misconfiguredEntityType.ClrType)
                                                                              .ToArray();
                    foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
                    {
                        entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);

                        if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many)
                        {
                            entityToBePatched.AddCollectionProperty(propertyToBeRemoved.PropertyInfo);
                        }
                        else
                        {
                            entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
                        }
                    }
                }
            }
        }
示例#12
0
        // patch up the base type for all entities that don't have any yet.
        internal void DiscoverInheritanceRelationships()
        {
            Dictionary <Type, EntityTypeConfiguration> entityMap = StructuralTypes.OfType <EntityTypeConfiguration>().ToDictionary(e => e.ClrType);

            foreach (EntityTypeConfiguration entity in StructuralTypes.OfType <EntityTypeConfiguration>().Where(e => !e.BaseTypeConfigured).ToArray())
            {
                Type baseClrType = entity.ClrType.BaseType;
                while (baseClrType != null)
                {
                    // see if we there is an entity that we know mapping to this clr types base type.
                    EntityTypeConfiguration baseEntityType;
                    if (entityMap.TryGetValue(baseClrType, out baseEntityType))
                    {
                        RemoveBaseTypeProperties(entity, baseEntityType);
                        entity.DerivesFrom(baseEntityType);
                        break;
                    }

                    baseClrType = baseClrType.BaseType;
                }
            }
        }
示例#13
0
        private void ReconfigureEntityTypesAsComplexType(IEnumerable <IEntityTypeConfiguration> misconfiguredEntityTypes)
        {
            IEnumerable <IEntityTypeConfiguration> actualEntityTypes = StructuralTypes
                                                                       .Except(misconfiguredEntityTypes)
                                                                       .OfType <IEntityTypeConfiguration>()
                                                                       .ToArray();

            foreach (IEntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes)
            {
                RemoveStructuralType(misconfiguredEntityType.ClrType);

                IComplexTypeConfiguration newComplexType = AddComplexType(misconfiguredEntityType.ClrType);
                foreach (var ignoredProperty in misconfiguredEntityType.IgnoredProperties)
                {
                    newComplexType.RemoveProperty(ignoredProperty);
                }

                foreach (IEntityTypeConfiguration entityToBePatched in actualEntityTypes)
                {
                    NavigationPropertyConfiguration[] propertiesToBeRemoved = entityToBePatched
                                                                              .NavigationProperties
                                                                              .Where(navigationProperty => navigationProperty.RelatedClrType == misconfiguredEntityType.ClrType)
                                                                              .ToArray();
                    foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
                    {
                        if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many)
                        {
                            // complex collections are not supported.
                            throw Error.NotSupported(SRResources.CollectionPropertiesNotSupported, propertyToBeRemoved.PropertyInfo.Name, propertyToBeRemoved.PropertyInfo.ReflectedType.FullName);
                        }
                        entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);
                        entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
                    }
                }

                AddComplexType(misconfiguredEntityType.ClrType);
            }
        }
示例#14
0
        private void ReconfigureEntityTypesAsComplexType(EntityTypeConfiguration[] misconfiguredEntityTypes)
        {
            IList <EntityTypeConfiguration> actualEntityTypes =
                StructuralTypes.OfType <EntityTypeConfiguration>()
                .Where(entity => entity.Keys().Any())
                .Concat(_explicitlyAddedTypes.OfType <EntityTypeConfiguration>())
                .Except(misconfiguredEntityTypes)
                .ToList();

            HashSet <EntityTypeConfiguration> visitedEntityType = new HashSet <EntityTypeConfiguration>();

            foreach (EntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes)
            {
                if (visitedEntityType.Contains(misconfiguredEntityType))
                {
                    continue;
                }

                // If one of the base types is already configured as entity type, we should keep this type as entity type.
                IEnumerable <EntityTypeConfiguration> basedTypes = misconfiguredEntityType
                                                                   .BaseTypes().OfType <EntityTypeConfiguration>();
                if (actualEntityTypes.Any(e => basedTypes.Any(a => a.ClrType == e.ClrType)))
                {
                    visitedEntityType.Add(misconfiguredEntityType);
                    continue;
                }

                // Make sure to remove current type and all the derived types
                IList <EntityTypeConfiguration> thisAndDerivedTypes = this.DerivedTypes(misconfiguredEntityType)
                                                                      .Concat(new[] { misconfiguredEntityType }).OfType <EntityTypeConfiguration>().ToList();
                foreach (EntityTypeConfiguration subEnityType in thisAndDerivedTypes)
                {
                    if (actualEntityTypes.Any(e => e.ClrType == subEnityType.ClrType))
                    {
                        throw Error.InvalidOperation(SRResources.CannotReconfigEntityTypeAsComplexType,
                                                     misconfiguredEntityType.ClrType.FullName, subEnityType.ClrType.FullName);
                    }

                    RemoveStructuralType(subEnityType.ClrType);
                }

                // this is a wrongly inferred type. so just ignore any pending configuration from it.
                AddComplexType(misconfiguredEntityType.ClrType);

                foreach (EntityTypeConfiguration subEnityType in thisAndDerivedTypes)
                {
                    visitedEntityType.Add(subEnityType);

                    // go through all structural types to remove all properties defined by this mis-configed type.
                    IList <StructuralTypeConfiguration> allTypes = StructuralTypes.ToList();
                    foreach (StructuralTypeConfiguration structuralToBePatched in allTypes)
                    {
                        NavigationPropertyConfiguration[] propertiesToBeRemoved = structuralToBePatched
                                                                                  .NavigationProperties
                                                                                  .Where(navigationProperty => navigationProperty.RelatedClrType == subEnityType.ClrType)
                                                                                  .ToArray();

                        foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
                        {
                            string propertyNameAlias = propertyToBeRemoved.Name;
                            PropertyConfiguration propertyConfiguration;

                            structuralToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);

                            if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many)
                            {
                                propertyConfiguration =
                                    structuralToBePatched.AddCollectionProperty(propertyToBeRemoved.PropertyInfo);
                            }
                            else
                            {
                                propertyConfiguration =
                                    structuralToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
                            }

                            Contract.Assert(propertyToBeRemoved.AddedExplicitly == false);

                            // The newly added property must be marked as added implicitly. This can make sure the property
                            // conventions can be re-applied to the new property.
                            propertyConfiguration.AddedExplicitly = false;

                            ReapplyPropertyConvention(propertyConfiguration, structuralToBePatched);

                            propertyConfiguration.Name = propertyNameAlias;
                        }
                    }
                }
            }
        }
 private IStructuralTypeConfiguration GetStructuralTypeOrNull(Type clrType)
 {
     return(StructuralTypes.Where(edmType => edmType.ClrType == clrType).SingleOrDefault());
 }