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);
 }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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));
        }