public static IEntityProperty GetProperty(this IEntityDefinition definition, string name) { return(definition.GetAllProperties().Where(p => p.PropertyInfo.Name == name).FirstOrDefault()); }
private IEnumerable <IEntityRelationship> GetEntityRelationships(IEntityDefinition definition) { var entityType = definition.EntityType; var propertyMap = definition.GetAllProperties().ToDictionary(p => p.PropertyInfo.Name, p => p); foreach (var mapping in propertyMap) { var currentProperty = mapping.Value; var propertyInfo = currentProperty.PropertyInfo; var propertyType = currentProperty.PropertyType; //For a single entity relationship var foreignKeyAttr = propertyInfo.GetCustomAttribute <ForeignKeyAttribute>(); if (foreignKeyAttr != null) { var linkedProperty = propertyMap.ContainsKey(foreignKeyAttr.Name) ? propertyMap[foreignKeyAttr.Name] : null; if (linkedProperty == null) { throw new InvalidOperationException($"Can't find property {foreignKeyAttr.Name} in {entityType.Name} as indicated by the {nameof(ForeignKeyAttribute)}."); } else if (IdTypes.Contains(currentProperty.PropertyType)) { yield return(new EntityRelationship { IdProperty = currentProperty, NavigationProperty = linkedProperty, EntityType = linkedProperty.PropertyType }); } else if (IdTypes.Contains(linkedProperty.PropertyType)) { yield return(new EntityRelationship { IdProperty = linkedProperty, NavigationProperty = currentProperty, EntityType = currentProperty.PropertyType }); } else { throw new InvalidOperationException($"Unable to determine the Id property between {currentProperty} and {linkedProperty}. Check the types for these properties are valid."); } continue; } //For an entity collection relationship if (propertyInfo.CanRead && propertyInfo.GetGetMethod().IsVirtual&& propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(ICollection <>)) { var collectionEntityType = propertyType.GetGenericArguments().FirstOrDefault(); var inversePropertyAttr = propertyInfo.GetCustomAttribute <InversePropertyAttribute>(); var relatedEntityMapping = EntityMapping.GetOrCreateDefinition(collectionEntityType).GetAllProperties(); IEntityProperty idProperty; if (inversePropertyAttr != null) { idProperty = relatedEntityMapping.Where(p => p.PropertyInfo.Name == inversePropertyAttr.Property).FirstOrDefault(); if (idProperty == null) { throw new InvalidOperationException($"Can't find property {inversePropertyAttr.Property} in {collectionEntityType} as indicated by the InversePropertyAttribute on {currentProperty}"); } else if (!IdTypes.Contains(idProperty.PropertyType)) { throw new InvalidOperationException($"The Id property {inversePropertyAttr.Property} in {collectionEntityType.Name} isn't of a compatible type."); } } else { //Default to the Id when no specific foreign key is found idProperty = relatedEntityMapping.Where(p => p.IsKey).FirstOrDefault(); } yield return(new EntityRelationship { IdProperty = idProperty, NavigationProperty = currentProperty, EntityType = collectionEntityType, IsCollection = true }); } } }