public QueryableBuilder(Expression source, Type elementType, Type extensionType, LambdaParameterNameFactory nameFactory, IResourceFactory resourceFactory, IResourceContextProvider resourceContextProvider, IModel entityModel, LambdaScopeFactory lambdaScopeFactory = null) { _source = source ?? throw new ArgumentNullException(nameof(source)); _elementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); _extensionType = extensionType ?? throw new ArgumentNullException(nameof(extensionType)); _nameFactory = nameFactory ?? throw new ArgumentNullException(nameof(nameFactory)); _resourceFactory = resourceFactory ?? throw new ArgumentNullException(nameof(resourceFactory)); _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); _entityModel = entityModel ?? throw new ArgumentNullException(nameof(entityModel)); _lambdaScopeFactory = lambdaScopeFactory ?? new LambdaScopeFactory(_nameFactory); }
private MemberAssignment CreatePropertyAssignment(PropertySelector selector, LambdaScope lambdaScope) { MemberExpression propertyAccess = Expression.Property(lambdaScope.Accessor, selector.Property); Expression assignmentRightHandSide = propertyAccess; if (selector.NextLayer != null) { HasManyThroughAttribute hasManyThrough = selector.OriginatingField as HasManyThroughAttribute; var lambdaScopeFactory = new LambdaScopeFactory(_nameFactory, hasManyThrough); assignmentRightHandSide = CreateAssignmentRightHandSideForLayer(selector.NextLayer, lambdaScope, propertyAccess, selector.Property, lambdaScopeFactory); } return(Expression.Bind(selector.Property, assignmentRightHandSide)); }
private Expression CreateCollectionInitializer(LambdaScope lambdaScope, PropertyInfo collectionProperty, Type elementType, QueryLayer layer, LambdaScopeFactory lambdaScopeFactory) { MemberExpression propertyExpression = Expression.Property(lambdaScope.Accessor, collectionProperty); var builder = new QueryableBuilder(propertyExpression, elementType, typeof(Enumerable), _nameFactory, _resourceFactory, _resourceContextProvider, _entityModel, lambdaScopeFactory); Expression layerExpression = builder.ApplyQuery(layer); Type enumerableOfElementType = typeof(IEnumerable <>).MakeGenericType(elementType); Type typedCollection = collectionProperty.PropertyType.ToConcreteCollectionType(); ConstructorInfo typedCollectionConstructor = typedCollection.GetConstructor(new[] { enumerableOfElementType }); if (typedCollectionConstructor == null) { throw new Exception( $"Constructor on '{typedCollection.Name}' that accepts '{enumerableOfElementType.Name}' not found."); } return(Expression.New(typedCollectionConstructor, layerExpression)); }
private Expression CreateAssignmentRightHandSideForLayer(QueryLayer layer, LambdaScope outerLambdaScope, MemberExpression propertyAccess, PropertyInfo selectorPropertyInfo, LambdaScopeFactory lambdaScopeFactory) { Type collectionElementType = TypeHelper.TryGetCollectionElementType(selectorPropertyInfo.PropertyType); Type bodyElementType = collectionElementType ?? selectorPropertyInfo.PropertyType; if (collectionElementType != null) { return(CreateCollectionInitializer(outerLambdaScope, selectorPropertyInfo, bodyElementType, layer, lambdaScopeFactory)); } if (layer.Projection == null || !layer.Projection.Any()) { return(propertyAccess); } using var scope = lambdaScopeFactory.CreateScope(bodyElementType, propertyAccess); return(CreateLambdaBodyInitializer(layer.Projection, layer.ResourceContext, scope, true)); }