Пример #1
0
        /// <summary>
        /// Order entities according to principal self navigation count ascendingly
        /// for defining state appropriately.
        /// </summary>
        /// <example>
        /// firstCategory which has null value on ParentCategory property has 0 principal self
        /// navigation count. If ParentCategory of secondCategory is firstCategory, then secondCategory
        /// has 1 principal self navigation count, if ParentCategory of thirdCateogry is secondCategory,
        /// then it has 2 principal self navigaiton count. In this case, state of enitites must be defined
        /// in ascending order. In our example, the order is like below:
        /// 1. firstCategory, 2. secondCategory, 3. thirdCateogry.
        /// </example>
        /// <exception cref="ArgumentNullException">
        /// When entityCollection is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// When entities in collection do not have same type.
        /// </exception>
        /// <param name="entityCollection">EntityCollection to define state define order.</param>
        /// <returns>Orderer entity collection suiting for defining state.</returns>
        private IEnumerable <object> DefineStateDefineOrder(IEnumerable <object> entityCollection)
        {
            if (entityCollection == null)
            {
                throw new ArgumentNullException(nameof(entityCollection));
            }

            if (!entityCollection.Any())
            {
                return(entityCollection);
            }

            // Get type of entity
            string entityTypeName = entityCollection.First().GetType().Name;

            // All entities must have same type in collection.
            if (entityCollection
                .Any(m => m != null && m.GetType().Name != entityTypeName))
            {
                throw new InvalidOperationException(string.Format(
                                                        "All entities must have same type in collection to define state define order."
                                                        + " Entity type: {0}.",
                                                        entityTypeName));
            }

            // Check if entity has navigation propert to itself. If not, then
            // there is no need to order them, otherwise order.
            IGraphEntityTypeManager entityTypeManager = GetEntityTypeManager(entityTypeName);
            NavigationDetail        navigationDetail  = entityTypeManager.GetNavigationDetail();
            bool hasPrinciplaSelfNavigationProperty   = navigationDetail
                                                        .Relations
                                                        .Any(m => m.Direction == NavigationDirection.From &&
                                                             m.PropertyTypeName == entityTypeName);

            if (!hasPrinciplaSelfNavigationProperty)
            {
                return(entityCollection);
            }

            // Initialize store for ordered entities.
            Dictionary <object, int> principalCountStore =
                new Dictionary <object, int>();

            for (int i = 0; i < entityCollection.Count(); i++)
            {
                dynamic entity             = entityCollection.ElementAt(i);
                int     principalSelfCount = CalculatePrincipalSelfNavigationCount(
                    entity, principalCountStore);
            }

            // Order according to principal slef navigation properties ascendingly.
            return(principalCountStore.OrderBy(m => m.Value).Select(m => m.Key));
        }
Пример #2
0
        /// <summary>
        /// Get list of unique properties.
        /// </summary>
        /// <remarks>
        /// Generally useful when logging to get key data to later find entity easily.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// When context or typeName is null.
        /// </exception>
        /// <param name="context">Context to get unique keys from.</param>
        /// <param name="typeName">Name of type to get unique keys for.</param>
        /// <returns>List of unique properties</returns>
        public static List <PropertyInfo> GetUniqueProperties(
            this DbContext context,
            string typeName)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (string.IsNullOrEmpty(typeName))
            {
                throw new ArgumentNullException(nameof(typeName));
            }

            ContextHelper           contextHelper     = new ContextHelper(context);
            IGraphEntityTypeManager entityTypeManager = contextHelper
                                                        .GetEntityTypeManager(typeName);

            return(entityTypeManager.GetUniqueProperties());
        }
Пример #3
0
        /// <summary>
        /// Calculate state define order of added entities.
        /// </summary>
        /// <returns>Sorted stete define order.</returns>
        private IOrderedEnumerable <KeyValuePair <string, int> > CalculateStateDefineOrder()
        {
            // Initialize store
            Dictionary <string, int> store = new Dictionary <string, int>();

            List <string> typeNames = ObjectContext
                                      .MetadataWorkspace
                                      .GetItems <EntityType>(DataSpace.CSpace)
                                      .Select(m => m.Name)
                                      .ToList();

            foreach (string typeName in typeNames)
            {
                IGraphEntityTypeManager entityTypeManager =
                    GetEntityTypeManager(typeName);
                entityTypeManager.FindPrincipalCount(store);
            }

            IOrderedEnumerable <KeyValuePair <string, int> > sorted =
                store.OrderBy(m => m.Value);

            return(sorted);
        }
Пример #4
0
        /// <summary>
        /// Detach dependants of entity.
        /// </summary>
        /// <exception cref="ArgumentNullException">
        /// When  entity is null
        /// </exception>
        /// <typeparam name="TEntity">Type of entity.</typeparam>
        /// <param name="entity">Entity to detach dependants.</param>
        /// <param name="detachItself">Also detach entity itself.</param>
        public void DetachWithDependants <TEntity>(
            TEntity entity,
            bool detachItself)
            where TEntity : class
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            string typeName = entity.GetType().Name;
            IGraphEntityTypeManager graphEntityTypeManager =
                GetEntityTypeManager(typeName);
            List <string> dependantPropertyTypes = graphEntityTypeManager
                                                   .GetForeignKeyDetails()
                                                   .Where(r => r.FromDetails
                                                          .ContainerClass
                                                          .Equals(typeName))
                                                   .Select(r => r.ToDetails.ContainerClass)
                                                   .ToList();

            List <PropertyInfo> dependantProperties = entity
                                                      .GetType()
                                                      .GetProperties()
                                                      .Where(p => dependantPropertyTypes
                                                             .Contains(p.PropertyType.GetUnderlyingType().Name))
                                                      .ToList();

            if (dependantProperties != null &&
                dependantProperties.Count > 0)
            {
                foreach (PropertyInfo childEntityProperty in dependantProperties)
                {
                    if (childEntityProperty.PropertyType.IsCollectionType())
                    {
                        // If child entity is collection detach all entities inside this collection
                        IEnumerable <object> enumerableChildEntity =
                            ReflectionExtensions.GetPropertyValue(entity, childEntityProperty.Name)
                            as IEnumerable <object>;

                        if (enumerableChildEntity != null)
                        {
                            foreach (dynamic childEntity in enumerableChildEntity.ToList())
                            {
                                if (childEntity != null)
                                {
                                    DetachWithDependants(childEntity, true);
                                }
                            }
                        }
                    }
                    else
                    {
                        // If child entity is not collection define state of its own
                        dynamic childEntity =
                            ReflectionExtensions.GetPropertyValue(entity, childEntityProperty.Name);

                        if (childEntity != null)
                        {
                            DetachWithDependants(childEntity, true);
                        }
                    }
                }
            }

            if (detachItself)
            {
                Context.Entry(entity).State = EntityState.Detached;
            }
        }
Пример #5
0
        /// <summary>
        /// Get parents of entity which contains this entity
        /// </summary>
        /// <exception cref="ArgumentNullException">
        /// When entity is null
        /// </exception>
        /// <typeparam name="TEntity">Type of entity.</typeparam>
        /// <param name="entity">Entity to get parent.</param>
        /// <param name="onlyPrincipal">Get only one-to-one parent of entity</param>
        /// <returns>Principal parent of entity.</returns>
        public IEnumerable <object> GetParents <TEntity>(
            TEntity entity,
            bool onlyPrincipal)
            where TEntity : class
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            string typeName = entity.GetType().Name;
            List <RelationshipMultiplicity> principalRelationshipMultiplicity =
                new List <RelationshipMultiplicity>()
            {
                RelationshipMultiplicity.One,
                RelationshipMultiplicity.ZeroOrOne
            };

            IGraphEntityTypeManager graphEntityTypeMangeer    = GetEntityTypeManager(typeName);
            NavigationDetail        navigationDetailOfCurrent = graphEntityTypeMangeer
                                                                .GetNavigationDetail();

            // Get only those parent property navigation details
            // which has navigation property to this entity
            var parentNavigationDetails = navigationDetailOfCurrent
                                          .Relations
                                          .Where(r => r.Direction == NavigationDirection.From)
                                          .Select(r =>
            {
                IGraphEntityTypeManager typeManager =
                    GetEntityTypeManager(r.PropertyTypeName);
                return(new
                {
                    SourceTypeName = r.PropertyTypeName,
                    Relation = typeManager
                               .GetNavigationDetail()
                               .Relations
                               .FirstOrDefault(pr =>
                                               pr.PropertyTypeName.Equals(typeName) &&
                                               pr.SourceMultiplicity == r.TargetMultiplicity &&
                                               pr.TargetMultiplicity == r.SourceMultiplicity &&
                                               pr.ToKeyNames.SequenceEqual(r.ToKeyNames))
                });
            })
                                          .Where(r => r.Relation != null);

            if (onlyPrincipal)
            {
                parentNavigationDetails = parentNavigationDetails
                                          .Where(r => principalRelationshipMultiplicity
                                                 .Contains(r.Relation.TargetMultiplicity));
            }

            List <string> parentPropertyNames = navigationDetailOfCurrent
                                                .Relations
                                                .Where(r => parentNavigationDetails.Any(p =>
                                                                                        p.SourceTypeName == r.PropertyTypeName &&
                                                                                        p.Relation.SourceMultiplicity == r.TargetMultiplicity &&
                                                                                        p.Relation.TargetMultiplicity == r.SourceMultiplicity &&
                                                                                        p.Relation.ToKeyNames.SequenceEqual(r.ToKeyNames)))
                                                .Select(r => r.PropertyName)
                                                .ToList();

            if (parentPropertyNames != null &&
                parentPropertyNames.Count > 0)
            {
                foreach (string propertyName in parentPropertyNames)
                {
                    object parent = entity.GetPropertyValue(propertyName);
                    if (parent != null)
                    {
                        yield return(parent);
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Find on how many properties this type depends on.
        /// </summary>
        /// <exception cref="ArgumentNullException">
        /// When store is null.
        /// </exception>
        /// <param name="store">Calculation store.</param>
        /// <returns>Calculated count.</returns>
        public int FindPrincipalCount(Dictionary <string, int> store)
        {
            if (store == null)
            {
                throw new ArgumentNullException(nameof(store));
            }

            // If principal count has already been
            // calculated for current type, get if from store.
            if (store.ContainsKey(EntityTypeName))
            {
                return(store[EntityTypeName]);
            }

            // Get principal properties.
            var navigationDetail    = GetNavigationDetail();
            var principalCollection = navigationDetail
                                      .Relations
                                      .Where(m => m.Direction == NavigationDirection.From);

            // Get state definers
            IEnumerable <PropertyInfo> stateDefiners = MappingStorage.Instance.StateDefiners
                                                       .Where(s => s.SourceType.Name.Equals(EntityTypeName))
                                                       .SelectMany(s => s.Properties);

            // Get types which this type is state definer for
            List <string> stateDefinerFor = MappingStorage
                                            .Instance
                                            .StateDefiners
                                            .Where(m => m.Properties
                                                   .Select(pr => pr.PropertyType.Name)
                                                   .Contains(EntityTypeName))
                                            .Select(m => m.SourceType.Name)
                                            .ToList();

            // If this type has no principal property
            // or stete definer return 0.
            if (principalCollection.Count() == 0 &&
                stateDefiners.Count() == 0)
            {
                store.Add(EntityTypeName, 0);
                return(0);
            }

            // Calculate initial count of principal properties
            // and state definers.
            int count = principalCollection.Count()
                        + stateDefiners.Count();

            // Loop through principal properties and add count of
            // principal properties of them to the current type.
            // Because when FirstType depends on SecondType,
            // and SecondType depends on ThirdType this means
            // that FirstType depends on SecondType and ThirdType.
            foreach (var principal in principalCollection)
            {
                // If this principal property is itself, do not count it
                if (principal.PropertyTypeName == EntityTypeName)
                {
                    continue;
                }

                // If this type is stete definer for principal
                // type, do not count it
                if (stateDefinerFor.Contains(principal.PropertyTypeName))
                {
                    continue;
                }

                IGraphEntityTypeManager entityTypeManager = ContextFactory
                                                            .GetEntityTypeManager(principal.PropertyTypeName);
                count += entityTypeManager.FindPrincipalCount(store);
            }

            // Add count of principal properties of state definers also.
            foreach (var stateDefiner in stateDefiners)
            {
                IGraphEntityTypeManager entityTypeManager = ContextFactory
                                                            .GetEntityTypeManager(stateDefiner.PropertyType.Name);
                count += entityTypeManager.FindPrincipalCount(store);
            }

            // Store calculation for further use.
            store.Add(EntityTypeName, count);
            return(count);
        }
Пример #7
0
        /// <summary>
        /// Get the the origin class which this foreign key refers to.
        /// </summary>
        /// <exception cref="ArgumentNullException">
        /// When foreignKeyName is null.
        /// </exception>
        /// <param name="foreignKeyName">Name of foreign key property.</param>
        /// <returns>Name of class which this foreign key refers to.</returns>
        public string GetOriginOfForeignKey(string foreignKeyName)
        {
            if (string.IsNullOrEmpty(foreignKeyName))
            {
                throw new ArgumentNullException(nameof(foreignKeyName));
            }

            // Try to get from store
            Tuple <string, string> key = new Tuple <string, string>(EntityTypeName, foreignKeyName);

            if (Store.ForeignKeyOrigin.ContainsKey(key))
            {
                return(Store.ForeignKeyOrigin[key]);
            }

            string originOfForeignKey = string.Empty;

            // Principal relationship multiplicities
            List <RelationshipMultiplicity> principalRelationshipMultiplicity =
                new List <RelationshipMultiplicity>()
            {
                RelationshipMultiplicity.One,
                RelationshipMultiplicity.ZeroOrOne
            };

            // Get the relationship detail which this foreign keys refers.
            RelationshipDetail parentType = GetForeignKeyDetails()
                                            .Where(r => r.ToDetails.ContainerClass.Equals(EntityTypeName) &&
                                                   r.ToDetails.Keys.Any(k => k.Equals(foreignKeyName)) &&
                                                   r.FromDetails != null &&
                                                   !string.IsNullOrEmpty(r.FromDetails.ContainerClass) &&
                                                   principalRelationshipMultiplicity
                                                   .Contains(r.FromDetails.RelationshipMultiplicity))
                                            .FirstOrDefault();

            if (parentType != null)
            {
                var currentReferencedTypeName = parentType.FromDetails.ContainerClass;
                var currentForeignKeyName     = GetMatchingFromForeignKeyName(parentType, foreignKeyName);
                while (!string.IsNullOrEmpty(currentReferencedTypeName))
                {
                    // If EntityTypeName and currentReferencedTypeName is same,
                    // then this is self reference, so we need to break infinete iteration.
                    if (EntityTypeName == currentReferencedTypeName)
                    {
                        break;
                    }

                    IGraphEntityTypeManager referencedTypeManager = ContextFactory
                                                                    .GetEntityTypeManager(currentReferencedTypeName);

                    // Get one-to-one principal parent relationship detail,
                    // because the origin of foreign key is uppermost principal parent.
                    RelationshipDetail principalParent = referencedTypeManager
                                                         .GetForeignKeyDetails()
                                                         .Where(r => r.ToDetails.ContainerClass.Equals(currentReferencedTypeName) &&
                                                                r.ToDetails.Keys.Contains(currentForeignKeyName) &&
                                                                r.FromDetails != null &&
                                                                !string.IsNullOrEmpty(r.FromDetails.ContainerClass) &&
                                                                principalRelationshipMultiplicity
                                                                .Contains(r.FromDetails.RelationshipMultiplicity))
                                                         .FirstOrDefault();

                    if (principalParent != null)
                    {
                        // If principal parent is not null set current to this.
                        currentReferencedTypeName = principalParent.FromDetails.ContainerClass;
                        currentForeignKeyName     = GetMatchingFromForeignKeyName(principalParent, currentForeignKeyName);
                    }
                    else
                    {
                        // If principal parent is null exit the iteration.
                        break;
                    }
                }

                originOfForeignKey = currentReferencedTypeName;
            }

            // Add to store
            Store.ForeignKeyOrigin.Add(key, originOfForeignKey);
            return(originOfForeignKey);
        }
        /// <summary>
        /// Synchronize keys of entity with matching entity.
        /// <remarks>
        /// In EntityFramework at one-to-one relationships, setting primary key
        /// of parent entity and setting state of entities to Unchanged or to Modified
        /// will also change primary key value of child entity.
        /// But vice-versa is not correct. This means that setting primary key value
        /// of child entity and setting state of entities to Unchanged or to Modified
        /// will not change primary key value of parent key, instead, it resets primary
        /// key value of child entity to its default value, (or to value of primary key
        /// of parent).
        /// This method is for synchronizing PKs of entity and PKs of matching entity and
        /// setting key of parent to key of child entities at one to relationships.
        /// </remarks>
        /// </summary>
        /// <param name="entity">Entity to set pk and parent key values.</param>
        /// <param name="matchingEntity">Found matching entity from underlying source.</param>
        public void SynchronizeKeys(
            TEntity entity,
            TEntity matchingEntity)
        {
            /*
             *
             *
             * Set keys of parent entity to value of child entity at one to one relations.
             *
             *
             */
            IEnumerable <RelationshipDetail> associatedRealtionships = GetForeignKeyDetails()
                                                                       .Where(m => m.ToDetails.ContainerClass.Equals(entity.GetType().Name) &&
                                                                              m.ToDetails.RelationshipMultiplicity == RelationshipMultiplicity.One);

            foreach (RelationshipDetail relationshipDetail in associatedRealtionships)
            {
                // Get parent property name from navigation details using information from foreign keys
                IGraphEntityTypeManager entityTypeManager = ContextFactory
                                                            .GetEntityTypeManager(relationshipDetail.ToDetails.ContainerClass);
                string parentPropertyName = entityTypeManager
                                            .GetNavigationDetail()
                                            .Relations
                                            .Where(n => n.PropertyTypeName.Equals(relationshipDetail.FromDetails.ContainerClass) &&
                                                   n.SourceMultiplicity == relationshipDetail.ToDetails.RelationshipMultiplicity &&
                                                   n.TargetMultiplicity == relationshipDetail.FromDetails.RelationshipMultiplicity)
                                            .Select(n => n.PropertyName)
                                            .FirstOrDefault();

                dynamic parent = entity.GetPropertyValue(parentPropertyName);

                if (parent != null)
                {
                    for (int i = 0; i < relationshipDetail.FromDetails.Keys.Count; i++)
                    {
                        // Get matching from and to key names
                        string fromKeyName = relationshipDetail.FromDetails.Keys[i];
                        string toKeyName   = relationshipDetail.ToDetails.Keys[i];

                        ReflectionExtensions.SetPropertyValue(parent,
                                                              fromKeyName,
                                                              matchingEntity.GetPropertyValue(toKeyName));
                    }
                }
            }

            /*
             *   Description:
             *     PK value shuold be changed by using
             *     context.Entry(entity).Property(pkName).CurrentValue = pkValue;
             *     becasue setting value by entity.pkName = pkValue will not synchronize
             *     it with dependent navigation properties automatically but prior method
             *     will do it.
             *     Primary key values of entity itself must be changed after
             *     principal parent keys has been synchronized. Because changing
             *     primary key value of entity using
             *     context.Entry(entity).Property(pkName).CurrentValue = pkValue
             *     set principal parent navigation property to null.
             */
            IEnumerable <string> primaryKeyNames = GetPrimaryKeys();

            DbEntityEntry current = Context.Entry(entity);

            foreach (string primaryKey in primaryKeyNames)
            {
                current.Property(primaryKey).CurrentValue =
                    matchingEntity.GetPropertyValue(primaryKey);
            }
        }
        /// <summary>
        /// Construct filter expression for entity.
        /// </summary>
        /// <param name="entity">Entity to construct filter expression for.</param>
        /// <param name="typeOfFilter">Type of filter expression.</param>
        /// <returns>Filter expression according to entity.</returns>
        public Expression <Func <TEntity, bool> > ConstructFilterExpression(
            TEntity entity,
            FilterType typeOfFilter)
        {
            Expression <Func <TEntity, bool> > filterExpression = null;
            IEnumerable <string> primaryKeyNames = GetPrimaryKeys();

            if (primaryKeyNames.Count() == 0)
            {
                throw new ArgumentException(string.Format(
                                                "'{0}' has no configured primary key.",
                                                typeof(TEntity).Name));
            }

            List <Expression>        equalityExpressions = new List <Expression>();
            IEnumerable <Expression> singleExpressionList;

            ParameterExpression parameterExp = Expression.Parameter(typeof(TEntity), "m");
            Expression          pkFilter     = null;
            Expression          ukFilter     = null;

            bool primaryKeysHaveDefaultValues = entity.HasDefaultValues(primaryKeyNames);

            if (!primaryKeysHaveDefaultValues &&
                typeOfFilter != FilterType.OnlyUnique)
            {
                // If primary keys do not have their default values
                // add this check to equlity expression list
                singleExpressionList = parameterExp
                                       .ConstructEqualityExpressions(
                    entity,
                    primaryKeyNames);

                pkFilter = singleExpressionList.ConstructAndChain();
            }

            if (typeOfFilter != FilterType.OnlyId &&
                (primaryKeysHaveDefaultValues ||
                 typeOfFilter != FilterType.IdOptionalUnique))
            {
                IEnumerable <PropertiesWithSource> uniqueProperties =
                    MappingStorage.Instance.UniqueProperties.Where(
                        m => m.SourceType.Equals(entity.GetType()));

                if (uniqueProperties.Count() > 0)
                {
                    foreach (PropertiesWithSource unique in uniqueProperties)
                    {
                        /*
                         ***********************************************************
                         * If any of current set of properties
                         * marked as unique is foreign key,
                         * has default value, and appropriate navigation property is not
                         * null and also origin of this foreign
                         * key has any store generated primary key then this
                         * uniqueness must be ignored.
                         * For example if PersonId (int) and DocumentType (short) has been
                         * set as composite unique in PersonDocument and
                         * if PersonId is foreign key to Person, which in its term has
                         * Primary key which is store generated and if there is no navigation
                         * property to Person from PersonDocument or PersonDocument.Person is not null
                         * then PersonId = 0 and DocumentType = 5 should not
                         * be treated as unique, because the real value of PersonId
                         * will be computed when data will be inserted.
                         ***********************************************************
                         */

                        IGraphEntityTypeManager uniqueSourceTypeManager = ContextFactory
                                                                          .GetEntityTypeManager(unique.SourceType.Name);

                        bool uniquenessMustBeIgnored = false;

                        var uniquePropertyNames = unique.Properties.Select(m => m.Name).ToList();
                        var uniqueForeignKeys   = uniqueSourceTypeManager
                                                  .GetForeignKeyDetails()
                                                  .Select(m => new
                        {
                            TargetClass = m.FromDetails.ContainerClass,
                            Keys        = m.ToDetails.Keys.Intersect(uniquePropertyNames)
                        })
                                                  .Where(m => m.Keys != null &&
                                                         m.Keys.Any());

                        NavigationDetail navigationDetailsOfCurrent = GetNavigationDetail();

                        // If unuque property is foreign key
                        if (uniqueForeignKeys != null &&
                            uniqueForeignKeys.Any())
                        {
                            foreach (var uniqueFk in uniqueForeignKeys)
                            {
                                // If foreign key has default value
                                if (uniqueFk.Keys.Any(u => entity.HasDefaultValue(u)))
                                {
                                    // Get navigation relation according to foreign key
                                    NavigationRelation navigationRelation = navigationDetailsOfCurrent
                                                                            .Relations
                                                                            .FirstOrDefault(r => r.Direction == NavigationDirection.From &&
                                                                                            r.PropertyTypeName.Equals(uniqueFk.TargetClass) &&
                                                                                            r.ToKeyNames.Intersect(uniqueFk.Keys).Any());

                                    // If corresponding navigation property is not null
                                    // or there is no such navigation property
                                    if (navigationRelation == null ||
                                        entity.GetPropertyValue(navigationRelation.PropertyName) != null)
                                    {
                                        bool foreignKeyHasStoreGeneratedPrimaryKey =
                                            uniqueFk.Keys.Any(k =>
                                        {
                                            // Get origin of foreign key and check
                                            // if it has store generated key.
                                            string foreignKeyOrigin = uniqueSourceTypeManager
                                                                      .GetOriginOfForeignKey(k);
                                            IGraphEntityTypeManager foreignKeyOriginTypeManger = ContextFactory
                                                                                                 .GetEntityTypeManager(foreignKeyOrigin);
                                            return(foreignKeyOriginTypeManger.HasStoreGeneratedKey());
                                        });

                                        // If origin of foreign key has store generated Primary key
                                        if (foreignKeyHasStoreGeneratedPrimaryKey)
                                        {
                                            uniquenessMustBeIgnored = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        // If uniqueness must be ignored then skip this iteration
                        if (uniquenessMustBeIgnored)
                        {
                            continue;
                        }

                        singleExpressionList = parameterExp
                                               .ConstructEqualityExpressions(
                            entity,
                            unique.Properties
                            .Select(m => m.Name).ToList());
                        equalityExpressions.Add(singleExpressionList.ConstructAndChain());
                    }

                    if (equalityExpressions.Count > 0)
                    {
                        ukFilter = equalityExpressions.ConstructOrChain();
                    }
                }
            }

            equalityExpressions.Clear();
            if (pkFilter != null)
            {
                equalityExpressions.Add(pkFilter);
            }

            if (ukFilter != null)
            {
                equalityExpressions.Add(ukFilter);
            }

            if (equalityExpressions.Count > 0)
            {
                Expression filterBaseExpression = typeOfFilter == FilterType.IdAndUnique
                    ? equalityExpressions.ConstructAndChain()
                    : equalityExpressions.ConstructOrChain();

                filterExpression = Expression.Lambda <Func <TEntity, bool> >(
                    filterBaseExpression, parameterExp);
            }

            return(filterExpression);
        }