public Expression FilterExpression(Tree tree, Expression dto, IClassCache cache)
        {
            if (tree.IsDirectPropertyAccess())
            {
                return(Expression.PropertyOrField(dto, tree.Root.Value.Text));
            }
            if (tree.IsPropertyAccess())
            {
                if (cache.GetOrAdd(dto.Type).CollectionNames.Contains(tree.Root.Value.Text))
                {
                    return(Expression.Empty());
                }
                return(FilterExpression(tree.Children.FirstOrDefault().Item2, Expression.PropertyOrField(dto, tree.Root.Value.Text), cache));
            }
            if (tree.Root.Value.Text == TextRepresentation.ValueComparison)
            {
                return(ComparisonExpression(tree, dto, cache));
            }
            if (tree.Root.Value.Text == TextRepresentation.LogicalComparison)
            {
                return(LogicalExpression(tree, dto, cache));
            }
            if (tree.IsStringFunction())
            {
                return(StringFunction(tree, dto, cache));
            }
            if (tree.Representation == TextRepresentation.BooleanValue)
            {
                return(BoolExpression(tree));
            }
            if (tree.Representation == TextRepresentation.NumberValue)
            {
                return(Expression.Constant(tree.Root.Value.Parsed, tree.Root.Value.Type));
            }
            if (tree.Representation == TextRepresentation.TextValue)
            {
                return(Expression.Constant(tree.Root.Value.Text.Substring(1, tree.Root.Value.Text.Length - 2)));
            }

            throw new NotImplementedException();
        }
예제 #2
0
        private static GraphSchema CreateFromGeneric <TDto>(IClassCache cache)
        {
            var vertices = new List <StatefulVertex <ClassInfo> >();
            var edges    = new List <Edge>();
            var types    = new HashSet <Type>();

            // Helper funcs
            // get the class info from type via the cache.
            ClassInfoUtility GetClassInfoFromType(Type t)
            {
                var hash = t.GetHashCode();

                if (cache.HasKey(hash))
                {
                    return(cache.Get(hash));
                }
                return(cache.GetOrAdd(t));
            }

            bool VerticesContainType(Type type) => vertices.Any(v => v.Vertex.Value.TypeId == type.GetHashCode());

            StatefulVertex <ClassInfo> GetOrAddVertex(Type type)
            {
                StatefulVertex <ClassInfo> vertex = null;

                if (VerticesContainType(type))
                {
                    vertex = vertices.First(v => v.Vertex.Value.TypeId == type.GetHashCode());
                }
                else
                {
                    vertex = new StatefulVertex <ClassInfo>(new Vertex(new ClassInfo(GetClassInfoFromType(type))), type);
                    vertices.Add(vertex);
                    types.Add(type);
                }
                return(vertex);
            }

            // initialize root.
            GetOrAddVertex(typeof(TDto));

            while (vertices.Any(v => v.Color != StatefulVertexStateType.Discovered))
            {
                var vertex = vertices.First(v => v.Color == StatefulVertexStateType.UnReached);
                vertex.Color = StatefulVertexStateType.Identified;

                var classInfo = GetClassInfoFromType(vertex.Type);
                var tentativeConnectionToType = new List <Edge>();

                void EstablishConnection(Type connectionToType, Property property)
                {
                    var toVertex = GetOrAddVertex(connectionToType);
                    var edge     = new Edge(vertex.Vertex as Vertex, toVertex.Vertex as Vertex, property);

                    if (!edges.Contains(edge))
                    {
                        edges.Add(edge);
                    }
                }

                foreach (var childNavigationProperty in vertex.Vertex.Value.Properties.Where(p => p.IsNavigationProperty))
                {
                    var type = classInfo.NavigationProperties.FirstOrDefault(x => x.Name == childNavigationProperty.Name)?.PropertyType;
                    if (type is null)
                    {
                        continue;
                    }
                    EstablishConnection(type, childNavigationProperty);
                }
                foreach (var childCollection in vertex.Vertex.Value.Properties.Where(p => p.IsCollection))
                {
                    var type = classInfo.Collections.FirstOrDefault(x => x.Name == childCollection.Name)?.PropertyType.GetGenericArguments()[0];
                    if (type is null)
                    {
                        continue;
                    }
                    EstablishConnection(type, childCollection);
                }

                vertex.Color = StatefulVertexStateType.Discovered;
            }

            return(new GraphSchema(vertices.Select(v => v.Vertex as Vertex), edges));
        }