Exemple #1
0
        public void ExecuteInMemory(Core.EntityCollectionBase target)
        {
            if (!target.IsLoaded)
            {
                return;
            }

            //if (IsExecutedInMemory)
            //    return;

            if (Relationship is not null && Relationship.Name != target.Relationship.Name)
            {
                return;
            }

            OGM?parent = target.ParentItem(this);

            if (parent is not null && target.Parent != parent)
            {
                return;
            }

            InMemoryLogic(target);

            IsExecutedInMemory = true;
        }
Exemple #2
0
        public void ExecuteInMemory(Core.EntityCollectionBase target)
        {
            if (!target.IsLoaded)
            {
                return;
            }

            if (Relationship != null)
            {
                if (Relationship.Name != target.Relationship.Name)
                {
                    return;
                }

                if (ActsOnSpecificParent())
                {
                    if (target.Parent != target.ParentItem(this))
                    {
                        return;
                    }
                }
            }
            else
            {
                Entity entity    = InItem.GetEntity();
                bool   shouldRun = false;
                if (target.ParentEntity == entity)
                {
                    shouldRun = true;
                    if (target.ForeignProperty != null && !target.ForeignProperty.Nullable)
                    {
                        return;
                    }
                }
                if (target.ForeignEntity == entity)
                {
                    shouldRun = true;
                    if (target.ParentProperty != null && !target.ParentProperty.Nullable)
                    {
                        return;
                    }
                }
                if (!shouldRun)
                {
                    return;
                }
            }
            InMemoryLogic(target);
        }
        public override IEnumerable <CollectionItem> Load(OGM parent, Core.EntityCollectionBase target)
        {
            Entity targetEntity = target.ForeignEntity;

            string[] nodeNames = target.Parent.GetEntity().GetDbNames("node");
            string[] outNames  = targetEntity.GetDbNames("out");

            if (nodeNames.Length > 1 && outNames.Length > 1)
            {
                throw new InvalidOperationException("Both ends are virtual entities, this is too expensive to query...");
            }

            List <string> fullMatch = new List <string>();

            for (int nodeIndex = 0; nodeIndex < nodeNames.Length; nodeIndex++)
            {
                for (int outIndex = 0; outIndex < outNames.Length; outIndex++)
                {
                    string pattern = string.Empty;
                    if (target.Direction == DirectionEnum.In)
                    {
                        pattern = "MATCH ({0})-[rel:{2}]->({3}) WHERE node.{1} = {{key}} RETURN out, rel";
                    }
                    else if (target.Direction == DirectionEnum.Out)
                    {
                        pattern = "MATCH ({0})<-[rel:{2}]-({3}) WHERE node.{1} = {{key}} RETURN out, rel";
                    }

                    string match = string.Format(pattern,
                                                 nodeNames[nodeIndex],
                                                 target.ParentEntity.Key.Name,
                                                 target.Relationship.Neo4JRelationshipType,
                                                 outNames[outIndex]);

                    fullMatch.Add(match);
                }
            }

            Dictionary <string, object?> parameters2 = new Dictionary <string, object?>();

            parameters2.Add("key", parent.GetKey());

            List <CollectionItem> items = new List <CollectionItem>();
            var result = Transaction.RunningTransaction.Run(string.Join(" UNION ", fullMatch), parameters2);

            foreach (var record in result)
            {
                RawNode node = record.Values["out"].As <RawNode>();
                if (node is null)
                {
                    continue;
                }

                OGM             item = ReadNode(parent, targetEntity, node);
                RawRelationship rel  = record.Values["rel"].As <RawRelationship>();

                DateTime?startDate = null;
                DateTime?endDate   = null;

                if (target.Relationship.IsTimeDependent)
                {
                    object?value;
                    if (rel.Properties.TryGetValue(target.Relationship.StartDate, out value))
                    {
                        startDate = Conversion <long, DateTime> .Convert((long)value);
                    }
                    if (rel.Properties.TryGetValue(target.Relationship.EndDate, out value))
                    {
                        endDate = Conversion <long, DateTime> .Convert((long)value);
                    }
                }

                items.Add(target.NewCollectionItem(parent, item, startDate, endDate));
            }

            return(items);
        }
        public override Dictionary <OGM, CollectionItemList> Load(IEnumerable <OGM> parents, Core.EntityCollectionBase target)
        {
            if (parents.Count() == 0)
            {
                return(new Dictionary <OGM, CollectionItemList>());
            }

            Dictionary <object, OGM> parentDict = new Dictionary <object, OGM>();

            foreach (OGM parent in parents)
            {
                object?key = parent.GetKey();
                if (key is null)
                {
                    continue;
                }

                if (!parentDict.ContainsKey(key))
                {
                    parentDict.Add(key, parent);
                }
            }

            string matchClause = string.Empty;

            if (target.Direction == DirectionEnum.In)
            {
                matchClause = "MATCH ({0})-[rel:{2}]->({3})";
            }
            else if (target.Direction == DirectionEnum.Out)
            {
                matchClause = "MATCH ({0})<-[rel:{2}]-({3})";
            }

            string whereClause  = " WHERE node.{1} in ({{keys}}) ";
            string returnClause = " RETURN node.{1} as ParentKey, out.{4} as ItemKey ";

            if (target.Relationship.IsTimeDependent)
            {
                returnClause = $" RETURN node.{{1}} as ParentKey, out.{{4}} as ItemKey, rel.{target.Relationship.StartDate} as StartDate, rel.{target.Relationship.EndDate} as EndDate";
            }

            Entity targetEntity = target.ForeignEntity;

            string[] nodeNames = target.Parent.GetEntity().GetDbNames("node");
            string[] outNames  = targetEntity.GetDbNames("out");

            if (nodeNames.Length > 1 && outNames.Length > 1)
            {
                throw new InvalidOperationException("Both ends are virtual entities, this is too expensive to query...");
            }

            List <string> fullMatch = new List <string>();

            for (int nodeIndex = 0; nodeIndex < nodeNames.Length; nodeIndex++)
            {
                for (int outIndex = 0; outIndex < outNames.Length; outIndex++)
                {
                    string match = string.Format(string.Concat(matchClause, whereClause, returnClause),
                                                 nodeNames[nodeIndex],
                                                 target.ParentEntity.Key.Name,
                                                 target.Relationship.Neo4JRelationshipType,
                                                 outNames[outIndex],
                                                 targetEntity.Key.Name);

                    fullMatch.Add(match);
                }
            }

            Dictionary <string, object?> parameters = new Dictionary <string, object?>();

            parameters.Add("keys", parents.Select(item => item.GetKey()).ToArray());

            if (parents.Any(parent => parent.GetEntity() != target.Parent.GetEntity()))
            {
                throw new InvalidOperationException("This code should only load collections of the same concrete parent class.");
            }

            var result = Transaction.RunningTransaction.Run(string.Join(" UNION ", fullMatch), parameters);
            List <RelationshipIndex> indexCache = new List <RelationshipIndex>();

            foreach (var record in result)
            {
                DateTime?startDate = null;
                DateTime?endDate   = null;

                if (target.Relationship.IsTimeDependent)
                {
                    startDate = (record.Values["StartDate"] != null) ? Conversion <long, DateTime> .Convert((long)record.Values["StartDate"].As <long>()) : (DateTime?)null;

                    endDate = (record.Values["EndDate"] != null) ? Conversion <long, DateTime> .Convert((long)record.Values["EndDate"].As <long>()) : (DateTime?)null;
                }

                indexCache.Add(new RelationshipIndex(record.Values["ParentKey"].As <object>(), record.Values["ItemKey"].As <object>(), startDate, endDate));
            }

            Dictionary <object, List <RawNode> > itemsCache = Load(targetEntity, indexCache.Select(r => r.TargetEntityKey));

            List <CollectionItem> items = new List <CollectionItem>();

            foreach (var index in indexCache)
            {
                OGM parent = parentDict[index.SourceEntityKey];
                foreach (var item in itemsCache[index.TargetEntityKey])
                {
                    OGM?child = ReadNode(parent, targetEntity, item);
                    items.Add(target.NewCollectionItem(parent, child, index.StartDate, index.EndDate));
                }
            }

            return(CollectionItemList.Get(items));
        }
Exemple #5
0
 protected abstract void InMemoryLogic(Core.EntityCollectionBase target);
        public override Dictionary <OGM, CollectionItemList> Load(IEnumerable <OGM> parents, Core.EntityCollectionBase target)
        {
            if (parents.Count() == 0)
            {
                return(new Dictionary <OGM, CollectionItemList>());
            }

            HashSet <OGM> parentHashset = new HashSet <OGM>(parents);

            string matchClause = string.Empty;

            if (target.Direction == DirectionEnum.In)
            {
                matchClause = "MATCH ({0})-[rel:{2}]->({3})";
            }
            else if (target.Direction == DirectionEnum.Out)
            {
                matchClause = "MATCH ({0})<-[rel:{2}]-({3})";
            }

            string whereClause  = " WHERE node.{1} in ($keys) ";
            string returnClause = " RETURN node as Parent, out as Item ";

            if (target.Relationship.IsTimeDependent)
            {
                returnClause = $" RETURN node as Parent, out as Item, rel.{target.Relationship.StartDate} as StartDate, rel.{target.Relationship.EndDate} as EndDate";
            }

            Entity targetEntity = target.ForeignEntity;

            string[] nodeNames = target.Parent.GetEntity().GetDbNames("node");
            string[] outNames  = targetEntity.GetDbNames("out");

            if (nodeNames.Length > 1 && outNames.Length > 1)
            {
                throw new InvalidOperationException("Both ends are virtual entities, this is too expensive to query...");
            }

            List <string> fullMatch = new List <string>();

            for (int nodeIndex = 0; nodeIndex < nodeNames.Length; nodeIndex++)
            {
                for (int outIndex = 0; outIndex < outNames.Length; outIndex++)
                {
                    string match = string.Format(string.Concat(matchClause, whereClause, returnClause),
                                                 nodeNames[nodeIndex],
                                                 target.ParentEntity.Key.Name,
                                                 target.Relationship.Neo4JRelationshipType,
                                                 outNames[outIndex]);

                    fullMatch.Add(match);
                }
            }

            Dictionary <string, object?> parameters = new Dictionary <string, object?>();

            parameters.Add("keys", parents.Select(item => item.GetKey()).ToArray());

            if (parents.Any(parent => parent.GetEntity() != target.Parent.GetEntity()))
            {
                throw new InvalidOperationException("This code should only load collections of the same concrete parent class.");
            }

            string cypher = string.Join(" UNION ", fullMatch);
            var    result = Transaction.RunningTransaction.Run(cypher, parameters);
            List <CollectionItem> items = new List <CollectionItem>();

            foreach (var record in result)
            {
                DateTime?startDate = null;
                DateTime?endDate   = null;

                if (target.Relationship.IsTimeDependent)
                {
                    startDate = (record.Values["StartDate"] is not null) ? Conversion <long, DateTime> .Convert((long)record.Values["StartDate"].As <long>()) : (DateTime?)null;

                    endDate = (record.Values["EndDate"] is not null) ? Conversion <long, DateTime> .Convert((long)record.Values["EndDate"].As <long>()) : (DateTime?)null;
                }
                OGM?parent = target.Parent.GetEntity().Map(record.Values["Parent"].As <RawNode>(), NodeMapping.AsWritableEntity);
                OGM?item   = targetEntity.Map(record.Values["Item"].As <RawNode>(), NodeMapping.AsWritableEntity);

                if (parent is null || item is null)
                {
                    throw new NotSupportedException("The cypher query expected to have a parent node and a child node.");
                }

                if (parentHashset.Contains(parent))
                {
                    items.Add(target.NewCollectionItem(parent, item, startDate, endDate));
                }
            }

            return(CollectionItemList.Get(items));
        }
Exemple #7
0
 public abstract Dictionary <OGM, CollectionItemList> Load(IEnumerable <OGM> parents, Core.EntityCollectionBase target);