private Expression LogicalExpression(Tree tree, Expression dto, IClassCache cache)
        {
            var children = new List <Graph.ITuple <Edge, Tree> >(tree.Children);

            if (children.Count != 3)
            {
                return(null);
            }

            var left  = FilterExpression(children[0].Item2, dto, cache);
            var right = FilterExpression(children[2].Item2, dto, cache);

            var compareText = tree.Children.ToList()[1].Item2.Root.Value.Text.ToLower();

            bool compare(string expected) => compareText == expected.ToLower();

            if (compare("and"))
            {
                return(Expression.And(left, right));
            }
            if (compare("or"))
            {
                return(Expression.Or(left, right));
            }

            throw new NotImplementedException();
        }
Esempio n. 2
0
        public Database(Configuration configuration)
        {
            this.connectionString = configuration.ConnectionString;
            if (this.connectionString == null)
            {
                throw new Exception("Configuration.ConnectionString is missing");
            }

            if (!this.connectionString.ToLowerInvariant().Contains(FullUriKey))
            {
                throw new Exception("Configuration.ConnectionString has no FullUri");
            }

            this.isInMemory = this.connectionString.ToLowerInvariant().Contains(InMemoryKey);

            if (this.isInMemory && !this.connectionString.ToLowerInvariant().Contains(SharedCacheKey))
            {
                throw new Exception("Configuration.ConnectionString is in memory and FullUri has no \"?cache=shared\" parameter");
            }

            if (this.isInMemory)
            {
                this.id = Guid.NewGuid().ToString("N").ToLowerInvariant();
            }
            else
            {
                var connectionStringBuilder = new SQLiteConnectionStringBuilder(this.connectionString);
                var dataSource = connectionStringBuilder.FullUri;
                if (dataSource.Contains(UriQueySeparator))
                {
                    dataSource = dataSource.Substring(0, dataSource.IndexOf(UriQueySeparator, StringComparison.Ordinal));
                }

                this.id = Path.GetFileName(dataSource);
            }

            this.objectFactory = configuration.ObjectFactory;
            if (this.objectFactory == null)
            {
                throw new Exception("Configuration.ObjectFactory is missing");
            }

            this.roleCache      = configuration.RoleCache ?? new RoleCache();
            this.classCache     = configuration.ClassCache ?? new ClassCache();
            this.commandTimeout = configuration.CommandTimeout ?? 30;
            this.isolationLevel = configuration.IsolationLevel ?? IsolationLevel.Serializable;
            this.autoIncrement  = configuration.AutoIncrement ?? false;

            this.mapping = new Mapping(this);

            if (this.isInMemory)
            {
                this.inMemoryConnection = new SQLiteConnection(this.ConnectionString);
                this.inMemoryConnection.Open();
            }

            this.idSequence = IdSequence.GetOrCreate(this);
        }
Esempio n. 3
0
        public Database(Configuration configuration)
        {
            this.connectionString = configuration.ConnectionString;
            if (this.connectionString == null)
            {
                throw new Exception("Configuration.ConnectionString is missing");
            }

            var connectionStringBuilder = new SqlConnectionStringBuilder(this.connectionString);
            var applicationName         = connectionStringBuilder.ApplicationName.Trim();

            if (!string.IsNullOrWhiteSpace(applicationName))
            {
                this.Id = applicationName;
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(connectionStringBuilder.InitialCatalog))
                {
                    this.Id = connectionStringBuilder.InitialCatalog.ToLowerInvariant();
                }
                else
                {
                    using (this.connection = new SqlConnection(this.connectionString))
                    {
                        this.connection.Open();
                        this.Id = this.connection.Database.ToLowerInvariant();
                    }
                }
            }

            this.objectFactory = configuration.ObjectFactory;
            if (this.objectFactory == null)
            {
                throw new Exception("Configuration.ObjectFactory is missing");
            }

            if (!this.objectFactory.MetaPopulation.IsValid)
            {
                throw new ArgumentException("Domain is invalid");
            }

            this.Mapping        = new Mapping(this);
            this.roleCache      = configuration.RoleCache ?? new RoleCache();
            this.classCache     = configuration.ClassCache ?? new ClassCache();
            this.CommandTimeout = configuration.CommandTimeout ?? 30;
            this.IsolationLevel = configuration.IsolationLevel ?? IsolationLevel.Snapshot;
            this.SchemaName     = configuration.SchemaName ?? "allors";
            this.useViews       = configuration.UseViews ?? true;
        }
Esempio n. 4
0
        public QueryParser(Parameters parameters, GraphSchema graph, IClassCache cache)
        {
            IsParsed = false;

            ClassProperties = graph.Vertices
                              .Select(v => v.Value.Properties)
                              .SelectMany(x => x).Select(x => x.Name)
                              .Distinct();

            OrderBy = new OrderByClauseParser <TRootVertex>(x => _GetTokens(x), parameters.OrderBy, graph, TermHelper.OrderByTerms);
            Select  = new SelectClauseParser <TRootVertex>(x => _GetTokens(x), parameters.Select, graph, TermHelper.SelectTerms);
            Filter  = new FilterClauseParser <TRootVertex>(x => _GetTokens(x), parameters.Filter, TermHelper.FilterTerms);
            Expand  = new ExpandClauseParser <TRootVertex>(x => _GetTokens(x), parameters.Expand, graph, Select, Filter, TermHelper.ExpandTerms);

            _Graph = graph;
            Cache  = cache;

            Parse();
        }
        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();
        }
Esempio n. 6
0
        public NoDataQuery(
            IQueryable <TDto> source,
            Parameters parameters,
            IClassCache cache,
            IEnumerable <ITuple <PathToProperty, SortDirection> > orderBy,
            Expression selectExpandExpression,
            Expression filterExpression,
            ParameterExpression dtoParameterExpression,
            QueryTree selectionTree)
        {
            Source     = source;
            Parameters = parameters;

            SelectionTree          = selectionTree;
            SelectExpandExpression = selectExpandExpression;
            DtoExpression          = dtoParameterExpression;
            FilterExpression       = filterExpression;
            OrderByPath            = orderBy;

            Cache = cache;
        }
Esempio n. 7
0
        private static IEnumerable <MemberBinding> ExpansionMemberBindings(Expression dto, QueryTree tree, IClassCache cache)
        {
            var vertex        = tree.Root;
            var classInfo     = cache.Get(vertex.Value.TypeId);
            var outgoingEdges = tree.Children.Select(c => c.Item1);

            // Bind all the non-expandable types.
            foreach (var prop in BindingsForProperties(vertex, cache, dto))
            {
                yield return(prop);
            }

            // navigation properties
            foreach (var prop in vertex.Value.Properties.Where(x => x.IsNavigationProperty))
            {
                var propertyInfo     = classInfo.NavigationProperties.First(x => x.Name == prop.Name);
                var navigationVertex = outgoingEdges.FirstOrDefault(x => x.Value.Name == prop.Name).To;
                var navigationTree   = tree.Children.First(c => c.Item1.To == navigationVertex).Item2;
                yield return(Expression.Bind(propertyInfo, GetExpandExpression(Expression.PropertyOrField(dto, prop.Name), navigationTree, cache)));
            }

            // // collections
            foreach (var prop in vertex.Value.Properties.Where(x => x.IsCollection))
            {
                var propertyInfo = classInfo.Collections.First(x => x.Name == prop.Name);

                if (!propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GenericTypeArguments.Length != 1)
                {
                    continue;
                }

                var collectionVertex = outgoingEdges.Single(x => x.Value.Name == prop.Name).To;
                var navigationTree   = tree.Children.First(c => c.Item1.To == collectionVertex).Item2;
                var collectionType   = cache.GetTypeFromId(collectionVertex.Value.TypeId);

                var listType = typeof(List <>).MakeGenericType(collectionType);

                var childrenParameter = Expression.Parameter(collectionType, prop.Name);
                var childrenProperty  = Expression.PropertyOrField(dto, prop.Name);
                var select            = ExpressionBuilder.BuildSelectExpression(collectionType,
                                                                                childrenProperty,
                                                                                childrenParameter, GetExpandExpression(childrenParameter, navigationTree, cache));
                var list = Expression.Condition(
                    Expression.Equal(childrenProperty, Expression.Constant(null)),
                    Expression.New(listType.GetConstructor(Array.Empty <Type>()), Array.Empty <Expression>()),
                    Expression.New(listType.GetConstructor(new Type[] { listType }), select)
                    );
                yield return(Expression.Bind(propertyInfo, list));
            }
        }
Esempio n. 8
0
 public static Expression GetExpandExpression(Expression dto, QueryTree tree, IClassCache cache) => BindingExpression(dto, ExpansionMemberBindings(dto, tree, cache));
Esempio n. 9
0
        // private static ICacheForever<int, List<MemberBinding>> _propertyBindingCache = new DictionaryCache<int, List<MemberBinding>>();
        private static IEnumerable <MemberBinding> BindingsForProperties(QueryVertex info, IClassCache cache, Expression dto)
        {
            // var hash = (info.GetHashCode() + properties.Sum(x => x.PropertyType.GetHashCode()) + dto.GetHashCode()) % int.MaxValue;
            // return _propertyBindingCache.GetOrAdd(info.Value.TypeId, () =>
            // {
            var result    = new List <MemberBinding>();
            var classInfo = cache.ClassFromTypeId(info.Value.TypeId);

            foreach (var prop in info.Value.Properties.Where(x => x.IsPrimitive))
            {
                result.Add(Expression.Bind(classInfo.NonExpandableProperties.First(x => x.Name == prop.Name), Expression.PropertyOrField(dto, prop.Name)));
            }
            return(result);
            // });
        }
Esempio n. 10
0
 public GraphTests()
 {
     cache = new ClassCache();
 }
        private Expression ComparisonExpression(Tree tree, Expression dto, IClassCache cache)
        {
            var children = new List <Graph.ITuple <Edge, Tree> >(tree.Children);

            if (children.Count != 3)
            {
                return(null);
            }

            var left  = FilterExpression(children[0].Item2, dto, cache);
            var right = FilterExpression(children[2].Item2, dto, cache);

            if (left.Type != right.Type && IsNumberType(left.Type) && IsNumberType(right.Type))
            {
                var lIndex      = IndexFromType(left.Type);
                var rIndex      = IndexFromType(right.Type);
                var largerIndex = Math.Max(lIndex, rIndex);
                if (lIndex != largerIndex)
                {
                    left = Expression.Convert(left, TypeFromIndex(largerIndex));
                }
                if (rIndex != largerIndex)
                {
                    right = Expression.Convert(right, TypeFromIndex(largerIndex));
                }
            }

            Expression doComparison()
            {
                var compareText = tree.Children.ToList()[1].Item2.Root.Value.Text.ToLower();

                bool Compare(string expected) => compareText == expected.ToLower();

                // eq, ne, gt, ge, lt ,le
                if (Compare("eq"))
                {
                    return(Expression.Equal(left, right));
                }
                else if (Compare("ne"))
                {
                    return(Expression.NotEqual(left, right));
                }
                else if (Compare("gt"))
                {
                    return(Expression.GreaterThan(left, right));
                }
                else if (Compare("ge"))
                {
                    return(Expression.GreaterThanOrEqual(left, right));
                }
                else if (Compare("lt"))
                {
                    return(Expression.LessThan(left, right));
                }
                else if (Compare("le"))
                {
                    return(Expression.LessThanOrEqual(left, right));
                }
                throw new NotImplementedException();
            }

            Expression IsChildPropertyAccessNull(Tree child, Expression parentClass)
            {
                if (child.IsPropertyAccess())
                {
                    Expression conditional(Expression propertyExpression)
                    {
                        var nullExpr = Expression.Constant(null);

                        if (propertyExpression.Type.IsValueType)
                        {
                            return(null);
                        }
                        return(Expression.NotEqual(propertyExpression, nullExpr));
                    }

                    if (!child.IsDirectPropertyAccess())
                    {
                        var subPropertyAccessCheck = IsChildPropertyAccessNull(child.Children.First().Item2, Expression.PropertyOrField(parentClass, child.Root.Value.Text));
                        if (subPropertyAccessCheck is null)
                        {
                            return(conditional(parentClass));
                        }
                        return(Expression.AndAlso(conditional(parentClass), subPropertyAccessCheck));
                    }
                    else
                    {
                        return(conditional(parentClass));
                    }
                }
                return(null);
            }

            var leftNullCheck  = IsChildPropertyAccessNull(children[0].Item2, dto);
            var rightNullCheck = IsChildPropertyAccessNull(children[1].Item2, dto);

            if (leftNullCheck == null && rightNullCheck == null)
            {
                return(doComparison());
            }
            if (leftNullCheck != null && rightNullCheck == null)
            {
                return(Expression.AndAlso(leftNullCheck, doComparison()));
            }
            if (leftNullCheck == null && rightNullCheck != null)
            {
                return(Expression.AndAlso(rightNullCheck, doComparison()));
            }
            return(Expression.AndAlso(Expression.AndAlso(leftNullCheck, rightNullCheck), doComparison()));
        }
        private Expression StringFunction(Tree tree, Expression dto, IClassCache cache)
        {
            var strFunction = tree.GetStringFunction();

            if (strFunction == TextRepresentation.StrLength)
            {
                // eval child expr
                var childExpression = FilterExpression(tree.Children.First().Item2, dto, cache);
                // fail if type isn't a string
                if (childExpression.Type != typeof(string))
                {
                    throw new ArgumentException("Tried to get length of non string property.");
                }
                return(Expression.Property(childExpression, nameof(string.Length)));
            }
            if (strFunction == TextRepresentation.StrToLower ||
                strFunction == TextRepresentation.StrToUpper ||
                strFunction == TextRepresentation.StrTrim)
            {
                // eval child expr
                var child1Expression = FilterExpression(tree.Children.First().Item2, dto, cache);
                // fail if type isn't a string
                if (child1Expression.Type != typeof(string))
                {
                    throw new ArgumentException("Can't check function endswith with argument of a non-string type.");
                }

                var methodName = "";

                if (strFunction == TextRepresentation.StrToUpper)
                {
                    methodName = nameof(string.ToUpper);
                }
                else if (strFunction == TextRepresentation.StrToLower)
                {
                    methodName = nameof(string.ToLower);
                }
                else if (strFunction == TextRepresentation.StrTrim)
                {
                    methodName = nameof(string.Trim);
                }

                var method = typeof(string).GetMethod(methodName, Array.Empty <Type>());

                return(Expression.Call(child1Expression, method));
            }
            if (strFunction == TextRepresentation.StrEndsWith ||
                strFunction == TextRepresentation.StrStartsWith ||
                strFunction == TextRepresentation.StrIndexOf ||
                strFunction == TextRepresentation.StrContains)
            {
                // eval child expr
                var child1Expression = FilterExpression(tree.Children.First().Item2, dto, cache);
                var child2Expression = FilterExpression(tree.Children.Last().Item2, dto, cache);
                // fail if types aren't a string
                if (child1Expression.Type != typeof(string) || child2Expression.Type != typeof(string))
                {
                    throw new ArgumentException("Can't check function endswith with argument of a non-string type.");
                }

                var methodName = "";

                if (strFunction == TextRepresentation.StrEndsWith)
                {
                    methodName = nameof(string.EndsWith);
                }
                else if (strFunction == TextRepresentation.StrStartsWith)
                {
                    methodName = nameof(string.StartsWith);
                }
                else if (strFunction == TextRepresentation.StrIndexOf)
                {
                    methodName = nameof(string.IndexOf);
                }
                else if (strFunction == TextRepresentation.StrContains)
                {
                    methodName = nameof(string.Contains);
                }

                var method = typeof(string).GetMethod(methodName, new[] { typeof(string) });

                return(Expression.Call(child1Expression, method, child2Expression));
            }
            if (strFunction == TextRepresentation.StrReplace)
            {
                var childList = tree.Children.ToList();
                // eval child expr
                var child1Expression = FilterExpression(childList[0].Item2, dto, cache);
                var child2Expression = FilterExpression(childList[1].Item2, dto, cache);
                var child3Expression = FilterExpression(childList[2].Item2, dto, cache);
                // fail if types aren't a string
                if (child1Expression.Type != typeof(string) || child2Expression.Type != typeof(string) || child3Expression.Type != typeof(string))
                {
                    throw new ArgumentException("Can't check function endswith with argument of a non-string type.");
                }

                var methodName = nameof(string.Replace);

                var method = typeof(string).GetMethod(methodName, new[] { typeof(string), typeof(string) });

                return(Expression.Call(child1Expression, method, child2Expression, child3Expression));
            }
            if (strFunction == TextRepresentation.StrConcat)
            {
                var childList = tree.Children.ToList();
                // eval child expr
                var child1Expression = FilterExpression(childList[0].Item2, dto, cache);
                var child2Expression = FilterExpression(childList[1].Item2, dto, cache);
                // fail if types aren't a string
                if (child1Expression.Type != typeof(string) || child2Expression.Type != typeof(string))
                {
                    throw new ArgumentException("Can't check function endswith with argument of a non-string type.");
                }

                string methodName = null;

                if (strFunction == TextRepresentation.StrConcat)
                {
                    methodName = nameof(string.Concat);
                }

                var method = typeof(string).GetMethod(methodName, new[] { typeof(string), typeof(string) });

                return(Expression.Call(method, child1Expression, child2Expression));
            }
            if (strFunction == TextRepresentation.StrSubString)
            {
                var childList = tree.Children.ToList();
                // eval child expr
                var child1Expression = FilterExpression(childList[0].Item2, dto, cache);

                var integerArgs = new List <Expression>(childList.Count - 1);
                // if (childList.Count == 2)
                //     integerArgs.Add(Expression.Constant(0, typeof(int)));
                for (var i = 1; i < childList.Count; ++i)
                {
                    integerArgs.Add(Expression.Convert(FilterExpression(childList[i].Item2, dto, cache), typeof(int)));
                }

                // fail if types aren't a string
                if (child1Expression.Type != typeof(string))
                {
                    throw new ArgumentException("Can't check function endswith with argument of a non-string type.");
                }

                if (!integerArgs.All(x => x.Type == typeof(int) || x.Type == typeof(long)))
                {
                    throw new ArgumentException("Argument not an integer for substring function.");
                }

                var method = typeof(string).GetMethod(nameof(string.Substring), integerArgs.Select(x => x.Type).ToArray());

                return(Expression.Call(child1Expression, method, integerArgs));
            }

            throw new NotImplementedException("String function is not implemented: " + strFunction);
        }
Esempio n. 13
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));
        }
Esempio n. 14
0
 public CacheAndGraphFixture()
 {
     cache = new ClassCache();
     graph = GraphSchema.Cache <TDto> .Graph;
 }
Esempio n. 15
0
        public Database(Configuration configuration)
        {
            this.connectionString = configuration.ConnectionString;
            if (this.connectionString == null)
            {
                throw new Exception("Configuration.ConnectionString is missing");
            }

            var connectionStringBuilder = new SqlConnectionStringBuilder(this.connectionString);
            var applicationName = connectionStringBuilder.ApplicationName.Trim();
            if (!string.IsNullOrWhiteSpace(applicationName))
            {
                this.id = applicationName;
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(connectionStringBuilder.InitialCatalog))
                {
                    this.id = connectionStringBuilder.InitialCatalog.ToLowerInvariant();
                }
                else
                {
                    using (this.connection = new SqlConnection(this.connectionString))
                    {
                        this.connection.Open();
                        this.id = this.connection.Database.ToLowerInvariant();
                    }
                }
            }

            this.objectFactory = configuration.ObjectFactory;
            if (this.objectFactory == null)
            {
                throw new Exception("Configuration.ObjectFactory is missing");
            }

            if (!this.objectFactory.MetaPopulation.IsValid)
            {
                throw new ArgumentException("Domain is invalid");
            }

            this.objectIds = configuration.ObjectIds ?? new ObjectIdsInteger();
            this.roleCache = configuration.RoleCache ?? new RoleCache();
            this.classCache = configuration.ClassCache ?? new ClassCache();
            this.commandTimeout = configuration.CommandTimeout ?? 30;
            this.isolationLevel = configuration.IsolationLevel ?? IsolationLevel.Snapshot;
            this.schemaName = configuration.SchemaName ?? "allors";
            this.useViews = configuration.UseViews ?? true;

            if (this.ObjectIds is ObjectIdsInteger)
            {
                this.mapping = new MappingInteger(this);
            }
            else if (this.ObjectIds is ObjectIdsLong)
            {
                this.mapping = new MappingLong(this);
            }
            else
            {
                throw new NotSupportedException("ObjectIds of type " + this.ObjectIds.GetType() + " are not supported.");
            }
        }