/// <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 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); } }
private IEnumerable <string> CalculateImplicitExpandPaths(IEnumerable <string> expandedPaths) { QueryStructuralType queryStructuralType = null; var queryCollectionType = this.QueryExpression.ExpressionType as QueryCollectionType; if (queryCollectionType != null) { queryStructuralType = queryCollectionType.ElementType as QueryStructuralType; } if (queryStructuralType != null) { // include navigation properties from the selected paths in expanded paths var navigationNames = queryStructuralType.GetBaseTypesAndSelf().SelectMany(t => t.Properties.Where(p => p.IsNavigationProperty())).Select(n => n.Name); var implicitlyExpandedPaths = this.SelectedPaths.Where(p => navigationNames.Contains(p.Split('/').Last())); if (implicitlyExpandedPaths.Any()) { return(expandedPaths.Union(implicitlyExpandedPaths).Except(new string[] { string.Empty })); } } return(expandedPaths); }
/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <returns>Value of the expression.</returns> public virtual QueryValue Visit(LinqNewInstanceExpression expression) { if (expression.ExpressionType is QueryStructuralType) { QueryStructuralType queryType = (QueryStructuralType)expression.ExpressionType; QueryStructuralValue instance = queryType.CreateNewInstance(); foreach (var property in queryType.Properties.Where(p => !(p.PropertyType is QueryScalarType))) { instance.SetValue(property.Name, property.PropertyType.DefaultValue); } for (int i = 0; i < expression.Members.Count; ++i) { instance.SetValue(expression.MemberNames[i], this.Evaluate(expression.Members[i])); } return(instance); } else if (expression.ExpressionType is QueryCollectionType) { // for QueryCollectionTypes we only support constructor arguments, hence we will only be evaluating constructor arguments. QueryCollectionValue instance = ((QueryCollectionType)expression.ExpressionType).CreateCollectionWithValues(expression.ConstructorArguments.Select(arg => this.Evaluate(arg))); return(instance); } else { var scalarType = expression.ExpressionType as QueryScalarType; ExceptionUtilities.CheckObjectNotNull(scalarType, "QueryType is not a supported type"); ExceptionUtilities.Assert(expression.ConstructorArguments.Count == 1, "Cannot pass multiple arguments to PrimitiveType constructor"); var constructorArgument = expression.ConstructorArguments.Select(this.Evaluate).Single(); QueryScalarValue instance = scalarType.CreateValue(constructorArgument); return(instance); } }
/// <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(); queryProperties = queryProperties.Where(qp => (qp.PropertyType as IQueryClrType).ClrType != typeof(Guid)).ToList(); } } return(queryProperties); }
/// <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 EntityDataKey GetEntityKey(QueryStructuralType type, SerializableEntity entity) { ExceptionUtilities.CheckArgumentNotNull(type, "type"); ExceptionUtilities.CheckArgumentNotNull(entity, "entity"); return(EntityDataKey.CreateFromValues(entity.Properties.Where(p => type.Properties.Any(k => k.IsPrimaryKey && k.Name == p.Name)).Select(p => this.DataOracleConverter.Convert(p)))); }
private IDictionary <EntityDataKey, SerializableEntity> GetEntitiesMappedByKey(QueryStructuralType type, IEnumerable <SerializableEntity> entities) { return(this.GetEntitiesMappedByKey(entities, e => this.GetEntityKey(type, e))); }
private MaskedQueryStructuralValue(QueryStructuralType type, bool isNull, QueryError evaluationError, IQueryEvaluationStrategy evaluationStrategy) : base(type, isNull, evaluationError, evaluationStrategy) { }
/// <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."); }