private void InternalImplementToType(IEntityBase targetType, ImplementTypeOptions options) { EntityBase entityBase = (EntityBase)targetType; List <PropertyBase> addedProperties = new List <PropertyBase>(); foreach (PropertyBase property in this.Properties) { if (!entityBase.ContainsProperty(property.PropertyKind, property.Name)) { PropertyBase copiedProperty = (PropertyBase)property.Copy(new[] { PersistentTypeHasProperties.PersistentTypeDomainRoleId }); entityBase.Properties.Add(copiedProperty); addedProperties.Add(copiedProperty); } } foreach (NavigationProperty navigationProperty in this.NavigationProperties) { if (!entityBase.ContainsProperty(PropertyKind.Navigation, navigationProperty.Name)) { NavigationProperty copiedNavigationProperty = (NavigationProperty)navigationProperty.Copy(new[] { PersistentTypeHasNavigationProperties.PersistentTypeOfNavigationPropertyDomainRoleId, }); entityBase.NavigationProperties.Add(copiedNavigationProperty); copiedNavigationProperty.PersistentTypeHasAssociations.SourcePersistentType = entityBase; addedProperties.Add(copiedNavigationProperty); } } foreach (EntityIndex entityIndex in this.Indexes) { if (!entityBase.ContainsIndex(entityIndex)) { EntityIndex copiedIndex = (EntityIndex)entityIndex.Copy(new[] { InterfaceHasIndexes.InterfaceOfIndexDomainRoleId }); entityBase.Indexes.Add(copiedIndex); } } if (Util.IsFlagSet(ImplementTypeOptions.CopyInheritedInterfaces, options)) { foreach (Interface inheritedInterface in this.InheritedInterfaces) { if (!entityBase.InheritedInterfaces.Contains(inheritedInterface)) { entityBase.InheritedInterfaces.Add(inheritedInterface); } } } if (!targetType.InheritedInterfaces.Contains(this)) { entityBase.InheritedInterfaces.Add(this); } var duplicatedInfo = PersistentTypeValidation.FindDuplicatedPropertieInInheritanceTree(targetType, null); foreach (var addedProperty in addedProperties) { Func <IPropertyBase, bool> foundPropertyFunc = item => item.PropertyKind == addedProperty.PropertyKind && Util.StringEqual(item.Name, addedProperty.Name, true); addedProperty.IsInherited = duplicatedInfo.PropertiesWithDifferentType.Any(foundPropertyFunc) || duplicatedInfo.PropertiesWithSameType.Any(foundPropertyFunc); } }
internal static void ValidateInheritanceTree(EntityModel entityModel, ValidationContext context) { context.BeginValidationGlobalStage(ValidationGlobalStage.EntityModelInheritanceTree); try { // get types which are on top of hierarchy, means that these types are not referenced as interfaces implementation nor as base type // for any other types var topHierarchyTypes = entityModel.TopHierarchyTypes; var inheritanceTrees = new Dictionary <IInterface, InheritanceTree>(); foreach (IInterface hierarchyType in topHierarchyTypes) { InheritanceTree inheritanceTree = hierarchyType.GetInheritanceTree(); inheritanceTree.RebuildTree(true); if (!inheritanceTrees.ContainsKey(hierarchyType)) { inheritanceTrees.Add(hierarchyType, inheritanceTree); } var duplicatedDirectInheritances = inheritanceTree.FoundDuplicatedDirectInheritances(); foreach (var inheritanceDetail in duplicatedDirectInheritances) { string duplicatedItems = string.Join(";", inheritanceDetail.Items.Select(item => string.Format("{0}:{1}", item.Interface.Name, item.Type == InheritanceType.Direct ? "D" : "I"))); string error = string.Format( "{0} '{1}' has direct inheritance to type '{2}', but {0} '{1}' is inherited(directly:D or indirectly:I) from other types ({3}) which already inheriting type '{2}'. Please remove direct inheritance '{2}' from type '{1}'", hierarchyType.TypeKind, hierarchyType.Name, inheritanceDetail.Owner.Name, duplicatedItems); var inheritanceLink = InterfaceInheritInterfaces.GetLink((Interface)hierarchyType, (Interface)inheritanceDetail.Owner); context.LogError(error, CODE_DUPLICATED_DIRECT_INHERITANCE, new[] { inheritanceLink }); } } // continue only if revious check does not log any error if (!context.HasViolations()) { foreach (var hierarchyType in topHierarchyTypes) { InheritanceTree inheritanceTree = null; if (inheritanceTrees.ContainsKey(hierarchyType)) { inheritanceTree = inheritanceTrees[hierarchyType]; } var duplicatedPropertiesInfo = PersistentTypeValidation.FindDuplicatedPropertieInInheritanceTree(hierarchyType, inheritanceTree); var duplicatedProperties = duplicatedPropertiesInfo.PropertiesWithSameType; bool logAsWarning = hierarchyType.TypeKind == PersistentTypeKind.Interface; IterateThroughDuplicatedProperties(hierarchyType, duplicatedProperties, false, logAsWarning, context); duplicatedProperties = duplicatedPropertiesInfo.PropertiesWithDifferentType; logAsWarning = false; IterateThroughDuplicatedProperties(hierarchyType, duplicatedProperties, true, logAsWarning, context); if (duplicatedPropertiesInfo.InheritancePathsCount > 1) { context.LogWarning( string.Format( "{0} '{1}' has multiple({2}) inheritance paths, this may cause an inconsistent property types and/or attributes generated", hierarchyType.TypeKind, hierarchyType.Name, duplicatedPropertiesInfo.InheritancePathsCount), "MultipleInheritancePaths", new ModelElement[] { hierarchyType as Interface }); } if (context.CountViolations(ViolationType.Error, ViolationType.Fatal) > 0) { PersistentTypeValidation.ValidateProperties((PersistentType)hierarchyType, inheritanceTree, context); } } } } finally { context.EndValidationGlobalStage(ValidationGlobalStage.EntityModelInheritanceTree); } }