internal static LinqLambdaExpression CreateLambda(QueryExpression source, IEnumerable <KeyValuePair <QueryProperty, QueryConstantExpression> > keys) { ExceptionUtilities.CheckArgumentNotNull(source, "source"); ExceptionUtilities.CheckCollectionNotEmpty(keys, "keys"); QueryType parameterType; if (source.ExpressionType.IsUnresolved) { parameterType = QueryType.Unresolved; } else { var queryCollectionType = source.ExpressionType as QueryCollectionType; ExceptionUtilities.CheckObjectNotNull(queryCollectionType, "Source expression type was not a collection. Type was: {0}", source.ExpressionType); parameterType = queryCollectionType.ElementType; } var parameter = LinqBuilder.Parameter(ParameterName, parameterType); // specifically using the overload of .Property which takes a type because it may have already been resolved and we don't want to throw that away var predicate = keys.Select(k => parameter.Property(k.Key.Name, k.Key.PropertyType).EqualTo(k.Value)).ToList(); QueryExpression body = predicate[0]; if (predicate.Count > 1) { for (int i = 1; i < predicate.Count; i++) { body = CommonQueryBuilder.And(body, predicate[i]); } } return(LinqBuilder.Lambda(body, parameter)); }
/// <summary> /// Orders the collection by applying given ordering. /// </summary> /// <param name="ordering">The ordering to use.</param> /// <returns>Ordered collection.</returns> /// <remarks>This overload allows for more intellisense-friendly way of specifying ordering.</remarks> public QueryCollectionValue OrderBy(QueryOrdering ordering) { ExceptionUtilities.CheckArgumentNotNull(ordering, "ordering"); ExceptionUtilities.CheckCollectionNotEmpty(ordering.Selectors, "ordering.Selectors"); if (this.IsNull) { return(this); } IEnumerable <QueryValue> orderedElements = ordering.Apply(this.Elements.Cast <object>()).Cast <QueryValue>(); QueryError currentError = QueryError.Combine(this.EvaluationError, QueryError.GetErrorFromValues(orderedElements)); if (currentError != null) { return((QueryCollectionValue)this.Type.CreateErrorValue(currentError)); } // if this collection contains duplicate order by key selectors if (HasNondeterministicOrdering(ordering, orderedElements)) { return(new QueryCollectionValue(this.Type, this.EvaluationStrategy, null, orderedElements, false)); } else { return(new QueryCollectionValue(this.Type, this.EvaluationStrategy, null, orderedElements, true)); } }
/// <summary> /// Initializes a new instance of the <see cref="GenericTypeAnnotation"/> class. /// </summary> /// <param name="genericTypeParameterNames">The names of the generic type parameters.</param> public GenericTypeAnnotation(params string[] genericTypeParameterNames) { ExceptionUtilities.CheckArgumentNotNull(genericTypeParameterNames, "genericTypeParameterNames"); ExceptionUtilities.CheckCollectionNotEmpty(genericTypeParameterNames, "genericTypeParameterNames"); this.TypeParameters = new ReadOnlyCollection <string>(genericTypeParameterNames); }
/// <summary> /// Factory method to create the <see cref="LinqToAstoriaKeyExpression"/>. /// </summary> /// <param name="source">The source query.</param> /// <param name="keys">The list of key properties.</param> /// <returns>The <see cref="QueryExpression"/> with the provided arguments.</returns> public static LinqToAstoriaKeyExpression Key(this QueryExpression source, IEnumerable <KeyValuePair <QueryProperty, QueryConstantExpression> > keys) { ExceptionUtilities.CheckArgumentNotNull(source, "source"); ExceptionUtilities.CheckCollectionNotEmpty(keys, "keys"); return(new LinqToAstoriaKeyExpression(source, keys, QueryType.Unresolved)); }
/// <summary> /// Adds a collection of objects(typically GraphNodes) to a specified property name in GraphNode /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="values">A collection of objects(typically GraphNodes)</param> /// <returns>The instance of GraphNode on which AddToCollection was invoked</returns> public GraphNode AddToCollection(string propertyName, params object[] values) { ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(propertyName, "propertyName"); ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); // Confirm the values in the list of values passed in match the allowed types for this method List <object> valuesToSet = this.TransformCollectionContents(values); object value = null; this.contents.TryGetValue(propertyName, out value); var collection = value as List <object>; if (collection == null) { collection = new List <object>(); this.contents.Add(propertyName, collection); } foreach (var item in valuesToSet) { collection.Add(item); } return(this); }
/// <summary> /// Synchronizes the data for the entity with the given set name and key values /// </summary> /// <param name="continuation">The asynchronous continuation to report failure/completion on</param> /// <param name="entitySetName">The entity set the entity belongs to</param> /// <param name="keyValues">The key values of the entity</param> public void SynchronizeEntityInstanceGraph(IAsyncContinuation continuation, string entitySetName, IEnumerable <NamedValue> keyValues) { ExceptionUtilities.CheckArgumentNotNull(continuation, "continuation"); ExceptionUtilities.CheckArgumentNotNull(entitySetName, "entitySetName"); ExceptionUtilities.CheckCollectionNotEmpty(keyValues, "keyValues"); ExceptionUtilities.CheckAllRequiredDependencies(this); this.OracleServiceClient.BeginGetEntity( entitySetName, keyValues.Select(v => new SerializableNamedValue() { Name = v.Name, Value = v.Value }).ToList(), result => AsyncHelpers.CatchErrors( continuation, delegate { string error; var entity = this.OracleServiceClient.EndGetEntity(out error, result); if (error != null) { continuation.Fail(new Exception(error)); return; } this.UnderlyingSynchronizer.SynchronizeEntityInstanceGraph(entity); continuation.Continue(); }), null); }
/// <summary> /// Constructs a key expression segment with the given values /// </summary> /// <param name="type">The type for the key</param> /// <param name="values">The values for the key</param> /// <returns>A key expression segment</returns> public static ODataUriSegment Key(EntityType type, IEnumerable <NamedValue> values) { ExceptionUtilities.CheckArgumentNotNull(type, "type"); ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); // intentionally avoiding using a linq-to-objects query as it introduces a compiler-generated class that shows up in the dependency layering output List <KeyValuePair <MemberProperty, object> > pairs = new List <KeyValuePair <MemberProperty, object> >(); Dictionary <string, MemberProperty> keyProperties = new Dictionary <string, MemberProperty>(); foreach (var keyProperty in type.AllKeyProperties) { keyProperties[keyProperty.Name] = keyProperty; } foreach (var pair in values) { MemberProperty keyProperty; ExceptionUtilities.Assert(keyProperties.TryGetValue(pair.Name, out keyProperty), "Could not find key property '" + pair.Name + "'"); pairs.Add(new KeyValuePair <MemberProperty, object>(keyProperty, pair.Value)); } ExceptionUtilities.Assert(pairs.Count == values.Count(), "Number of pairs does not match input"); return(new KeyExpressionSegment(pairs)); }
/// <summary> /// Registers a custom resolver for the given service reference client type using a sequence of uri resolvers. /// If a resolver returns null, the next one will be used. If they all return null, then a null value will be returned for the dependency. /// </summary> /// <typeparam name="TClient">The service reference client type contract</typeparam> /// <param name="container">The dependency injection container</param> /// <param name="serviceUriResolvers">The uri resolvers to try</param> public static void RegisterServiceReference <TClient>(this DependencyInjectionContainer container, params Func <Uri>[] serviceUriResolvers) { ExceptionUtilities.CheckArgumentNotNull(container, "container"); ExceptionUtilities.CheckCollectionNotEmpty(serviceUriResolvers, "serviceUriResolvers"); ExceptionUtilities.CheckCollectionDoesNotContainNulls(serviceUriResolvers, "serviceUriResolvers"); var options = container.RegisterCustomResolver( typeof(TClient), t => { Uri serviceUri = null; foreach (var uriResolver in serviceUriResolvers) { serviceUri = uriResolver(); if (serviceUri != null) { break; } } if (serviceUri == null) { return(null); } var factory = container.Resolve <IServiceReferenceFactory>(); return(factory.CreateInstance <TClient>(serviceUri)); }); options.IsTransient = true; }
/// <summary> /// Performs the specified action on a subset of root queries within the repository /// </summary> /// <param name="queryFilter">the filter used to generate the subset</param> /// <param name="action">the action to perform</param> /// <remarks> /// For whatever reason, the CLR on the Phone (.netCF) does not allow static methods in a static class to call each other. /// Doing so will result in a runtime TypeLoadException which is quite painful to debug. /// The below code, while it looks sub-optimal is the only way to get this type to load on the Windows Phone platform /// </remarks> public void RunOnEntitySetRootQueries( Func <TypedQueryExpression <QueryCollectionType <QueryStructuralType> >, bool> queryFilter, Action <TypedQueryExpression <QueryCollectionType <QueryStructuralType> > > action) { ExceptionUtilities.CheckArgumentNotNull(queryFilter, "queryFilter"); ExceptionUtilities.CheckArgumentNotNull(action, "action"); var rootQueries = this.Repository.RootQueries.Collections <QueryStructuralType>(); ExceptionUtilities.CheckCollectionNotEmpty(rootQueries, "rootQueries"); bool wasQueryRun = false; foreach (var rootQuery in rootQueries) { if (rootQuery.Expression.IsRootEntitySetQuery()) { if (queryFilter(rootQuery)) { wasQueryRun = true; action(rootQuery); } } } if (!wasQueryRun) { throw new TestSkippedException("No root queries were found that matched the given filter."); } }
private QueryScalarValue SelectRelevantValue(IEnumerable <QueryScalarValue> dataValues) { ExceptionUtilities.CheckCollectionNotEmpty(dataValues, "dataValues"); // Don't select null constants where possible, null constants should be tested separately using the isNull and isNotNull expressions. if (dataValues.All(dv => dv.IsNull)) { return(dataValues.First()); } else { var dataType = dataValues.First().Type; var scalarDataValues = dataValues.Where(dv => !dv.IsNull).Select(dv => dv.Value); // if we have more than 3 rows to choose from, then removing the largest and the smallest values from being chosen allows us to // guarantee that the query returns a result for equality and order comparisons. if (scalarDataValues.Count() >= 3 && scalarDataValues.First() is IComparable) { var maxValue = scalarDataValues.Max(); var minValue = scalarDataValues.Min(); var valuesList = scalarDataValues.ToList(); valuesList.Remove(maxValue); valuesList.Remove(minValue); scalarDataValues = valuesList.AsEnumerable(); } return(dataType.CreateValue(this.Random.ChooseFrom(scalarDataValues))); } }
/// <summary> /// Initializes a new instance of the KeyExpressionSegment class /// </summary> /// <param name="values">The key values</param> internal KeyExpressionSegment(IEnumerable <KeyValuePair <MemberProperty, object> > values) : base() { ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); this.IncludedValues = new ReadOnlyCollection <KeyValuePair <MemberProperty, object> >(values.ToList()); this.IsComposite = this.IncludedValues.Count > 1; }
/// <summary> /// Initializes a new instance of the ParametersExpressionSegment class /// </summary> /// <param name="values">The key values</param> internal ParametersExpressionSegment(IEnumerable<KeyValuePair<string, ITypedValue>> values) : base() { ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); this.IncludedTypedValues = new ReadOnlyCollection<KeyValuePair<string, ITypedValue>>(values.ToList()); this.IsComposite = this.IncludedTypedValues.Count > 1; }
/// <summary> /// Initializes a new instance of the FixedSetDataGenerator class. /// </summary> /// <param name="random">Random number generator.</param> /// <param name="allowRepeats">A value indicating whether repeats are allowed</param> /// <param name="interestingData">Interesting data that should be generated randomly.</param> public FixedSetDataGenerator(IRandomNumberGenerator random, bool allowRepeats, IEnumerable <TData> interestingData) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckCollectionNotEmpty(interestingData, "interestingData"); this.random = random; this.allowRepeats = allowRepeats; this.interestingData = interestingData.ToList(); }
/// <summary> /// Gets an implementation by its name /// </summary> /// <param name="selectorName">Name of selector to find</param> /// <param name="assemblies">Assemblies to look in</param> /// <returns>selector name and its values</returns> public static TestDimension GetImplementationsByName(string selectorName, IEnumerable <Assembly> assemblies) { ExceptionUtilities.CheckArgumentNotNull(selectorName, "selectorName"); ExceptionUtilities.CheckArgumentNotNull(assemblies, "assemblies"); ExceptionUtilities.CheckCollectionNotEmpty(assemblies, "assemblies"); var implementations = GetImplementationsBySelectorName(selectorName, assemblies.SelectMany(s => s.GetTypes())); return(new TestDimension(selectorName, implementations.Select(s => s.ImplementationName).ToArray())); }
/// <summary> /// Gets an Implementation by its tag and selector name /// </summary> /// <param name="selectorName">Selector name</param> /// <param name="assemblies">assemblies to look in</param> /// <param name="tagNames">tag names to look for</param> /// <returns>A selector name followed by its values</returns> public static TestDimension GetImplementationsByNameAndTag(string selectorName, IEnumerable <Assembly> assemblies, params string[] tagNames) { ExceptionUtilities.CheckArgumentNotNull(selectorName, "selectorName"); ExceptionUtilities.CheckArgumentNotNull(assemblies, "assemblies"); ExceptionUtilities.CheckCollectionNotEmpty(assemblies, "assemblies"); var implementations = GetImplementationsBySelectorName(selectorName, assemblies.SelectMany(s => s.GetTypes())); return(new TestDimension(selectorName, implementations.Where(s1 => tagNames.Any(t => s1.Tags.Contains(t))).Select(s => s.ImplementationName).ToArray())); }
/// <summary> /// Initializes a new instance of the CodeFreeVariable class. /// </summary> /// <param name="name">Variable name.</param> /// <param name="variableType">Variable type.</param> /// <param name="possibleValues">Values that can be assigned to the variable.</param> public CodeFreeVariable(string name, CodeTypeReference variableType, IEnumerable <CodeExpression> possibleValues) { ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(name, "name"); ExceptionUtilities.CheckArgumentNotNull(variableType, "variableType"); ExceptionUtilities.CheckCollectionNotEmpty(possibleValues, "possibleValues"); this.Name = name; this.VariableType = variableType; this.PossibleValues = possibleValues.ToList().AsReadOnly(); }
/// <summary> /// Fixes up the properties of the structural value based on the given selected paths /// </summary> /// <param name="instance">The value to fix up</param> /// <param name="selectedPaths">The selected paths for the value's scope</param> /// <returns>The fixed-up value</returns> private QueryStructuralValue FixupPropertiesForSelect(QueryStructuralValue instance, IEnumerable <string> selectedPaths) { ExceptionUtilities.CheckArgumentNotNull(instance, "instance"); ExceptionUtilities.CheckCollectionNotEmpty(selectedPaths, "selectedPaths"); var entityType = instance.Type as QueryEntityType; ExceptionUtilities.CheckObjectNotNull(entityType, "Select is not supported on non-entity types"); var masked = MaskedQueryStructuralValue.Create(instance); bool wildCard = selectedPaths.Contains(Endpoints.SelectAll); var propertyNames = entityType.EntityType.AllProperties.Select(p => p.Name).Concat(entityType.Properties.Streams().Select(m => m.Name)); foreach (string propertyName in propertyNames) { if (!selectedPaths.Contains(Uri.EscapeDataString(propertyName)) && !wildCard) { // Primitive, bag and stream properties are either entirely present or entirely missing. // However, complex properties can be partially present if a mapped sub-property has a // null value. For this reason, we recursively hide the property and all sub-properties. HidePropertyRecursive(masked, propertyName); } } foreach (string propertyName in entityType.EntityType.AllNavigationProperties.Select(p => p.Name)) { string pathMarker = Uri.EscapeDataString(propertyName) + "/"; var subpaths = selectedPaths.Where(p => p.StartsWith(pathMarker, StringComparison.Ordinal)).Select(p => p.Substring(pathMarker.Length)); var value = instance.GetValue(propertyName); ExceptionUtilities.CheckObjectNotNull(value, "Value for property '{0}' was null", propertyName); if (selectedPaths.Contains(Uri.EscapeDataString(propertyName))) { continue; } else if (subpaths.Any()) { var maskedValue = this.VisitEntityValues(value, s => this.FixupPropertiesForSelect(s, subpaths)); masked.SetValue(propertyName, maskedValue); } else if (wildCard) { masked.SetValue(propertyName, value.Type.NullValue); } else { masked.HideMember(propertyName); } } return(masked); }
/// <summary> /// Initializes a new instance of the DelegatedRandomDataGenerator class. /// </summary> /// <param name="random">Random number generator.</param> /// <param name="generateDataDelegates">Delegates to use when generating data. Delegate is picked randomly each time if more than one delegate provided.</param> /// <param name="interestingData">Interesting data that should be generated randomly.</param> public DelegatedRandomDataGenerator(IRandomNumberGenerator random, IEnumerable <Func <IRandomNumberGenerator, TData> > generateDataDelegates, params TData[] interestingData) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckCollectionNotEmpty(generateDataDelegates, "generateDataDelegates"); ExceptionUtilities.CheckCollectionDoesNotContainNulls(generateDataDelegates, "generateDataDelegates"); ExceptionUtilities.CheckArgumentNotNull(interestingData, "interestingData"); this.random = random; this.generateDataDelegates = generateDataDelegates.ToArray(); this.interestingData = interestingData.ToArray(); }
/// <summary> /// Performs the specified action on all root queries within the repository /// </summary> /// <param name="action">the action to perform</param> /// <remarks> /// For whatever reason, the CLR on the Phone (.netCF) does not allow static methods in a static class to call each other. /// Doing so will result in a runtime TypeLoadException which is quite painful to debug. /// The below code, while it looks sub-optimal is the only way to get this type to load on the Windows Phone platform /// </remarks> public void RunOnAllRootQueries(Action <TypedQueryExpression <QueryCollectionType <QueryStructuralType> > > action) { ExceptionUtilities.CheckArgumentNotNull(action, "action"); var rootQueries = this.Repository.RootQueries.Collections <QueryStructuralType>(); ExceptionUtilities.CheckCollectionNotEmpty(rootQueries, "rootQueries"); foreach (var rootQuery in rootQueries) { action(rootQuery); } }
/// <summary> /// Creates EntityDataKey from a collection of NamedValue instances /// </summary> /// <param name="values">The collection of values to create EntityDataKey from.</param> /// <returns>Entity data key</returns> public static EntityDataKey CreateFromValues(IEnumerable <NamedValue> values) { ExceptionUtilities.CheckArgumentNotNull(values, "values"); ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); var key = new EntityDataKey(values.Select(v => v.Name)); foreach (var keyValue in values) { key[keyValue.Name] = keyValue.Value; } return(key); }
/// <summary> /// Finds the maximum version from those given /// </summary> /// <param name="versions">The versions to get the max from</param> /// <returns>The maximum version of those given</returns> public static DataServiceProtocolVersion GetMaximumVersion(params DataServiceProtocolVersion[] versions) { ExceptionUtilities.CheckCollectionNotEmpty(versions, "versions"); DataServiceProtocolVersion max = DataServiceProtocolVersion.Unspecified; foreach (var version in versions) { if (max == DataServiceProtocolVersion.Unspecified || version > max) { max = version; } } return(max); }
/// <summary> /// Finds the minumum version from those given. Will NOT consider 'Unspecified' to be a minimal value. /// </summary> /// <param name="versions">The versions to get the min from</param> /// <returns>The minimum specified version</returns> public static DataServiceProtocolVersion GetMinimumVersion(params DataServiceProtocolVersion[] versions) { ExceptionUtilities.CheckCollectionNotEmpty(versions, "versions"); DataServiceProtocolVersion min = GetMaximumVersion(versions); // doing this to handle Unspecified safely foreach (var version in versions) { if (version != DataServiceProtocolVersion.Unspecified && version < min) { min = version; } } return(min); }
/// <summary> /// Calculates the key for an entity, which is used to build uris for link update and delete operations /// </summary> /// <param name="entity">The entity to build a key for</param> /// <returns>The key of the entity</returns> public string CalculateEntityKey(object entity) { var entityType = entity.GetType(); var keyProperties = entityType.GetCustomAttributes(typeof(KeyAttribute), true) .Cast <KeyAttribute>().SelectMany(att => att.KeyNames) .Concat(entityType.GetProperties().Select(p => p.Name).Where(p => p.EndsWith("ID", StringComparison.Ordinal))) .Distinct() .OrderBy(p => p, Comparer <string> .Default) .Select(p => entityType.GetProperty(p)) .ToList(); ExceptionUtilities.CheckCollectionNotEmpty(keyProperties, "keyProperties"); ExceptionUtilities.CheckCollectionDoesNotContainNulls(keyProperties, "keyProperties"); StringBuilder builder = new StringBuilder(); this.LiteralConverter.AppendKeyExpression(builder, keyProperties.Select(p => new NamedValue(p.Name, p.GetValue(entity, null)))); return(builder.ToString()); }
/// <summary> /// Concatenates the given sequence of segment sets onto the given string builder /// </summary> /// <param name="converter">The uri to string converter to extend</param> /// <param name="builder">The string builder to append onto</param> /// <param name="segmentSets">The segment sets to append</param> public static void ConcatenateSegments(this IODataUriToStringConverter converter, StringBuilder builder, ODataUriSegmentPathCollection segmentSets) { ExceptionUtilities.CheckArgumentNotNull(converter, "converter"); ExceptionUtilities.CheckArgumentNotNull(builder, "builder"); ExceptionUtilities.CheckCollectionNotEmpty(segmentSets, "segmentSets"); bool isFirstSegmentSet = true; foreach (var segments in segmentSets) { if (!isFirstSegmentSet) { builder.Append(','); } isFirstSegmentSet = false; converter.ConcatenateSegments(builder, segments); } }
/// <summary> /// Removes the specified instances from a collection /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="values">A collection of GraphNodes to remove from the property</param> /// <returns> /// The instance of GraphNode on which AddToCollection was invoked /// </returns> public GraphNode RemoveFromCollection(string propertyName, params object[] values) { ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(propertyName, "propertyName"); ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); // Confirm the values in the list of values passed in match the allowed types for this method List <object> valuesToRemove = this.TransformCollectionContents(values); object value = null; this.contents.TryGetValue(propertyName, out value); if (value == null) { throw new TaupoInvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to remove object from {0} collection property as this collection is not present in this Graph Node!", propertyName)); } var collection = (List <object>)value; ExceptionUtilities.CheckObjectNotNull(collection, string.Format(CultureInfo.InvariantCulture, "Unable to remove GraphNode(s) from {0} collection as collection was null!", propertyName)); foreach (var propertyValue in valuesToRemove) { int index = collection.IndexOf(propertyValue); if (index < 0) { throw new TaupoInvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to remove Graph Node as it is not found in the collection {0}!", propertyName)); } else { collection.Remove(propertyValue); } } if (collection.Count == 0) { this.contents.Remove(propertyName); } return(this); }
/// <summary> /// Concatenates the given sequence of segments onto the given string builder /// </summary> /// <param name="converter">The uri to string converter to extend</param> /// <param name="builder">The string builder to append onto</param> /// <param name="segments">The segments to append</param> public static void ConcatenateSegments(this IODataUriToStringConverter converter, StringBuilder builder, IEnumerable <ODataUriSegment> segments) { ExceptionUtilities.CheckArgumentNotNull(converter, "converter"); ExceptionUtilities.CheckArgumentNotNull(builder, "builder"); ExceptionUtilities.CheckCollectionNotEmpty(segments, "segments"); bool isFirstSegment = true; foreach (var segment in segments) { if (!isFirstSegment && segment.HasPrecedingSlash) { if (builder[builder.Length - 1] != '/') { builder.Append('/'); } } isFirstSegment = false; builder.Append(converter.ConvertToString(segment)); } }
/// <summary> /// Factory method to create the <see cref="LinqToAstoriaKeyExpression"/>. /// </summary> /// <param name="source">The source query.</param> /// <param name="keys">The set of key property values.</param> /// <returns>The <see cref="QueryExpression"/> with the provided arguments.</returns> public static LinqToAstoriaKeyExpression Key(this QueryExpression source, IEnumerable <NamedValue> keys) { ExceptionUtilities.CheckArgumentNotNull(source, "source"); ExceptionUtilities.CheckCollectionNotEmpty(keys, "keys"); QueryType elementType = QueryType.Unresolved; var queryCollectionType = source.ExpressionType as QueryCollectionType; if (queryCollectionType != null) { elementType = queryCollectionType.ElementType; } var structuralType = elementType as QueryStructuralType; var key = new List <KeyValuePair <QueryProperty, QueryConstantExpression> >(); foreach (var keyValue in keys) { QueryScalarType primitiveType = QueryType.UnresolvedPrimitive; QueryProperty queryProperty = QueryProperty.Create(keyValue.Name, primitiveType); if (structuralType != null) { queryProperty = structuralType.Properties.SingleOrDefault(p => p.Name == keyValue.Name); ExceptionUtilities.CheckObjectNotNull(queryProperty, "Could not find property with name '{0}' on type '{1}'", keyValue.Name, structuralType); primitiveType = queryProperty.PropertyType as QueryScalarType; ExceptionUtilities.CheckObjectNotNull(primitiveType, "Property '{0}' on type '{1}' was not a primitive type", keyValue.Name, structuralType); } var value = CommonQueryBuilder.Constant(keyValue.Value, primitiveType); key.Add(new KeyValuePair <QueryProperty, QueryConstantExpression>(queryProperty, value)); } return(new LinqToAstoriaKeyExpression(source, key, source.ExpressionType)); }
private static IList <ImplementationNameAttribute> GetImplementationsBySelectorName(string selectorName, IEnumerable <Type> typeClosure) { List <ImplementationNameAttribute> implementations = new List <ImplementationNameAttribute>(); Type foundContractType = null; foreach (Type type in typeClosure) { var isa = PlatformHelper.GetCustomAttribute <ImplementationSelectorAttribute>(type, false); if (isa != null && isa.TestArgumentName == selectorName) { foundContractType = type; break; } } if (foundContractType == null) { throw new TaupoInfrastructureException(string.Format(CultureInfo.InvariantCulture, "Unable to find selector with name '{0}'", selectorName)); } foreach (Type type in typeClosure) { var isva = PlatformHelper.GetCustomAttribute <ImplementationNameAttribute>(type, false); if (isva != null) { if (isva.ContractType == foundContractType) { ExceptionUtilities.CheckObjectNotNull(isva.ImplementationName, "Implementation Name of ImplementationType '{0}' must not be null", type.Name); implementations.Add(isva); } } } ExceptionUtilities.CheckCollectionNotEmpty(implementations, "implementations"); return(implementations); }
/// <summary> /// Predefined data generator which selects a value from a predefined set of values /// </summary> /// <typeparam name="TData">The data type</typeparam> /// <param name="random">A Random number generator to allow the framework to pick a random value from the set of values</param> /// <param name="values">The set of allowed values</param> /// <returns>predefined data generator</returns> public static IDataGenerator <TData> PredefinedValues <TData>(IRandomNumberGenerator random, params TData[] values) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckCollectionNotEmpty(values, "values"); return(new DelegatedDataGenerator <TData>(() => random.ChooseFrom(values))); }
/// <summary> /// Deserializes a collection property /// </summary> /// <param name="propertyElement">The xml element representing the property</param> /// <returns>The deserialized property</returns> private PropertyInstance DeserializeCollectionProperty(XElement propertyElement) { ExceptionUtilities.CheckArgumentNotNull(propertyElement, "propertyElement"); ExceptionUtilities.CheckCollectionNotEmpty(propertyElement.Elements(), "propertyElement.Elements()"); ExceptionUtilities.Assert(propertyElement.Elements().All(e => e.Name == DataServicesElement), "Collection property sub elements had inconsistent names"); string propertyName = propertyElement.Name.LocalName; string fullTypeName = null; string bagElementTypeName = null; var type = propertyElement.Attribute(MetadataType); if (type != null) { fullTypeName = type.Value; bagElementTypeName = ParseBagElementTypeName(type.Value); } // convert the elements first, then decide if its a primitive or complex collection // note that a collection containing all null values will appear as a primitive collection, regardless of what the type really is List <PropertyInstance> elements = null; if (bagElementTypeName != null) { elements = propertyElement.Elements().Select(e => this.DeserializeProperty(e, bagElementTypeName)).ToList(); } else { elements = propertyElement.Elements().Select(e => this.DeserializeProperty(e)).ToList(); } if (elements.OfType <ComplexProperty>().Any()) { var complex = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(fullTypeName, false)); foreach (var complexElement in elements) { if (complexElement.ElementType == ODataPayloadElementType.NullPropertyInstance) { var nullProperty = complexElement as NullPropertyInstance; complex.Value.Add(new ComplexInstance(nullProperty.FullTypeName, true)); } else { ExceptionUtilities.Assert(complexElement.ElementType == ODataPayloadElementType.ComplexProperty, "Complex value collection contained non-complex, non-null value"); complex.Value.Add((complexElement as ComplexProperty).Value); } } return(complex); } else { var primitive = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(fullTypeName, false)); foreach (var primitiveElement in elements) { if (primitiveElement.ElementType == ODataPayloadElementType.NullPropertyInstance) { var nullProperty = primitiveElement as NullPropertyInstance; primitive.Value.Add(new PrimitiveValue(nullProperty.FullTypeName, null)); } else { ExceptionUtilities.Assert(primitiveElement.ElementType == ODataPayloadElementType.PrimitiveProperty, "Primitive value collection contained non-primitive, non-null value"); primitive.Value.Add((primitiveElement as PrimitiveProperty).Value); } } return(primitive); } }