/// <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)); }
private QueryValue BuildCollectionQueryValue(string propertyPath, QueryCollectionType queryCollectionType, EntitySetDataRow row) { QueryScalarType scalarElementDataType = queryCollectionType.ElementType as QueryScalarType; QueryComplexType complexTypeElementDataType = queryCollectionType.ElementType as QueryComplexType; List <QueryValue> queryValues = new List <QueryValue>(); if (scalarElementDataType != null) { int i = 0; while (row.PropertyPaths.Any(pp => pp == propertyPath + i)) { var value = row[propertyPath + i]; queryValues.Add(scalarElementDataType.CreateValue(value)); i++; } } else { ExceptionUtilities.CheckObjectNotNull(complexTypeElementDataType, "PropertyPath '{0}' is an invalid type '{1}'", propertyPath, queryCollectionType.ElementType); int i = 0; while (row.PropertyPaths.Where(pp => pp.StartsWith(propertyPath + i, StringComparison.Ordinal)).Count() > 0) { QueryStructuralValue complexChildInstance = complexTypeElementDataType.CreateNewInstance(); this.BuildStructuralPropertiesQueryValue(complexChildInstance, propertyPath + i + ".", complexTypeElementDataType.ComplexType.Properties, complexTypeElementDataType.Properties, row); queryValues.Add(complexChildInstance); i++; } } return(queryCollectionType.CreateCollectionWithValues(queryValues.ToArray())); }
/// <summary> /// Override the default method, adding generation of root queries that call designated service operations /// </summary> /// <param name="entityModelSchema">Entity Model Schema</param> /// <param name="queryTypeLibrary">Query Type Library</param> protected override void BuildRootQueriesAndTypes(EntityModelSchema entityModelSchema, QueryTypeLibrary queryTypeLibrary) { base.BuildRootQueriesAndTypes(entityModelSchema, queryTypeLibrary); // For each service operation marked as root, add a root query that calls the operation var rootServiceOperationQueries = new List <QueryExpression>(); foreach (var serviceOperation in entityModelSchema.Functions.Where(f => f.Annotations.OfType <FunctionBodyAnnotation>().Any(a => a.IsRoot))) { QueryExpression bodyExpression = serviceOperation.Annotations.OfType <FunctionBodyAnnotation>().Single().FunctionBody; ExceptionUtilities.CheckObjectNotNull(bodyExpression, "Root level function has null body expression"); QueryType rootQueryType = queryTypeLibrary.GetDefaultQueryType(serviceOperation.ReturnType); var rootQuery = new QueryCustomFunctionCallExpression(rootQueryType, serviceOperation, bodyExpression, true, false); rootServiceOperationQueries.Add(rootQuery); QueryStructuralType structuralType = rootQueryType as QueryStructuralType; if (structuralType == null) { QueryCollectionType collectionType = rootQueryType as QueryCollectionType; if (collectionType != null) { structuralType = collectionType.ElementType as QueryStructuralType; } } ExceptionUtilities.CheckObjectNotNull(structuralType, "Root level service op query must return structural type"); this.RootDataTypes.Add(serviceOperation.Name, structuralType); } this.RootQueries = this.RootQueries.Concat(rootServiceOperationQueries); }
/// <summary> /// Creates the typed collection where element type is the current primitive type. /// </summary> /// <returns>Collection of the given type.</returns> protected override QueryCollectionType CreateCollectionTypeInternal() { if (this.collectionType == null) { this.collectionType = QueryCollectionType.Create(this); } return((QueryCollectionType)this.collectionType); }
/// <summary> /// Creates a QueryValue of a given type. /// </summary> /// <param name="type">Type of the QueryValue that will be generated.</param> /// <returns>QueryValue representing the provided object.</returns> public QueryValue Visit(QueryCollectionType type) { var resultFragment = this.ResultFragmentStack.Pop(); var resultCollectionElements = new List <QueryValue>(); // need to materialize results first to get the complete graph, before we start converting to QueryValue var resultFragmentList = ((IEnumerable)resultFragment).Cast <object>().ToList(); foreach (var resultFragmentElement in resultFragmentList) { var resultCollectionElement = this.Convert(resultFragmentElement, type.ElementType); resultCollectionElements.Add(resultCollectionElement); } return(type.CreateCollectionWithValues(resultCollectionElements)); }
private void BuildStructuralPropertiesQueryValue(QueryStructuralValue instance, string propertyPath, IList <MemberProperty> properties, IList <QueryProperty> queryProperties, EntitySetDataRow row) { ExceptionUtilities.Assert(properties.Count == queryProperties.Count, "QueryProperties '{0}' and MemberProperties '{1}' are not the same number!", CreateQueryPropertyList(queryProperties), CreateMemberPropertyList(properties)); // TODO: Some Taupo framework pieces skip over StreamDataType properties foreach (MemberProperty childProperty in properties.Where(p => !(p.PropertyType is StreamDataType))) { string childPropertyPath = propertyPath + childProperty.Name; List <QueryProperty> childQueryProperties = queryProperties.Where(p => p.Name == childProperty.Name).ToList(); ExceptionUtilities.Assert(childQueryProperties.Count == 1, "Could not find query property based on MemberProperty Name '{0}' in list of query properties '{1}'", childProperty.Name, CreateQueryPropertyList(childQueryProperties)); QueryProperty childQueryProperty = childQueryProperties.First(); QueryCollectionType childCollectionDataType = childQueryProperty.PropertyType as QueryCollectionType; QueryScalarType childScalarType = childQueryProperty.PropertyType as QueryScalarType; QueryComplexType childComplexType = childQueryProperty.PropertyType as QueryComplexType; if (childCollectionDataType != null) { instance.SetValue(childProperty.Name, this.BuildCollectionQueryValue(childPropertyPath + ".", childCollectionDataType, row)); } else if (childScalarType != null) { var value = row[childPropertyPath]; var queryValue = childScalarType.CreateValue(value); instance.SetValue(childQueryProperty.Name, queryValue); } else { ExceptionUtilities.CheckObjectNotNull(childComplexType, "Unknown type '{0}'", childProperty.PropertyType); // If a complex type instance is null in the datarow, we will create a QueryStructuralValue indicating null and set it on the instance. if (row.PropertyPaths.Contains(childPropertyPath) && row[childPropertyPath] == null) { instance.SetValue(childProperty.Name, new QueryStructuralValue(childComplexType, true, null, childComplexType.EvaluationStrategy)); } else { QueryStructuralValue childInstance = childComplexType.CreateNewInstance(); this.BuildStructuralPropertiesQueryValue(childInstance, childPropertyPath + ".", childComplexType.ComplexType.Properties, childComplexType.Properties, row); instance.SetValue(childProperty.Name, childInstance); } } } }
/// <summary> /// Visits a <see cref="QueryCollectionType"/>. /// </summary> /// <param name="type">Query type being visited.</param> /// <returns>The result of visiting this query type.</returns> public ComparisonResult Visit(QueryCollectionType type) { return(this.parent.CompareCollection((QueryCollectionValue)this.expectedValue, this.actualValue, this.path, this.shouldThrow)); }