public async Task TestInsertStyle()
        {
            Style s = new Style();

            s.Id   = (new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)).ToString("n");
            s.Name = "Concrete";
            s.Category.Add(Category.Bags, AcceptanceState.Suggested);
            s.Category.Add(Category.Headwear, AcceptanceState.Suggested);
            s.Category.Add(Category.Legging, AcceptanceState.Suggested);
            s.WaistLine.Add(new List <float>(new float[] { 0, 1, 2.2f }), AcceptanceState.Suggested);
            Color c = new Color();

            c.Id = (new Guid(100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90)).ToString("n");
            c.Hex.Add("ABC123", AcceptanceState.Suggested);
            Color c2 = new Color();

            c2.Id = (new Guid(50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40)).ToString("n");
            c2.Hex.Add("DEF987", AcceptanceState.Accepted);
            c.Template.Add(c2, AcceptanceState.RolledBack);
            s.Colors.Add(new List <Color>(new Color[] { c }), AcceptanceState.Suggested);
            s.Template = new Style()
            {
                Name     = "Template",
                Id       = (new Guid(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)).ToString("n"),
                Template = new Style()
                {
                    Id   = (new Guid(20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30)).ToString("n"),
                    Name = "Super Template"
                }
            };

            await s.Save(Client);

            var a = Neo4jSet <Style> .All(Client)
                    .Include(x => x.Template.Template)

                    .Include(x => x.Category.Start.Value)
                    .Include(x => x.Category.Start.Next.Value)
                    .Include(x => x.Category.Start.Next.Next.Value)

                    .Include(x => x.Colors)
                    .ThenInclude(x => x.Start)
                    .ThenInclude(x => x.Value)

                    .Include(x => x.Colors)
                    .ThenInclude(x => x.Start)
                    .ThenInclude(x => x.Next)
                    .ThenInclude(x => x.Value)
                    .ThenIncludeCollection(x => x, x => x.Hex)
                    .ThenInclude(x => x.Start)
                    .ThenInclude(x => x.Next)
                    .ThenInclude(x => x.Value)

                    //.Where(x => x.Id == (new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)).ToString("n"));
            ;

            LiveDbObject <Style>[] sOut = (await a.ReturnAsync()).ToArray();
            Style[] sCache = sOut.Select(x => x.BackingInstance).ToArray();

            LiveDbObject <Style> templt = sOut.Single(x =>
            {
                x.LiveMode = LiveObjectMode.Live;
                return(x.Get(y => y.Name).Result == "Template");
            });

            await templt.Call(x => x.Colors, (y, a) => y.Add(a, AcceptanceState.Suggested), new List <Color>() { c2 } as ICollection <Color>);

            LiveDbObject <Style> suprTemplt = sOut.Single(x =>
            {
                x.LiveMode = LiveObjectMode.Live;
                return(x.Get(y => y.Name).Result == "Super Template");
            });

            Color c3 = new Color();

            c3.Hex.Add("dahex", AcceptanceState.RolledBack);
            c3.Template.Add(c2, AcceptanceState.Finalized);
            await suprTemplt.Call(x => x.Colors, (y, a) => y.Add(a, AcceptanceState.Suggested), new List <Color>() { c, c2, c3 } as ICollection <Color>);
        }
示例#2
0
        public async Task <IEnumerable <LiveDbObject <T> > > ReturnAsync()
        {
            internalQ.Append("WITH ");
            for (int i = 0; i < PathCount; i++)
            {
                if (i > 0)
                {
                    internalQ.Append(" + ");
                }
                internalQ.Append($"collect(p{i})");
            }
            internalQ.Append($" AS paths{Environment.NewLine}");

            internalQ.Append($"UNWIND paths AS ret{Environment.NewLine}");
            internalQ = internalQ.AppendLine("RETURN ret as json");

            using (IDriver driver = clientFactory())
            {
                Query         q            = new Query(internalQ.ToString());
                IResultCursor resultCursor = await driver.AsyncSession().RunAsync(q);

                List <IRecord> results = await resultCursor.ToListAsync();

                Dictionary <string, INeo4jNode> nodeHeap = new Dictionary <string, INeo4jNode>();
                var raw = results.SelectMany(x =>
                {
                    var h = x["json"].As <IPath>();

                    List <INeo4jNode> nodes = h.Nodes.Select(a =>
                    {
                        INeo4jNode parentInstance;
                        if (!nodeHeap.TryGetValue(a["Id"].ToString(), out parentInstance))
                        {
                            Type parentType = ReflectionCache.BuildType(a["__type__"].As <string>());
                            parentInstance  = Activator.CreateInstance(parentType) as INeo4jNode;

                            ReflectionCache.Type typeData = ReflectionCache.GetTypeData(parentType);
                            foreach (KeyValuePair <string, object> k in a.Properties)
                            {
                                if (typeData.props.TryGetValue(k.Key, out ReflectionCache.Property prop))
                                {
                                    prop.PushValue(parentInstance, DBOps.Neo4jDecode(k.Value, prop.info.PropertyType));
                                }
                            }

                            nodeHeap.Add(a["Id"].ToString(), parentInstance);
                        }
                        return(parentInstance);
                    }).ToList();

                    return(h.Relationships
                           .Select((x, i) => (nodes[i].Id, nodes[i + 1].Id, x.Type))
                           .Cast <(string parentID, string childID, string relationship)>());
                }).ToList();

                var withProps = raw.Select(x => (x.Item1, x.Item2,
                                                 ReflectionCache.GetTypeData(nodeHeap[x.Item1]).props
                                                 .Where(y =>
                                                        y.Key == x.Item3
                                                        ||
                                                        (
                                                            y.Value.neo4JAttributes.Where(x => x is DbNameAttribute).Any()
                                                            &&
                                                            y.Value.neo4JAttributes.Select(x => x as DbNameAttribute).Where(x => x != null).FirstOrDefault()?.Name
                                                            ==
                                                            x.Item3
                                                        )
                                                        )
                                                 .SingleOrDefault()
                                                 .Value
                                                 )).ToList();

                var groupDedupe = withProps.GroupBy(x => x.Item1 + x.Item2).Select(x => x.First()).GroupBy(x => (x.Value, x.Item1));

                foreach (var g in groupDedupe)
                {
                    if (!g.Key.Value.isCollection)
                    {
                        var v = g.Single();
                        v.Item3.PushValue(nodeHeap[v.Item1], nodeHeap[v.Item2]);
                    }
                    else
                    {
                        System.Type     t    = g.Key.Value.info.PropertyType.GetGenericArguments()[0];
                        System.Type     lstT = typeof(List <>).MakeGenericType(t);
                        ConstructorInfo cotr = lstT.GetConstructors().Where(x => x.GetParameters().Length == 0).Single();

                        Type       enu   = typeof(Enumerable);
                        MethodInfo selct = enu.GetMethods()
                                           .Where(x => x.Name == "Select")
                                           .OrderBy(x => x.GetParameters().Length)
                                           .First()
                                           .MakeGenericMethod(typeof(string), t);
                        MethodInfo toLst = enu.GetMethods()
                                           .Where(x => x.Name == "ToList")
                                           .OrderBy(x => x.GetParameters().Length)
                                           .First()
                                           .MakeGenericMethod(t);

                        Type ndhpTyp = nodeHeap.GetType();

                        ParameterExpression ndhp = Expression.Parameter(ndhpTyp, "ndhp");
                        ParameterExpression ky   = Expression.Parameter(typeof(string), "ky");
                        var selExpr = Expression.Lambda(
                            Expression.Convert(Expression.Property(ndhp, "Item", ky), t),
                            ky
                            );

                        var expr = Expression.Lambda(
                            Expression.Call(
                                null,
                                toLst,
                                Expression.Call(
                                    null,
                                    selct,
                                    Expression.Constant(g.Select(x => x.Item2)),
                                    selExpr
                                    )
                                ),
                            ndhp
                            );

                        object psh = expr.Compile().DynamicInvoke(nodeHeap);

                        g.Key.Item1.PushValue(nodeHeap[g.Key.Item2],
                                              psh);
                    }
                }

                var ret = nodeHeap
                          .Select(x => x.Value)
                          .Where(x => x is T)
                          .Cast <T>()
                          .Distinct()
                          .Select(x => LiveDbObject <T> .Build(x, clientFactory, LiveObjectMode.LiveWrite | LiveObjectMode.DeferedRead))
                          .ToArray();

                return(ret);
            }
        }