private void FixUpDeferredForeignKeyMetadata( CustomMetadataWorkspace workspace, IEnumerable <DeferredForeignKeyMetadata> deferredForeignKeys ) { foreach (DeferredForeignKeyMetadata metadata in deferredForeignKeys) { CustomEntityType targetEntity; if (!workspace.TryGetEntityType(metadata.Attribute.TargetEntityType, out targetEntity)) { ThrowUnableToFindPartOfForeignKey( "entity type mapped to CLR object", metadata.Attribute.TargetEntityType.Name, metadata ); } var targetPrimaryKey = targetEntity.PrimaryKeyProperties .Where(pk => pk.Name == metadata.Attribute.TargetKeyPropertyName) .Select(pk => pk) .SingleOrDefault(); if (null == targetPrimaryKey) { ThrowUnableToFindPartOfForeignKey( "primary key", metadata.Attribute.TargetKeyPropertyName, metadata ); } metadata.Consraint.DefferedInitialization(targetEntity, targetPrimaryKey); } }
private CustomEntitySetType InferEntitySetFromEntityType( CustomMetadataWorkspace metadata, CustomEntityType entityType, string context ) { var candidateEntitySets = metadata.EntitySets.Where(es => es.BaseElementType .IsAssignableFrom(entityType)) .Select(es => es); if (candidateEntitySets.Count() == 1) { return(candidateEntitySets.First()); } throw new CustomMetadataException(String.Format( "Cannot infer type of entity set from given entity type '{0}' " + "in the context of '{1}' because there are either no or several " + "entity sets with suitable base element type: [{2}]. Specify " + "which entity set to use.", entityType, context, CustomUtils.FormatCsvString(candidateEntitySets.Select(e => e.Name)) )); }
private void FixUpDeferredRelationshipMetadata( CustomMetadataWorkspace workspace, IEnumerable <DeferredRelationshipMetadata> deferredRelationships ) { foreach (DeferredRelationshipMetadata metadata in deferredRelationships) { CustomEntityType entityType; if (!workspace.TryGetEntityType(metadata.ClrObjectType, out entityType)) { ThrowUnableToFindPartOfRelationship("entity type mapped to CLR object", metadata.ClrObjectType.Name, metadata); } CustomEntitySetType entitySetType; if (null == metadata.Attribute.EntitySetName) { entitySetType = InferEntitySetFromEntityType(workspace, entityType, metadata.ToString()); } else { if (!workspace.TryGetEntitySet(metadata.Attribute.EntitySetName, out entitySetType)) { ThrowUnableToFindPartOfRelationship("entity set", metadata.Attribute.EntitySetName, metadata); } Debug.Assert(entitySetType.BaseElementType.IsAssignableFrom(entityType)); } var multiplicity = metadata.Attribute.Multiplicity; var navProperty = metadata.NavigationProperty; bool isPrimaryEnd = metadata.Attribute.IsPrimaryEnd; var relatedEndMultiplicity = metadata.Attribute.RelatedEndMultiplicity; CustomEntityType relatedEndEntityType; if (null == metadata.Attribute.RelatedEndEntityType) { if (CustomMultiplicity.Many == relatedEndMultiplicity) { Debug.Assert(typeof(IEnumerable).IsAssignableFrom(navProperty.ClrType)); if ((typeof(ICollection <>).IsAssignableFrom(navProperty.ClrType.GetGenericTypeDefinition()))) { relatedEndEntityType = workspace.GetEntityType(navProperty.ClrType.GetGenericArguments()[0]); } else { throw new CustomMetadataException(String.Format( "Cannot infer type of collection returned by navigation " + "property '{0}' because it is not generic collection. Use " + "generic collection or specify the type of the related entity.", navProperty )); } } else { Debug.Assert(!typeof(IEnumerable).IsAssignableFrom(navProperty.ClrType)); relatedEndEntityType = workspace.GetEntityType(navProperty.ClrType); } } else { if (!workspace.TryGetEntityType(metadata.Attribute.RelatedEndEntityType, out relatedEndEntityType)) { ThrowUnableToFindPartOfRelationship("entity type mapped to CLR object", metadata.Attribute.RelatedEndEntityType.Name, metadata); } } CustomEntitySetType relatedEndEntitySetType; if (null == metadata.Attribute.RelatedEndEntitySetName) { relatedEndEntitySetType = InferEntitySetFromEntityType(workspace, relatedEndEntityType, metadata.ToString()); } else { if (!workspace.TryGetEntitySet(metadata.Attribute.RelatedEndEntitySetName, out relatedEndEntitySetType)) { ThrowUnableToFindPartOfRelationship("entity set", metadata.Attribute.RelatedEndEntitySetName, metadata); } Debug.Assert(relatedEndEntitySetType.BaseElementType.IsAssignableFrom(relatedEndEntityType)); } CustomNavigationPropertyType relatedEndProperty = null; if (null != metadata.Attribute.RelatedEndPropertyName) { relatedEndProperty = relatedEndEntityType.NavigationProperties .Where(p => p.Name == metadata.Attribute.RelatedEndPropertyName) .Select(p => p) .SingleOrDefault(); if (null == relatedEndProperty) { ThrowUnableToFindPartOfRelationship("other end navigation property", metadata.Attribute.RelatedEndPropertyName, metadata); } } metadata.NavigationProperty.From.DefferedInitialization( isPrimaryEnd, entitySetType, entityType, navProperty, multiplicity ); metadata.NavigationProperty.To.DefferedInitialization( !isPrimaryEnd, relatedEndEntitySetType, relatedEndEntityType, relatedEndProperty, relatedEndMultiplicity ); if (null != metadata.NavigationProperty.To.RelatedProperty) { var fromMember = metadata.NavigationProperty.To; if (fromMember.RelatedProperty.From.EntityType != null) { /* * Debug.Assert(fromMember.RelatedProperty.To.RelatedProperty == metadata.NavigationProperty); * Debug.Assert(fromMember.RelatedProperty.To.EntityType == metadata.NavigationProperty.From.EntityType); * Debug.Assert(fromMember.RelatedProperty.To.Multiplicity == metadata.NavigationProperty.From.Multiplicity); * Debug.Assert(fromMember.RelatedProperty.To.IsPrimaryEnd == metadata.NavigationProperty.From.IsPrimaryEnd); */ } } if (CustomMultiplicity.Many == navProperty.To.Multiplicity) { Debug.Assert(typeof(IEnumerable).IsAssignableFrom(navProperty.ClrType));; } } }
private CustomMetadataWorkspace Build() { CustomMetadataWorkspace workspace = new CustomMetadataWorkspace(); ICollection <DeferredForeignKeyMetadata> deferredForeignKeys = new List <DeferredForeignKeyMetadata>(); ICollection <DeferredRelationshipMetadata> deferredRelationships = new List <DeferredRelationshipMetadata>(); ICollection <CustomEntitySetType> collectedEntitySets = new List <CustomEntitySetType>(); foreach (Type clrObjectType in _clrObjectTypeCollection) { ICollection <EntityMemberCandidate> memberCandidates = CollectFlatMemberCandidateList(clrObjectType); ICollection <CustomPropertyType> properties = GetEntityProperties( clrObjectType, memberCandidates, deferredForeignKeys ); ICollection <CustomNavigationPropertyType> navigationProperties = GetEntityNavigationProperties( clrObjectType, memberCandidates, deferredRelationships ); CustomEntityType entityType = new CustomEntityType( clrObjectType, properties, navigationProperties ); CollectEntitySets(clrObjectType, entityType, collectedEntitySets); workspace.Add(entityType); if (memberCandidates.Count > 0) { /* * warn user about unmapped properties? * Debug.Fail(String.Format( * "Found unmapped properties [{0}] in CLR object '{1}'.", * CustomUtils.FormatCsvString(memberCandidates.Select(m => m.ToString())), clrObjectType.Name * )); */ } } foreach (CustomEntitySetType entitySet in collectedEntitySets) { workspace.Add(entitySet); } FixUpDeferredForeignKeyMetadata(workspace, deferredForeignKeys); FixUpDeferredRelationshipMetadata(workspace, deferredRelationships); workspace.ValidateAndLock(); return(workspace); }