Esempio n. 1
0
        /// <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;
         }
     }
 }
Esempio n. 8
0
        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);
        }
Esempio n. 10
0
        /// <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();
            }
        }
Esempio n. 15
0
 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);