private bool StructuralTypesAreEqual(QueryStructuralType firstStructuralType, QueryStructuralType secondStructuralType)
        {
            var firstComplexType = firstStructuralType as QueryComplexType;

            if (firstComplexType != null)
            {
                var secondComplexType = secondStructuralType as QueryComplexType;
                return(secondComplexType != null && firstComplexType.ComplexType.Equals(secondComplexType.ComplexType));
            }

            var firstEntityType = firstStructuralType as QueryEntityType;

            if (firstEntityType != null)
            {
                var secondEntityType = secondStructuralType as QueryEntityType;
                return(secondEntityType != null && firstEntityType.EntityType.Equals(secondEntityType.EntityType));
            }

            var firstAnonymousType = firstStructuralType as QueryAnonymousStructuralType;

            if (firstAnonymousType != null)
            {
                var secondAnonymousType = secondStructuralType as QueryAnonymousStructuralType;
                return(secondAnonymousType != null && firstAnonymousType.Equals(secondAnonymousType));
            }

            var firstGroupingType = firstStructuralType as QueryGroupingType;

            ExceptionUtilities.Assert(firstGroupingType != null, "Unknown QueryStructuralType: {0}", firstStructuralType);

            var secondGroupingType = secondStructuralType as QueryGroupingType;

            return(secondGroupingType != null);
        }
        /// <summary>
        /// Initializes a new instance of the QueryStructuralValue class.
        /// </summary>
        /// <param name="type">The type of the value.</param>
        /// <param name="isNull">If set to <c>true</c> the structural value is null.</param>
        /// <param name="evaluationError">The evaluation error.</param>
        /// <param name="evaluationStrategy">The evaluation strategy.</param>
        public QueryStructuralValue(QueryStructuralType type, bool isNull, QueryError evaluationError, IQueryEvaluationStrategy evaluationStrategy)
            : base(evaluationError, evaluationStrategy)
        {
            ExceptionUtilities.CheckArgumentNotNull(type, "type");

            this.Type   = type;
            this.isNull = isNull;
        }
        private QueryValue TreatAs(QueryStructuralType structuralType)
        {
            if (structuralType.IsAssignableFrom(this.Type))
            {
                return(this);
            }

            return(structuralType.NullValue);
        }
        /// <summary>
        /// Converts the <see cref="QueryValue"/> to a particular <see cref="QueryType"/>.
        /// </summary>
        /// <param name="type">The type for the As operation.</param>
        /// <returns>The <see cref="QueryValue"/> converted to the specified type if successful. Returns null if this operation fails.</returns>
        public override QueryValue TreatAs(QueryType type)
        {
            QueryStructuralType structuralType = type as QueryStructuralType;

            if (structuralType == null)
            {
                return(this.Type.CreateErrorValue(new QueryError("Invalid 'As' Operation : Cannot perform an 'As' of a structural type to a non-structural type")));
            }

            return(this.TreatAs(structuralType));
        }
Beispiel #5
0
        /// <summary>
        /// Gets all the nested properties of a structural type recursively.
        /// </summary>
        /// <param name="structuralType">The type from which to extra properties.</param>
        /// <param name="operationFilter">The filter to apply based on supported operations of each property.</param>
        /// <param name="navigationPropertyFilter">The filter to apply based on whether or not to select navigation properties.</param>
        /// <returns>A list of string arrays representing the property paths to each property (including nested properties) in the entity.</returns>
        protected IEnumerable <string[]> GetAllNestedPropertyPaths(QueryStructuralType structuralType, SupportOperationsFilter operationFilter, NavigationPropertyFilter navigationPropertyFilter)
        {
            IList <string[]> allPropertyPaths = new List <string[]>();

            foreach (var property in structuralType.Properties)
            {
                var propertyType = property.PropertyType;
                var qst          = propertyType as QueryScalarType;
                var qcxt         = propertyType as QueryComplexType;
                var qct          = propertyType as QueryCollectionType;

                if (qst != null)
                {
                    if (operationFilter == SupportOperationsFilter.NoFilter ||
                        (operationFilter == SupportOperationsFilter.ArithmeticOperable && this.SupportsArithmeticOperations(qst)) ||
                        (operationFilter == SupportOperationsFilter.EqualComparable && qst.SupportsEqualityComparison) ||
                        (operationFilter == SupportOperationsFilter.OrderComparable && qst.SupportsOrderComparison))
                    {
                        if (navigationPropertyFilter != NavigationPropertyFilter.NavigationOnly)
                        {
                            allPropertyPaths.Add(new string[] { property.Name });
                        }
                    }
                }
                else if (qcxt != null)
                {
                    // For complex types recursively find child properties and add them to the list of property paths.
                    var nestedTypePaths = this.GetAllNestedPropertyPaths(qcxt, operationFilter, navigationPropertyFilter);

                    foreach (var nestedTypePath in nestedTypePaths)
                    {
                        var propertyPath = new string[] { property.Name };
                        propertyPath = propertyPath.Concat(nestedTypePath).ToArray();

                        if (navigationPropertyFilter != NavigationPropertyFilter.NavigationOnly)
                        {
                            allPropertyPaths.Add(propertyPath);
                        }
                    }
                }
                else if (qct != null)
                {
                    if (navigationPropertyFilter != NavigationPropertyFilter.NonNavigationOnly)
                    {
                        allPropertyPaths.Add(new string[] { property.Name });
                    }
                }
            }

            return(allPropertyPaths.AsEnumerable());
        }
Beispiel #6
0
        /// <summary>
        /// Returns an enumeration of the type's ancestor types and itself
        /// </summary>
        /// <param name="type">The type to get base types of</param>
        /// <returns>An enumeration containing the base types and the given type</returns>
        public static IEnumerable <QueryStructuralType> GetBaseTypesAndSelf(this QueryStructuralType type)
        {
            ExceptionUtilities.CheckArgumentNotNull(type, "type");

            var list = new List <QueryStructuralType> {
                type
            };

            while (type.Parent != null)
            {
                list.Insert(0, type.Parent);
                type = type.Parent;
            }

            return(list.AsEnumerable());
        }
        /// <summary>
        /// Casts a <see cref="QueryValue"/> to a <see cref="QueryType"/>. The cast will return the value type cast to the new type.
        /// </summary>
        /// <param name="type">The type for the cast operation.</param>
        /// <returns><see cref="QueryValue"/> which is cast to the appropriate type</returns>
        public override QueryValue Cast(QueryType type)
        {
            QueryStructuralType structuralType = type as QueryStructuralType;

            if (structuralType == null)
            {
                return(this.Type.CreateErrorValue(new QueryError("Invalid Cast : Cannot perform a cast of a structural type to a non-structural type")));
            }

            QueryValue result = this.TreatAs(structuralType);

            if (result.IsNull)
            {
                return(this.Type.CreateErrorValue(new QueryError("Invalid Cast : Cannot perform Cast to the specified type")));
            }

            return(result);
        }
        /// <summary>
        /// Determines if the current value is of a given type or an equivalent type in the type hierarchy
        /// </summary>
        /// <param name="resultType">The type to compare against</param>
        /// <param name="performExactMatch">A flag that determines if an exact match needs to be performed</param>
        /// <returns>The elements from the collection, that match the input type or an equivalent type</returns>
        public QueryValue OfType(QueryStructuralType resultType, bool performExactMatch)
        {
            QueryCollectionValue result = resultType.CreateCollectionType().CreateCollectionWithValues(Enumerable.Empty <QueryValue>());

            if (!this.IsNull)
            {
                foreach (QueryStructuralValue element in this.Elements)
                {
                    bool isOfEquivalentType = (bool)((QueryScalarValue)element.IsOf(resultType, performExactMatch)).Value;
                    if (isOfEquivalentType)
                    {
                        result.Elements.Add(element.TreatAs(resultType));
                    }
                }
            }

            return(result);
        }
Beispiel #9
0
        /// <summary>
        /// Creates a strongly-typed QueryProperty of T
        /// </summary>
        /// <param name="propertyName">The name of the property.</param>
        /// <param name="propertyType">Type of the property.</param>
        /// <returns>Strongly typed QueryProperty of T.</returns>
        public static QueryProperty <QueryStructuralType> Create(string propertyName, QueryStructuralType propertyType)
        {
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            ExceptionUtilities.CheckArgumentNotNull(propertyType, "propertyType");

            return(new QueryProperty <QueryStructuralType>(propertyName, propertyType));
        }
Beispiel #10
0
        private IEnumerable <QueryScalarValue> GetPropertyRows(IEnumerable <QueryStructuralValue> dataRows, IList <string> propertyPaths, QueryStructuralType rowType)
        {
            var currentPropertyPath = propertyPaths[0];
            var nestedPropertyType  = rowType.Properties.Where(p => p.Name == currentPropertyPath).Single().PropertyType;

            if (propertyPaths.Count == 1)
            {
                var nestedScalarType = nestedPropertyType as QueryScalarType;
                ExceptionUtilities.CheckObjectNotNull(nestedScalarType, "The leaf property of any structural type must be a scalar type");
                var propertyDataSet = dataRows.Select(qsv => qsv.GetValue(currentPropertyPath));

                if (propertyDataSet.Count() > 0)
                {
                    ExceptionUtilities.Assert(propertyDataSet.First() is QueryScalarValue, "Type mismatch between property type and data set, property {0} should be a scalar value in the dataSet", currentPropertyPath);
                    return(propertyDataSet.Cast <QueryScalarValue>());
                }
                else
                {
                    var propertyDataSetList = new List <QueryScalarValue>();
                    propertyDataSetList.Add(nestedScalarType.DefaultValue as QueryScalarValue);
                    return(propertyDataSetList.AsEnumerable <QueryScalarValue>());
                }
            }
            else
            {
                // if we are not at the leaf property, find it recursively.
                var nestedStructuralType = nestedPropertyType as QueryStructuralType;
                ExceptionUtilities.CheckObjectNotNull(nestedStructuralType, "A non-leaf property of a structural type must be a structural type");
                propertyPaths.RemoveAt(0);
                var nestedProperties = dataRows.Select(qsv => qsv.GetValue(currentPropertyPath)).Cast <QueryStructuralValue>();

                return(this.GetPropertyRows(nestedProperties, propertyPaths, nestedStructuralType));
            }
        }
 /// <summary>
 /// Creates a QueryProperty for a property that is a non entity Collection 
 /// </summary>
 /// <param name="library">Library Query Type</param>
 /// <param name="result">resulting Query Structural Type</param>
 /// <param name="collectionProperty">Member to calculate</param>
 /// <param name="pathToProperty">Path to the Property</param>
 /// <returns>A Query Property of the collectionType</returns>
 protected virtual QueryProperty CreateNonentityCollectionMember(QueryTypeLibrary library, QueryStructuralType result, MemberProperty collectionProperty, PathToProperty pathToProperty)
 {
     throw new TaupoNotSupportedException("This type of property is not supported.");
 }
        /// <summary>
        /// Creates new members on a structural type
        /// </summary>
        /// <param name="library">Type library</param>
        /// <param name="result">Structural Type to add members to</param>
        /// <param name="properties">Properties of the Structural Type member</param>
        /// <param name="pathToProperty">Path to the Property</param>
        protected void CreateMembers(QueryTypeLibrary library, QueryStructuralType result, IEnumerable<MemberProperty> properties, PathToProperty pathToProperty)
        {
            // TODO: Some Taupo framework pieces skip over StreamDataType properties
            foreach (var prop in properties.Where(p => !(p.PropertyType is StreamDataType)))
            {
                QueryProperty queryProperty = null;
                pathToProperty.PathStackWithinEntityType.Add(prop.Name);

                var pdt = prop.PropertyType as PrimitiveDataType;
                var cdt = prop.PropertyType as ComplexDataType;
                if (pdt != null)
                {
                    QueryScalarType queryPropertyType = this.GetQueryTypeForMappedProperty(pathToProperty, library, pdt);
                    queryProperty = QueryProperty.Create(prop.Name, queryPropertyType);
                }
                else if (cdt != null)
                {
                    ComplexType ct = cdt.Definition;
                    QueryComplexType queryComplexType = this.CreateStubComplexType(ct);
                    this.CreateMembers(library, queryComplexType, ct.Properties, pathToProperty);
                    library.SetQueryComplexType(ct, queryComplexType);
                    queryProperty = QueryProperty.Create(prop.Name, queryComplexType);
                }
                else
                {
                    queryProperty = this.CreateNonentityCollectionMember(library, result, prop, pathToProperty);
                }

                pathToProperty.PathStackWithinEntityType.RemoveAt(pathToProperty.PathStackWithinEntityType.Count - 1);

                queryProperty.SetPrimaryKey(prop.IsPrimaryKey);
                result.Add(queryProperty);
            }
        }
        /// <summary>
        /// Creates a QueryProperty for a property that is a non entity Collection 
        /// </summary>
        /// <param name="library">Library Query Type</param>
        /// <param name="result">resulting Query Structural Type</param>
        /// <param name="collectionProperty">Member to calculate</param>
        /// <param name="pathToProperty">Path to the Property</param>
        /// <returns>A Query Property of the collectionType</returns>
        protected override QueryProperty CreateNonentityCollectionMember(QueryTypeLibrary library, QueryStructuralType result, MemberProperty collectionProperty, PathToProperty pathToProperty)
        {
            ExceptionUtilities.CheckArgumentNotNull(collectionProperty, "collectionProperty");

            var collectionType = collectionProperty.PropertyType as CollectionDataType;
            ExceptionUtilities.Assert(collectionType != null, "This type of property is not supported.");
            var collectionPrimitiveElementType = collectionType.ElementDataType as PrimitiveDataType;
            var collectionComplexElementType = collectionType.ElementDataType as ComplexDataType;
            QueryCollectionType queryCollectionType = null;
            if (collectionPrimitiveElementType != null)
            {
                QueryScalarType queryPropertyType = this.GetQueryTypeForMappedProperty(pathToProperty, library, collectionPrimitiveElementType);
                queryCollectionType = queryPropertyType.CreateCollectionType();
            }
            else
            {
                ExceptionUtilities.Assert(collectionComplexElementType != null, "This type of property is not supported.");
                QueryComplexType queryComplexType = this.CreateStubComplexType(collectionComplexElementType.Definition);
                CreateMembers(library, queryComplexType, collectionComplexElementType.Definition.Properties, pathToProperty);
                queryCollectionType = queryComplexType.CreateCollectionType();
            }

            return QueryProperty.Create(collectionProperty.Name, queryCollectionType);
        }
        /// <summary>
        /// Get properties in the structural type that support a specific Binary Operation.
        /// </summary>
        /// <param name="type">Structural Type.</param>
        /// <param name="op">An enum that represents a Query Binary Operation.</param>
        /// <returns>A collection of properties.</returns>
        protected IEnumerable<QueryProperty<QueryScalarType>> GetPropertiesWithBinaryOpSupport(QueryStructuralType type, QueryBinaryOperation op)
        {
            List<QueryProperty<QueryScalarType>> queryProperties = type.Properties.Primitive().Where(m => m.PropertyType.Supports(op)).ToList();

            DataServiceExecuteVerifier verifier = this.Verifier as DataServiceExecuteVerifier;
            if (verifier != null && verifier.IsUri == false)
            {
                if (op == QueryBinaryOperation.GreaterThan || op == QueryBinaryOperation.GreaterThanOrEqualTo || op == QueryBinaryOperation.LessThan || op == QueryBinaryOperation.LessThanOrEqualTo)
                {
                    // Exclude string, DateTime and boolean properties as these don't support greater than or less than operators in the Client Linq Code
                    queryProperties = queryProperties.Where(qp => (qp.PropertyType as IQueryClrType).ClrType != typeof(string)).ToList();
                    queryProperties = queryProperties.Where(qp => (qp.PropertyType as IQueryClrType).ClrType != typeof(bool)).ToList();
                    queryProperties = queryProperties.Where(qp => (qp.PropertyType as IQueryClrType).ClrType != typeof(DateTime)).ToList();
#if !WINDOWS_PHONE
                    queryProperties = queryProperties.Where(qp => (qp.PropertyType as IQueryClrType).ClrType != typeof(Guid)).ToList();
#endif
                }
            }

            return queryProperties;
        }
 private MaskedQueryStructuralValue(QueryStructuralType type, bool isNull, QueryError evaluationError, IQueryEvaluationStrategy evaluationStrategy)
     : base(type, isNull, evaluationError, evaluationStrategy)
 {
 }
Beispiel #16
0
        /// <summary>
        /// Gets all the nested properties of a structural type recursively.
        /// </summary>
        /// <param name="structuralType">The type from which to extra properties.</param>
        /// <param name="operationFilter">The filter to apply based on supported operations of each property.</param>
        /// <param name="navigationPropertyFilter">The filter to apply based on whether or not to select navigation properties.</param>
        /// <returns>A list of string arrays representing the property paths to each property (including nested properties) in the entity.</returns>
        protected IEnumerable<string[]> GetAllNestedPropertyPaths(QueryStructuralType structuralType, SupportOperationsFilter operationFilter, NavigationPropertyFilter navigationPropertyFilter)
        {
            IList<string[]> allPropertyPaths = new List<string[]>();

            foreach (var property in structuralType.Properties)
            {
                var propertyType = property.PropertyType;
                var qst = propertyType as QueryScalarType;
                var qcxt = propertyType as QueryComplexType;
                var qct = propertyType as QueryCollectionType;

                if (qst != null)
                {
                    if (operationFilter == SupportOperationsFilter.NoFilter ||
                        (operationFilter == SupportOperationsFilter.ArithmeticOperable && this.SupportsArithmeticOperations(qst)) ||
                        (operationFilter == SupportOperationsFilter.EqualComparable && qst.SupportsEqualityComparison) ||
                        (operationFilter == SupportOperationsFilter.OrderComparable && qst.SupportsOrderComparison))
                    {
                        if (navigationPropertyFilter != NavigationPropertyFilter.NavigationOnly)
                        {
                            allPropertyPaths.Add(new string[] { property.Name });
                        }
                    }
                }
                else if (qcxt != null)
                {
                    // For complex types recursively find child properties and add them to the list of property paths.
                    var nestedTypePaths = this.GetAllNestedPropertyPaths(qcxt, operationFilter, navigationPropertyFilter);

                    foreach (var nestedTypePath in nestedTypePaths)
                    {
                        var propertyPath = new string[] { property.Name };
                        propertyPath = propertyPath.Concat(nestedTypePath).ToArray();

                        if (navigationPropertyFilter != NavigationPropertyFilter.NavigationOnly)
                        {
                            allPropertyPaths.Add(propertyPath);
                        }
                    }
                }
                else if (qct != null)
                {
                    if (navigationPropertyFilter != NavigationPropertyFilter.NonNavigationOnly)
                    {
                        allPropertyPaths.Add(new string[] { property.Name });
                    }
                }
            }

            return allPropertyPaths.AsEnumerable();
        }
Beispiel #17
0
        private IEnumerable<QueryScalarValue> GetPropertyRows(IEnumerable<QueryStructuralValue> dataRows, IList<string> propertyPaths, QueryStructuralType rowType)
        {
            var currentPropertyPath = propertyPaths[0];
            var nestedPropertyType = rowType.Properties.Where(p => p.Name == currentPropertyPath).Single().PropertyType;
            
            if (propertyPaths.Count == 1)
            {
                var nestedScalarType = nestedPropertyType as QueryScalarType;
                ExceptionUtilities.CheckObjectNotNull(nestedScalarType, "The leaf property of any structural type must be a scalar type");
                var propertyDataSet = dataRows.Select(qsv => qsv.GetValue(currentPropertyPath));

                if (propertyDataSet.Count() > 0)
                {
                    ExceptionUtilities.Assert(propertyDataSet.First() is QueryScalarValue, "Type mismatch between property type and data set, property {0} should be a scalar value in the dataSet", currentPropertyPath);
                    return propertyDataSet.Cast<QueryScalarValue>();
                }
                else
                {
                    var propertyDataSetList = new List<QueryScalarValue>();
                    propertyDataSetList.Add(nestedScalarType.DefaultValue as QueryScalarValue);
                    return propertyDataSetList.AsEnumerable<QueryScalarValue>();
                }
            }
            else
            {
                // if we are not at the leaf property, find it recursively.
                var nestedStructuralType = nestedPropertyType as QueryStructuralType;
                ExceptionUtilities.CheckObjectNotNull(nestedStructuralType, "A non-leaf property of a structural type must be a structural type");
                propertyPaths.RemoveAt(0);
                var nestedProperties = dataRows.Select(qsv => qsv.GetValue(currentPropertyPath)).Cast<QueryStructuralValue>();

                return this.GetPropertyRows(nestedProperties, propertyPaths, nestedStructuralType);
            }
        }