/// <summary> /// Gets a navigation property on the given entity type. Returns null if no navigation property is found. /// </summary> /// <param name="entityType"> The entity type to find the navigation property on. </param> /// <param name="propertyInfo"> The navigation property on the entity class. </param> /// <returns> The navigation property, or null if none is found. </returns> public static INavigation FindNavigation([NotNull] this IEntityType entityType, [NotNull] PropertyInfo propertyInfo) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(propertyInfo, nameof(propertyInfo)); return(entityType.FindNavigation(propertyInfo.Name)); }
/// <inheritdoc /> public void Resolve() { if (EntityFrameworkCoreIsEnabled()) { DbContext context = _resolver.GetContext(); foreach (ContextEntity ce in _graph.Entities) { IEntityType meta = context.Model.FindEntityType(ce.EntityType); if (meta == null) { continue; } foreach (var attr in ce.Relationships) { if (attr is HasManyThroughAttribute) { continue; } INavigation inverseNavigation = meta.FindNavigation(attr.InternalRelationshipName)?.FindInverse(); attr.InverseNavigation = inverseNavigation?.Name; } } } }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public static IEnumerable <IPropertyBase> GetNotificationProperties( [NotNull] this IEntityType entityType, [CanBeNull] string propertyName) { if (string.IsNullOrEmpty(propertyName)) { foreach (var property in entityType.GetProperties() .Where(p => p.GetAfterSaveBehavior() == PropertySaveBehavior.Save)) { yield return(property); } foreach (var navigation in entityType.GetNavigations()) { yield return(navigation); } } else { // ReSharper disable once AssignNullToNotNullAttribute var property = (IPropertyBase)entityType.FindProperty(propertyName) ?? entityType.FindNavigation(propertyName); if (property != null) { yield return(property); } } }
/// <summary> /// Gets a navigation property on the given entity type. Returns <c>null</c> if no navigation property is found. /// </summary> /// <param name="entityType"> The entity type to find the navigation property on. </param> /// <param name="memberInfo"> The navigation property on the entity class. </param> /// <returns> The navigation property, or <c>null</c> if none is found. </returns> public static INavigation FindNavigation([NotNull] this IEntityType entityType, [NotNull] MemberInfo memberInfo) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(memberInfo, nameof(memberInfo)); return(entityType.FindNavigation(memberInfo.GetSimpleMemberName())); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual void Intercept(IInvocation invocation) { var methodName = invocation.Method.Name; if (_lazyLoaderGetter.Equals(invocation.Method)) { invocation.ReturnValue = _loader; } else if (_lazyLoaderSetter.Equals(invocation.Method)) { _loader = (ILazyLoader)invocation.Arguments[0]; } else { if (_loader != null && methodName.StartsWith("get_", StringComparison.Ordinal)) { var navigationName = methodName.Substring(4); var navigation = _entityType.FindNavigation(navigationName); if (navigation != null && !navigation.ForeignKey.IsOwnership) { _loader.Load(invocation.Proxy, navigationName); } } invocation.Proceed(); } }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public static IEnumerable <IPropertyBase> GetNotificationProperties( [NotNull] this IEntityType entityType, [CanBeNull] string propertyName) { if (string.IsNullOrEmpty(propertyName)) { foreach (var property in entityType.GetProperties().Where(p => !p.IsReadOnlyAfterSave)) { yield return(property); } foreach (var navigation in entityType.GetNavigations()) { yield return(navigation); } } else { var property = (IPropertyBase)entityType.FindProperty(propertyName) ?? entityType.FindNavigation(propertyName); if (property != null) { yield return(property); } } }
private void ResolveRelationships(IReadOnlyCollection <RelationshipAttribute> relationships, IEntityType entityType) { foreach (var relationship in relationships) { if (!(relationship is HasManyThroughAttribute)) { INavigation inverseNavigation = entityType.FindNavigation(relationship.Property.Name)?.FindInverse(); relationship.InverseNavigationProperty = inverseNavigation?.PropertyInfo; } } }
public static INavigation GetNavigation([NotNull] this IEntityType entityType, [NotNull] string name) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(name, nameof(name)); var navigation = entityType.FindNavigation(name); if (navigation == null) { throw new ModelItemNotFoundException(Strings.NavigationNotFound(name, entityType.Name)); } return(navigation); }
public static IEntityType GetOwnedProperty(this DbContext context, IEntityType rootEntity, string navigationProperty) { INavigation navigationProp = rootEntity .FindNavigation(navigationProperty); IEntityType ownedEntity = context.Model.GetEntityTypes() .FirstOrDefault( x => x.ClrType == navigationProp.ClrType && x.IsOwned()); return(ownedEntity); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual void Intercept(IInvocation invocation) { var methodName = invocation.Method.Name; if (invocation.Method.DeclaringType == _notifyChangingInterface) { if (methodName == $"add_{nameof(INotifyPropertyChanging.PropertyChanging)}") { _handler = (PropertyChangingEventHandler)Delegate.Combine( _handler, (Delegate)invocation.Arguments[0]); } else if (methodName == $"remove_{nameof(INotifyPropertyChanging.PropertyChanging)}") { _handler = (PropertyChangingEventHandler)Delegate.Remove( _handler, (Delegate)invocation.Arguments[0]); } } else if (methodName.StartsWith("set_", StringComparison.Ordinal)) { var propertyName = methodName.Substring(4); var property = _entityType.FindProperty(propertyName); if (property != null) { var comparer = property.IsKey() || property.IsForeignKey() ? property.GetKeyValueComparer() : property.GetValueComparer(); HandleChanging(invocation, property, comparer); } else { var navigation = _entityType.FindNavigation(propertyName) ?? (INavigationBase)_entityType.FindSkipNavigation(propertyName); if (navigation != null) { HandleChanging(invocation, navigation, LegacyReferenceEqualityComparer.Instance); } else { invocation.Proceed(); } } } else { invocation.Proceed(); } }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void Intercept(IInvocation invocation) { var methodName = invocation.Method.Name; if (methodName.StartsWith("get_", StringComparison.Ordinal)) { var navigationName = methodName.Substring(4); var navigation = _entityType.FindNavigation(navigationName); if (navigation != null) { _loader.Load(invocation.Proxy, navigationName); } } invocation.Proceed(); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public static IProperty GetProperty([NotNull] this IEntityType entityType, [NotNull] string name) { Check.NotEmpty(name, nameof(name)); var property = entityType.FindProperty(name); if (property == null) { if (entityType.FindNavigation(name) != null) { throw new InvalidOperationException( CoreStrings.PropertyIsNavigation(name, entityType.DisplayName(), nameof(EntityEntry.Property), nameof(EntityEntry.Reference), nameof(EntityEntry.Collection))); } throw new InvalidOperationException(CoreStrings.PropertyNotFound(name, entityType.DisplayName())); } return(property); }
private void Resolve(DbContext dbContext) { foreach (ResourceContext resourceContext in _resourceContextProvider.GetResourceContexts()) { IEntityType entityType = dbContext.Model.FindEntityType(resourceContext.ResourceType); if (entityType != null) { foreach (var relationship in resourceContext.Relationships) { if (!(relationship is HasManyThroughAttribute)) { INavigation inverseNavigation = entityType.FindNavigation(relationship.Property.Name)?.FindInverse(); relationship.InverseNavigationProperty = inverseNavigation?.PropertyInfo; } } } } }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual void Intercept(IInvocation invocation) { var methodName = invocation.Method.Name; if (invocation.Method.DeclaringType.Equals(_notifyChangingInterface)) { if (methodName == $"add_{nameof(INotifyPropertyChanging.PropertyChanging)}") { _handler = (PropertyChangingEventHandler)Delegate.Combine( _handler, (Delegate)invocation.Arguments[0]); } else if (methodName == $"remove_{nameof(INotifyPropertyChanging.PropertyChanging)}") { _handler = (PropertyChangingEventHandler)Delegate.Remove( _handler, (Delegate)invocation.Arguments[0]); } } else if (methodName.StartsWith("set_", StringComparison.Ordinal)) { var propertyName = methodName.Substring(4); var property = _entityType.FindProperty(propertyName); if (property != null) { HandleChanging(invocation, propertyName); } else { var navigation = _entityType.FindNavigation(propertyName); if (navigation != null) { HandleChanging(invocation, propertyName); } else { invocation.Proceed(); } } } else { invocation.Proceed(); } }
private static IPropertyBase TryGetPropertyBase(IEntityType entityType, string propertyName) => (IPropertyBase)entityType.FindProperty(propertyName) ?? entityType.FindNavigation(propertyName);
private List <List <MemberInfo> > ResolveIncludePaths(string[] names, ref int depth, ref IEntityType entityType) { var navigations = entityType.FindDerivedNavigations(names[depth]); if (entityType.FindNavigation(names[depth]) is INavigation nonderived) { navigations = navigations.Prepend(nonderived); } var result = new List <List <MemberInfo> >(); if (!navigations.Any()) { return(result); } navigations = navigations.Distinct(); depth++; if (depth == names.Length) { depth--; result.AddRange(navigations.Select(n => new List <MemberInfo> { n.GetReadableMemberInfo() })); return(result); } foreach (var navigation in navigations) { var subtype = navigation.GetTargetType(); var success = false; var resolvedSubpaths = ResolveIncludePaths(names, ref depth, ref subtype); foreach (var subpath in resolvedSubpaths) { success |= (subpath.Count != 0); subpath.Insert(0, navigation.GetReadableMemberInfo()); result.Add(subpath); } if (!success) { entityType = subtype; } if (resolvedSubpaths.Count == 0) { result.Add(new List <MemberInfo> { navigation.GetReadableMemberInfo() }); } } return(result); }
private INavigation TryGetNavigation(RelationshipAttribute relationship) { IEntityType entityType = _dbContext.Model.FindEntityType(typeof(TResource)); return(entityType?.FindNavigation(relationship.Property.Name)); }
private static IPropertyBase TryGetPropertyBase(IEntityType entityType, string propertyName) => (IPropertyBase)entityType.FindProperty(propertyName) ?? entityType.FindNavigation(propertyName);