Пример #1
0
        /// <summary>
        /// Configures a related entity of the given entity.
        /// </summary>
        /// <typeparam name="TProperty">The type of the related entity property.</typeparam>
        /// <typeparam name="TKey">The type of the related entity key.</typeparam>
        /// <param name="relatedEntityProperty">The related entity property.</param>
        /// <param name="relatedEntityKey">The related entity key.</param>
        /// <returns>The configuration ovject of the given entity.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="relatedEntityProperty"/> is null.</exception>
        /// <exception cref="System.ArgumentException">The <paramref name="relatedEntityProperty"/> is not an one level property expression.</exception>
        public RelatedEntityItemConfiguration <TEntity, TProperty> WithEntity <TProperty, TKey>(
            Expression <Func <TItem, TProperty> > relatedEntityProperty,
            Expression <Func <TItem, TKey> > relatedEntityKey)
            where TProperty : class
        {
            Error.ArgumentNullException_IfNull(relatedEntityProperty, "relatedEntityProperty");
            DAError.ArgumentException_IfNotOneLevelPropertyExpression(relatedEntityProperty);
            if (relatedEntityKey != null)
            {
                DAError.ArgumentException_IfNotOneLevelPropertyExpression(relatedEntityKey);
            }

            var memberProperty = ReflectionHelper.GetPropertyName(relatedEntityProperty);
            var memberKey      = relatedEntityKey != null?ReflectionHelper.GetPropertyName(relatedEntityKey) : string.Empty;

            var newMember = new RelatedEntityInfo(
                string.Format(newMemberFormat2, currentRelatedEntityInfo.RelatedPropertyPath, memberProperty),
                string.Format(newMemberFormat2, currentRelatedEntityInfo.RelatedKeyPath, memberKey));

            if (!relatedEntityInfo.Contains(newMember))
            {
                relatedEntityInfo.Remove(currentRelatedEntityInfo);

                relatedEntityInfo.Add(newMember);
            }

            return(new RelatedEntityItemConfiguration <TEntity, TProperty>(
                       relatedEntityInfo, newMember, subEntityInfo, usedEntityInfo, usingEntityInfo));
        }
Пример #2
0
        /// <summary>
        /// Initializes the new instance of the <see cref="RelatedEntityItemConfiguration{TEntity,TItem}"/> class.
        /// </summary>
        /// <param name="relatedEntityInfo">Information about related entities.</param>
        /// <param name="currentRelatedEntityInfo">Information about the current related entity to be continued.</param>
        /// <param name="subEntityInfo">Information about sub entities for the given entity.</param>
        /// <param name="usedEntityInfo">Information about entities used by the given entity.</param>
        /// <param name="usingEntityInfo">Information about entities using the given entity.</param>
        /// <exception cref="System.ArgumentNullException">The <paramref name="relatedEntityInfo"/> or
        /// <paramref name="currentRelatedEntityInfo"/> or <paramref name="subEntityInfo"/> or
        /// <paramref name="usedEntityInfo"/> or <paramref name="usingEntityInfo"/> is null.</exception>
        internal RelatedEntityItemConfiguration(IList <RelatedEntityInfo> relatedEntityInfo,
                                                RelatedEntityInfo currentRelatedEntityInfo, IList <RelatedEntityInfo> subEntityInfo,
                                                IList <RelatedEntityInfo> usedEntityInfo, IList <RelatedEntityInfo> usingEntityInfo)
            : base(subEntityInfo, usedEntityInfo, usingEntityInfo)
        {
            Error.ArgumentNullException_IfNull(relatedEntityInfo, "currentEntityInfo");
            Error.ArgumentNullException_IfNull(currentRelatedEntityInfo, "currentRelatedEntityInfo");

            this.relatedEntityInfo        = relatedEntityInfo;
            this.currentRelatedEntityInfo = currentRelatedEntityInfo;
        }
Пример #3
0
        /// <summary>
        /// Combines the two related entity information instances.
        /// </summary>
        /// <param name="firstInfo">The first related entity information.</param>
        /// <param name="secondInfo">The second related entity information.</param>
        /// <returns>The combined related entity information.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="firstInfo"/>
        /// or the <paramref name="secondInfo"/> is null.</exception>
        public static RelatedEntityInfo Combine(RelatedEntityInfo firstInfo, RelatedEntityInfo secondInfo)
        {
            Error.ArgumentNullException_IfNull(firstInfo, "firstInfo");
            Error.ArgumentNullException_IfNull(secondInfo, "secondInfo");

            if (firstInfo.IsEmpty())
            {
                return(secondInfo);
            }
            else if (secondInfo.IsEmpty())
            {
                return(firstInfo);
            }

            return(new RelatedEntityInfo(string.Format("{0}.{1}", firstInfo.RelatedPropertyPath, secondInfo.RelatedPropertyPath),
                                         string.Format("{0}.{1}", firstInfo.RelatedKeyPath, secondInfo.RelatedKeyPath)));
        }
Пример #4
0
        /// <summary>
        /// Combines the two related entity information instances.
        /// </summary>
        /// <param name="firstInfo">The first related entity information.</param>
        /// <param name="secondInfo">The second related entity information.</param>
        /// <returns>The combined related entity information.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="firstInfo"/>
        /// or the <paramref name="secondInfo"/> is null.</exception>
        public static RelatedEntityInfo Combine(RelatedEntityInfo firstInfo, RelatedEntityInfo secondInfo)
        {
            Error.ArgumentNullException_IfNull(firstInfo, "firstInfo");
            Error.ArgumentNullException_IfNull(secondInfo, "secondInfo");

            if (firstInfo.IsEmpty())
            {
                return secondInfo;
            }
            else if (secondInfo.IsEmpty())
            {
                return firstInfo;
            }

            return new RelatedEntityInfo(string.Format("{0}.{1}", firstInfo.RelatedPropertyPath, secondInfo.RelatedPropertyPath),
                string.Format("{0}.{1}", firstInfo.RelatedKeyPath, secondInfo.RelatedKeyPath));
        }
        /// <summary>
        /// Configures using entities for the entity.
        /// </summary>
        /// <typeparam name="TProperty">The type of the using entities property.</typeparam>
        /// <param name="usingEntitiesProperty">The using collection.</param>
        /// <returns>The configuration object to configure a using entities.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="usingEntitiesProperty"/> is null.</exception>
        /// <exception cref="System.ArgumentException">The <paramref name="usingEntitiesProperty"/> is not an one level property expression.</exception>
        public RelatedEntityItemConfiguration <TEntity, TProperty> IsUsedByEntities <TProperty>(
            Expression <Func <TEntity, ICollection <TProperty> > > usingEntitiesProperty)
            where TProperty : class
        {
            Error.ArgumentNullException_IfNull(usingEntitiesProperty, "usingEntitiesProperty");
            DAError.ArgumentException_IfNotOneLevelPropertyExpression(usingEntitiesProperty);

            var member = new RelatedEntityInfo(ReflectionHelper.GetPropertyName(usingEntitiesProperty), string.Empty);

            if (!usingEntityInfo.Contains(member))
            {
                usingEntityInfo.Add(member);
            }

            return(new RelatedEntityItemConfiguration <TEntity, TProperty>(
                       usingEntityInfo, member, subEntityInfo, usedEntityInfo, usingEntityInfo));
        }
        /// <summary>
        /// Configures a sub entity of the entity.
        /// </summary>
        /// <typeparam name="TProperty">The type of the sub entity property.</typeparam>
        /// <typeparam name="TKey">The type of the sub entity key.</typeparam>
        /// <param name="subEntityProperty">The sub entity property.</param>
        /// <param name="subEntityKey">The sub entity key.</param>
        /// <returns>The configuration object for related entities.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="subEntityProperty"/> is null.</exception>
        /// <exception cref="System.ArgumentException">The <paramref name="subEntityProperty"/> or
        /// <paramref name="subEntityKey"/> is not an one level property expression.</exception>
        public RelatedEntityItemConfiguration <TEntity, TProperty> HasSubEntity <TProperty, TKey>(
            Expression <Func <TEntity, TProperty> > subEntityProperty, Expression <Func <TEntity, TKey> > subEntityKey)
            where TProperty : class
        {
            Error.ArgumentNullException_IfNull(subEntityProperty, "subEntityProperty");
            DAError.ArgumentException_IfNotOneLevelPropertyExpression(subEntityProperty);
            if (subEntityKey != null)
            {
                DAError.ArgumentException_IfNotOneLevelPropertyExpression(subEntityKey);
            }

            var member = new RelatedEntityInfo(ReflectionHelper.GetPropertyName(subEntityProperty),
                                               subEntityKey != null ? ReflectionHelper.GetPropertyName(subEntityKey) : string.Empty);

            if (!subEntityInfo.Contains(member))
            {
                subEntityInfo.Add(member);
            }

            return(new RelatedEntityItemConfiguration <TEntity, TProperty>(
                       subEntityInfo, member, subEntityInfo, usedEntityInfo, usingEntityInfo));
        }
Пример #7
0
        /// <summary>
        /// Checks if the current information includes the specified information.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns><c>true</c> if the current information includes the specified information, otherwise <c>false</c>.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="other"/> is null.</exception>
        public bool Includes(RelatedEntityInfo other)
        {
            Error.ArgumentNullException_IfNull(other, "other");

            return(RelatedPropertyPath.StartsWith(other.RelatedPropertyPath));
        }
Пример #8
0
        /// <summary>
        /// Checks if the current information includes the specified information.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns><c>true</c> if the current information includes the specified information, otherwise <c>false</c>.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="other"/> is null.</exception>
        public bool Includes(RelatedEntityInfo other)
        {
            Error.ArgumentNullException_IfNull(other, "other");

            return RelatedPropertyPath.StartsWith(other.RelatedPropertyPath);
        }
Пример #9
0
        /// <summary>
        /// Recursively iterates over all the related entities and runs the specified action.
        /// Iteration is executed in the recursive ascending direction.
        /// </summary>
        /// <param name="rootEntity">The root entity.</param>
        /// <param name="relatedEntityContainer">The related entity container.</param>
        /// <param name="currentEntityInfo">The current entity information.</param>
        /// <param name="containerEntityInfo">The container's entity information.</param>
        /// <param name="direction">A direction of the recursive iteration.</param>
        /// <param name="action">The action.</param>
        /// <param name="subEntityInfo">The information about sub entities to skip.</param>
        private void ForEachRelatedEntity(TEntity rootEntity, object relatedEntityContainer,
                                          RelatedEntityInfo currentEntityInfo, RelatedEntityInfo containerEntityInfo,
                                          RecursionDirection direction, Action <RelatedEntityActionContext <TEntity> > action,
                                          RelatedEntityInfo[] subEntityInfo)
        {
            var info = currentEntityInfo.First();

            var absoluteInfo = RelatedEntityInfo.Combine(containerEntityInfo, info);

            //If we're working with used or using entities, then
            //skip the related entity if it is a part of a sub entity.
            //Do not call action for sub entities.
            var callAction = subEntityInfo == null ||
                             !subEntityInfo.Any(se => se.Includes(absoluteInfo));

            var nextInfo = currentEntityInfo.WithoutFirst();

            if (ReflectionHelper.IsInherited <IEnumerable <object> >(relatedEntityContainer.GetType(), info.RelatedPropertyPath))
            {
                var collection = ReflectionHelper.GetPropertyValue <IEnumerable <object> >(
                    relatedEntityContainer, info.RelatedPropertyPath);

                if (direction == RecursionDirection.Descending)
                {
                    if (callAction)
                    {
                        action(new RelatedEntityActionContext <TEntity>()
                        {
                            RootEntity                = rootEntity,
                            RelatedEntity             = collection,
                            RelatedEntityContainer    = relatedEntityContainer,
                            RelatedEntityInfo         = absoluteInfo,
                            RelatedEntityPropertyInfo =
                                ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedPropertyPath),
                            RelatedEntityKeyInfo = !string.IsNullOrEmpty(info.RelatedKeyPath) ?
                                                   ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedKeyPath) : null
                        });
                    }

                    collection = ReflectionHelper.GetPropertyValue <IEnumerable <object> >(
                        relatedEntityContainer, info.RelatedPropertyPath);

                    //After the action above the collection can be null
                    if (collection == null)
                    {
                        return;
                    }
                }

                //Convert to list because the collection can be modified
                if (collection != null)
                {
                    foreach (var item in collection.ToList())
                    {
                        if (direction == RecursionDirection.Ascending)
                        {
                            if (item != null && !nextInfo.IsEmpty())
                            {
                                ForEachRelatedEntity(rootEntity, item, nextInfo,
                                                     absoluteInfo, direction, action, subEntityInfo);
                            }
                        }

                        if (callAction)
                        {
                            action(new RelatedEntityActionContext <TEntity>()
                            {
                                RootEntity                = rootEntity,
                                RelatedEntity             = item,
                                RelatedEntityContainer    = relatedEntityContainer,
                                RelatedEntityInfo         = absoluteInfo,
                                RelatedEntityPropertyInfo =
                                    ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedPropertyPath),
                                RelatedEntityKeyInfo = !string.IsNullOrEmpty(info.RelatedKeyPath) ?
                                                       ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedKeyPath) : null
                            });
                        }

                        if (direction == RecursionDirection.Descending)
                        {
                            if (item == null)
                            {
                                continue;
                            }

                            if (!nextInfo.IsEmpty())
                            {
                                ForEachRelatedEntity(rootEntity, item, nextInfo,
                                                     absoluteInfo, direction, action, subEntityInfo);
                            }
                        }
                    }
                }

                if (direction == RecursionDirection.Ascending)
                {
                    if (callAction)
                    {
                        action(new RelatedEntityActionContext <TEntity>()
                        {
                            RootEntity                = rootEntity,
                            RelatedEntity             = collection,
                            RelatedEntityContainer    = relatedEntityContainer,
                            RelatedEntityInfo         = absoluteInfo,
                            RelatedEntityPropertyInfo =
                                ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedPropertyPath),
                            RelatedEntityKeyInfo = !string.IsNullOrEmpty(info.RelatedKeyPath) ?
                                                   ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedKeyPath) : null
                        });
                    }
                }
            }
            else
            {
                var member = ReflectionHelper.GetPropertyValue <object>(relatedEntityContainer, info.RelatedPropertyPath);

                if (direction == RecursionDirection.Ascending)
                {
                    if (member != null && !nextInfo.IsEmpty())
                    {
                        ForEachRelatedEntity(rootEntity, member, nextInfo,
                                             absoluteInfo, direction, action, subEntityInfo);
                    }
                }

                if (callAction)
                {
                    action(new RelatedEntityActionContext <TEntity>()
                    {
                        RootEntity                = rootEntity,
                        RelatedEntity             = member,
                        RelatedEntityContainer    = relatedEntityContainer,
                        RelatedEntityInfo         = absoluteInfo,
                        RelatedEntityPropertyInfo =
                            ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedPropertyPath),
                        RelatedEntityKeyInfo = !string.IsNullOrEmpty(info.RelatedKeyPath) ?
                                               ReflectionHelper.GetPropertyInfo(relatedEntityContainer.GetType(), info.RelatedKeyPath) : null
                    });
                }

                if (direction == RecursionDirection.Descending)
                {
                    member = ReflectionHelper.GetPropertyValue <object>(relatedEntityContainer, info.RelatedPropertyPath);

                    if (member == null)
                    {
                        return;
                    }

                    if (!nextInfo.IsEmpty())
                    {
                        ForEachRelatedEntity(rootEntity, member, nextInfo,
                                             absoluteInfo, direction, action, subEntityInfo);
                    }
                }
            }
        }