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>); }
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); } }