Beispiel #1
0
        /// <summary>
        /// Get entity type
        /// </summary>
        /// <param name="relation">Relation name</param>
        /// <param name="end1">Entity relation END 1</param>
        /// <returns>Type</returns>
        public string GetEntityType(string relation, ModelEntity end1)
        {
            var chain = GetRelationEntityChain(
                relation,
                end1
                );

            return
                ((chain.RelationType == ModelRelationEntityChainType.ManyToMany ||
                  chain.RelationType == ModelRelationEntityChainType.OneToMany)
                    ? "BaseEntityCollection<" + chain.End2.Name + ">"
                    : chain.End2.Name);
        }
Beispiel #2
0
        /// <summary>
        /// Get relation entity chain
        /// </summary>
        /// <param name="relation">Relation name</param>
        /// <param name="end1">Entity relation END 1</param>
        /// <returns>Entity chain</returns>
        public ModelRelationEntityChain GetRelationEntityChain(string relation, ModelEntity end1)
        {
            var chain = new ModelRelationEntityChain();

            chain.End1 = end1;

            #region Seek chain
            var path = relation
                       .Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            if (path.Length != 2)
            {
                throw new ModelException("Malformed relation");
            }
            chain.Parent = Entities.FirstOrDefault(
                x => x.Name.Equals(path[0], StringComparison.InvariantCultureIgnoreCase));
            if (chain.Parent == null)
            {
                throw new ModelException("Unknown entity \"" + path[0] + "\"");
            }
            chain.Relation = chain.Parent.Relations.FirstOrDefault(
                x => x.Name.Equals(path[1], StringComparison.InvariantCultureIgnoreCase));
            if (chain.Relation == null)
            {
                throw new ModelException("Relation \"" + path[1] + "\" cannot be found on \"" + path[0] + "\"");
            }
            chain.End2 = Entities.FirstOrDefault(
                x => x.Name.Equals(chain.Relation.EntityName, StringComparison.InvariantCultureIgnoreCase));
            if (chain.End2 == null)
            {
                throw new ModelException("Referenced entity \"" + chain.Relation.EntityName +
                                         "\" cannot be found by \"" + chain.Relation.Name + "\"");
            }

            // @if END 1 is the same as END 2 then relation parent should become the new END 2;
            if (chain.End1 == chain.End2)
            {
                chain.End2 =
                    chain.Parent;
            }
            #endregion

            #region Find relation type
            if (chain.End1 != chain.Parent &&
                chain.End1 != chain.End2 && chain.Parent != chain.End2)
            {
                chain.RelationType = ModelRelationEntityChainType.ManyToMany;
                if (!chain.Parent.Fields.Where(
                        x => string.IsNullOrEmpty(x.Relation)).All(x => x.IsKey == true))
                {
                    chain.End2         = chain.Parent;
                    chain.RelationType = ModelRelationEntityChainType.ManyToOne;
                }
            }
            else
            {
                var relationEnd1KeyFields = new Dictionary <string, ModelField>(StringComparer.InvariantCultureIgnoreCase);
                foreach (var item in chain.Relation.Fields)
                {
                    relationEnd1KeyFields.Add(item.ParentColumnName,
                                              chain.End1.Fields.FirstOrDefault(x =>
                                                                               x.ColumnName != null &&
                                                                               x.ColumnName.Equals(item.ParentColumnName, StringComparison.InvariantCultureIgnoreCase))
                                              );
                }
                var relationEnd2KeyFields = new Dictionary <string, ModelField>(StringComparer.InvariantCultureIgnoreCase);
                foreach (var item in chain.Relation.Fields)
                {
                    relationEnd2KeyFields.Add(item.ChildColumnName,
                                              chain.End2.Fields.FirstOrDefault(x =>
                                                                               x.ColumnName != null &&
                                                                               x.ColumnName.Equals(item.ChildColumnName, StringComparison.InvariantCultureIgnoreCase))
                                              );
                }

                var numOfKeysOnEnd1 = chain.End1.Fields.Count(x => x.IsKey == true);
                var numOfKeysOnEnd2 = chain.End2.Fields.Count(x => x.IsKey == true);
                if (numOfKeysOnEnd1 == numOfKeysOnEnd2 &&
                    relationEnd1KeyFields.Count == relationEnd2KeyFields.Count &&
                    numOfKeysOnEnd1 == relationEnd1KeyFields.Count)
                {
                    chain.RelationType = ModelRelationEntityChainType.OneToOne;
                }
                else if (numOfKeysOnEnd1 == relationEnd1KeyFields.Count)
                {
                    chain.RelationType = ModelRelationEntityChainType.OneToMany;
                }
                else if (numOfKeysOnEnd2 == relationEnd2KeyFields.Count)
                {
                    chain.RelationType = ModelRelationEntityChainType.ManyToOne;
                }
            }
            #endregion

            return(chain);
        }
Beispiel #3
0
        /// <summary>
        /// Get entity relation hierarchy
        /// </summary>
        /// <param name="rootEntity">Root entity</param>
        /// <returns>Entity hierarchy</returns>
        public List <ModelEntity> GetEntityRelationHierarchy(ModelEntity rootEntity)
        {
            var bag = new Dictionary <ModelEntity, HashSet <ModelEntity> >();
            var res = new List <ModelEntity>();

            #region Collect dependencies
            Action <ModelEntity> depCollAct = null;
            depCollAct =
                new Action <ModelEntity>((currEntity) =>
            {
                if (bag.ContainsKey(currEntity))
                {
                    return;
                }
                bag.Add(currEntity, new HashSet <ModelEntity>());
                foreach (var field in
                         currEntity.Fields.Where(x => !string.IsNullOrEmpty(x.Relation)))
                {
                    var chain = GetRelationEntityChain(
                        field.Relation,
                        currEntity
                        );
                    switch (chain.RelationType)
                    {
                    case ModelRelationEntityChainType.ManyToMany:
                        depCollAct(chain.Parent);
                        break;

                    case ModelRelationEntityChainType.ManyToOne:
                        bag[currEntity].Add(chain.End2);
                        depCollAct(chain.End2);
                        break;

                    default:
                        depCollAct(chain.End2);
                        break;
                    }
                }
            });
            depCollAct(rootEntity);
            #endregion

            #region Sort by dependencies
            while (bag.Count > 0)
            {
                var currEntity =
                    bag.FirstOrDefault(x => x.Value.Count == 0);
                if (currEntity.Key == null)
                {
                    currEntity = bag.First();
                }

                bag.Remove(currEntity.Key);

                foreach (var entity in bag)
                {
                    entity.Value.Remove(currEntity.Key);
                }

                res.Add(currEntity.Key);
            }
            #endregion

            return(res);
        }