public object[] GetContinuationToken(IEnumerator enumerator) { CountingEnumerator countingEnumerator = enumerator as CountingEnumerator; if (countingEnumerator != null) { return(countingEnumerator.GetSkipToken(this.resourceQueryProvider)); } return(null); }
private object WrapEnumerables(object resource) { if (IsExpandedWrapperInstance(resource)) { IQueryable collectionPropertyQueryable = (resource.GetType().GetProperty("ProjectedProperty0").GetValue(resource, null) as IEnumerable).AsQueryable(); Type collectionElementType = collectionPropertyQueryable.ElementType; object expandedElement = resource.GetType().GetProperty("ExpandedElement").GetValue(resource, null); string description = (string)resource.GetType().GetProperty("Description").GetValue(resource, null); ResourceProperty expandedProperty = this.resourceType.Properties.First(p => p.Name == description); ParameterExpression innerParam = Expression.Parameter(collectionElementType, "inner"); PropertyInfo keyProperty = collectionElementType.GetProperties().First(p => p.Name.Contains("ID")); Expression propertyAccess = Expression.Property( innerParam, keyProperty); Expression innerExpression = Expression.Call( typeof(Queryable), "OrderBy", new Type[] { collectionElementType, keyProperty.PropertyType }, Expression.Constant(collectionPropertyQueryable), Expression.Lambda(propertyAccess, innerParam)); collectionPropertyQueryable = collectionPropertyQueryable.Provider.CreateQuery(innerExpression); object value = typeof(CountingEnumerator) .GetMethod("CreateCountingEnumerator", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(collectionElementType) .Invoke(null, new object[] { collectionPropertyQueryable, expandedProperty.ResourceType, this.cm }); object clone = Activator.CreateInstance(resource.GetType()); clone.GetType().GetProperty("ExpandedElement").SetValue(clone, expandedElement, null); clone.GetType().GetProperty("Description").SetValue(clone, description, null); clone.GetType().GetProperty("ProjectedProperty0").SetValue(clone, value, null); return(clone); } else if (this.IsReflectableResourceType && typeof(Customer).IsAssignableFrom(resource.GetType())) { PropertyInfo collectionProperty = resource.GetType().GetProperties().First(p => IsCollectionProperty(p)); IQueryable collectionPropertyQueryable = (collectionProperty.GetValue(resource, null) as IEnumerable).AsQueryable(); Type collectionElementType = AstoriaUnitTests.TypeUtils.GetElementType(collectionProperty.PropertyType); ParameterExpression innerParam = Expression.Parameter(collectionElementType, "inner"); PropertyInfo keyProperty = collectionElementType.GetProperties().First(p => p.Name.Contains("ID")); Expression propertyAccess = Expression.Property( innerParam, keyProperty); Expression innerExpression = Expression.Call( typeof(Queryable), "OrderBy", new Type[] { collectionElementType, keyProperty.PropertyType }, Expression.Constant(collectionPropertyQueryable), Expression.Lambda(propertyAccess, innerParam)); collectionPropertyQueryable = collectionPropertyQueryable.Provider.CreateQuery(innerExpression); object value = typeof(CountingEnumerator) .GetMethod("CreateCountingEnumerator", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(collectionElementType) .Invoke(null, new object[] { collectionPropertyQueryable, null, this.cm }); object clone = GetClone(resource); collectionProperty.SetValue(clone, value, null); return(clone); } else { RowEntityTypeWithIDAsKey row = resource as RowEntityTypeWithIDAsKey; if (row == null) { return(resource); } RowEntityTypeWithIDAsKey newRow = new RowEntityTypeWithIDAsKey(row.TypeName); newRow.ID = row.ID; foreach (KeyValuePair <string, object> kv in row.Properties) { ResourceProperty property = this.resourceType.Properties.FirstOrDefault(p => p.Name == kv.Key); if (property != null && property.Kind == ResourcePropertyKind.ResourceSetReference) { IEnumerable enumerable = kv.Value as IEnumerable; if (enumerable == null) { newRow.Properties.Add(kv); } else { IQueryable queryable = enumerable.AsQueryable(); ParameterExpression innerParam = Expression.Parameter(property.ResourceType.InstanceType, "inner"); ResourceProperty keyProperty = property.ResourceType.KeyProperties[0]; Expression propertyAccess = keyProperty.CanReflectOnInstanceTypeProperty ? (Expression)Expression.Property( innerParam, property.ResourceType.InstanceType.GetProperty(keyProperty.Name)) : (Expression)Expression.Convert(Expression.Call( Expression.Property(innerParam, "Properties"), Expression.Property(innerParam, "Properties").Type.GetProperty("Item").GetGetMethod(), Expression.Constant(keyProperty.Name)), keyProperty.ResourceType.InstanceType); Expression innerExpression = Expression.Call( typeof(Queryable), "OrderBy", new Type[] { property.ResourceType.InstanceType, property.ResourceType.KeyProperties[0].ResourceType.InstanceType }, Expression.Constant(queryable), Expression.Lambda(propertyAccess, innerParam)); queryable = queryable.Provider.CreateQuery(innerExpression); object value = new CountingEnumerator(queryable, property.ResourceType, this.cm); newRow.Properties.Add(kv.Key, value); } } else { newRow.Properties[kv.Key] = kv.Value; } } return(newRow); } }