private Expression BuildProjector(Expression selector, ProjectionBindingContext context) { var selectorNode = selector; if (!(selectorNode is ISerializationExpression)) { var serializer = SerializerBuilder.Build(selector, context.SerializerRegistry); BsonSerializationInfo info; switch (selector.NodeType) { case ExpressionType.MemberInit: case ExpressionType.New: info = new BsonSerializationInfo(null, serializer, serializer.ValueType); break; default: // this occurs when a computed field is used. This is a magic string // that shouldn't ever be reference anywhere else... info = new BsonSerializationInfo("__fld0", serializer, serializer.ValueType); break; } selectorNode = new SerializationExpression(selector, info); } return selectorNode; }
public override Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { LambdaExpression aggregator; if (node.Method.Name.EndsWith("Async")) { aggregator = CreateAsyncAggregator(); } else { aggregator = CreateSyncAggregator(); } var source = projection.Source; var argument = arguments.FirstOrDefault(); if (argument != null && ExtensionExpressionVisitor.IsLambda(argument)) { source = BindPredicate(projection, context, source, argument); } source = new TakeExpression(source, 1); var serializer = context.SerializerRegistry.GetSerializer(typeof(int)); var accumulator = new AccumulatorExpression(typeof(int), AccumulatorType.Count, null); var serializationAccumulator = new SerializationExpression( accumulator, new BsonSerializationInfo("__agg0", serializer, serializer.ValueType)); var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator); return new ProjectionExpression( rootAccumulator, serializationAccumulator, aggregator); }
public override Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { // OfType is two operations in one. First we create WhereExpression // for the test. Second, we want to issue a conversion projection // using the selector parameter of a ProjectionExpression such that // the conversion will be propogated to all future expressions. var newType = node.Method.GetGenericArguments()[0]; var parameter = Expression.Parameter(projection.Projector.Type); var predicate = Expression.Lambda( Expression.TypeIs(parameter, newType), parameter); var source = BindPredicate(projection, context, projection.Source, predicate); var serializer = context.SerializerRegistry.GetSerializer(newType); var info = new BsonSerializationInfo(null, serializer, newType); var projector = new SerializationExpression( Expression.Convert(projection.Projector, newType), info); return new ProjectionExpression( source, projector); }
protected override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.ElementName != null) { _serializationExpressions.Add(node); } return(node); }
public PipelineExpression(Expression source, SerializationExpression projector, ResultOperator resultOperator) { _source = Ensure.IsNotNull(source, nameof(source)); _projector = Ensure.IsNotNull(projector, nameof(projector)); _resultOperator = resultOperator; _type = _resultOperator == null ? typeof(IEnumerable<>).MakeGenericType(_projector.Type) : _resultOperator.Type; }
public PipelineExpression Update(Expression source, SerializationExpression projector, ResultOperator resultOperator) { if (source != _source || projector != _projector || resultOperator != _resultOperator) { return new PipelineExpression(source, projector, resultOperator); } return this; }
public PipelineExpression Update(Expression source, SerializationExpression projector, ResultOperator resultOperator) { if (source != _source || projector != _projector || resultOperator != _resultOperator) { return(new PipelineExpression(source, projector, resultOperator)); } return(this); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var distinct = new DistinctExpression(projection.Source, projection.Projector); var serializer = SerializerBuilder.Build(projection.Projector, context.SerializerRegistry); var info = new BsonSerializationInfo("_id", serializer, serializer.ValueType); var projector = new SerializationExpression(projection.Projector, info); return new ProjectionExpression( distinct, projector); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var collectionLambda = ExtensionExpressionVisitor.GetLambda(arguments.First()); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(collectionLambda.Parameters[0], projection.Projector); var collectionSelector = binder.Bind(collectionLambda.Body) as SerializationExpression; if (collectionSelector == null) { var message = string.Format("Unable to determine the collection selector in the tree: {0}", node.ToString()); throw new NotSupportedException(message); } var collectionArraySerializer = collectionSelector.SerializationInfo.Serializer as IBsonArraySerializer; BsonSerializationInfo collectionItemSerializationInfo; if (collectionArraySerializer == null || !collectionArraySerializer.TryGetItemSerializationInfo(out collectionItemSerializationInfo)) { var message = string.Format("The collection selector's serializer must implement IBsonArraySerializer: {0}", node.ToString()); throw new NotSupportedException(message); } Expression resultSelector; if (arguments.Count() == 2) { var resultLambda = ExtensionExpressionVisitor.GetLambda(arguments.Last()); binder.RegisterParameterReplacement(resultLambda.Parameters[0], projection.Projector); binder.RegisterParameterReplacement( resultLambda.Parameters[1], new SerializationExpression( resultLambda.Parameters[1], collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName))); resultSelector = binder.Bind(resultLambda.Body); } else { resultSelector = new SerializationExpression( collectionSelector, collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName)); } var projector = BuildProjector(resultSelector, context); return new ProjectionExpression( new SelectManyExpression( projection.Source, collectionSelector, resultSelector), projector); }
public PipelineExpression(Expression source, SerializationExpression projector, ResultOperator resultOperator) { _source = Ensure.IsNotNull(source, nameof(source)); _projector = Ensure.IsNotNull(projector, nameof(projector)); _resultOperator = resultOperator; if (_resultOperator == null) { _serializer = SerializerHelper.CreateEnumerableSerializer(_projector.Serializer); _type = typeof(IEnumerable<>).MakeGenericType(_projector.Type); } else { _serializer = _resultOperator.Serializer; _type = _resultOperator.Type; } }
public PipelineExpression(Expression source, SerializationExpression projector, ResultOperator resultOperator) { _source = Ensure.IsNotNull(source, nameof(source)); _projector = Ensure.IsNotNull(projector, nameof(projector)); _resultOperator = resultOperator; if (_resultOperator == null) { _serializer = SerializerHelper.CreateEnumerableSerializer(_projector.Serializer); _type = typeof(IEnumerable <>).MakeGenericType(_projector.Type); } else { _serializer = _resultOperator.Serializer; _type = _resultOperator.Type; } }
private GroupIdExpression BindId(ProjectionExpression projection, ProjectionBindingContext context, Expression node) { var lambda = ExtensionExpressionVisitor.GetLambda(node); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var selector = binder.Bind(lambda.Body); if (!(selector is ISerializationExpression)) { var serializer = SerializerBuilder.Build(selector, context.SerializerRegistry); selector = new SerializationExpression( selector, new BsonSerializationInfo(null, serializer, serializer.ValueType)); } return new GroupIdExpression(selector, ((ISerializationExpression)selector).SerializationInfo); }
public override Expression Bind(Expressions.ProjectionExpression projection, ProjectionBindingContext context, System.Linq.Expressions.MethodCallExpression node, IEnumerable<System.Linq.Expressions.Expression> arguments) { var aggregatorName = "Single"; var returnType = node.Method.ReturnType; if (node.Method.Name.EndsWith("Async")) { aggregatorName += "Async"; returnType = returnType.GetGenericArguments()[0]; } var aggregator = CreateAggregator(aggregatorName, returnType); var source = projection.Source; var argument = arguments.FirstOrDefault(); if (argument != null && ExtensionExpressionVisitor.IsLambda(argument)) { var lambda = ExtensionExpressionVisitor.GetLambda(argument); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); argument = binder.Bind(lambda.Body); } else { argument = projection.Projector; var select = source as SelectExpression; if (select != null) { source = select.Source; } } var serializer = context.SerializerRegistry.GetSerializer(returnType); var accumulator = new AccumulatorExpression(returnType, AccumulatorType, argument); var serializationAccumulator = new SerializationExpression( accumulator, new BsonSerializationInfo("__agg0", serializer, serializer.ValueType)); var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator); return new ProjectionExpression( rootAccumulator, serializationAccumulator, aggregator); }
protected internal override Expression VisitCorrelatedGroupBy(CorrelatedGroupByExpression node) { if (_lookup != null && _lookup.Contains(node.CorrelationId)) { var source = Visit(node.Source); var accumulators = new List<SerializationExpression>(); var comparer = new ExpressionComparer(); foreach (var correlatedAccumulator in _lookup[node.CorrelationId]) { var index = accumulators.FindIndex(x => comparer.Compare(x.Expression, correlatedAccumulator.Accumulator)); if (index == -1) { var serializer = _serializerRegistry.GetSerializer(correlatedAccumulator.Type); var info = new BsonSerializationInfo( "__agg" + accumulators.Count, serializer, serializer.ValueType); var serializationExpression = new SerializationExpression(correlatedAccumulator.Accumulator, info); accumulators.Add(serializationExpression); _map[correlatedAccumulator] = serializationExpression; } else { _map[correlatedAccumulator] = accumulators[index]; } } node = node.Update( source, node.Id, accumulators.OfType<Expression>()); } return base.VisitCorrelatedGroupBy(node); }
private Expression BindSelector(ProjectionExpression projection, ProjectionBindingContext context, Expression id, Expression node) { var lambda = ExtensionExpressionVisitor.GetLambda(node); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); var serializer = SerializerBuilder.Build(projection.Projector, context.SerializerRegistry); var sequenceSerializer = (IBsonSerializer)Activator.CreateInstance( typeof(ArraySerializer<>).MakeGenericType(projection.Projector.Type), new object[] { serializer }); var sequenceInfo = new BsonSerializationInfo( null, sequenceSerializer, sequenceSerializer.ValueType); var sequenceExpression = new SerializationExpression( lambda.Parameters[1], sequenceInfo); binder.RegisterParameterReplacement(lambda.Parameters[0], id); binder.RegisterParameterReplacement(lambda.Parameters[1], sequenceExpression); var correlationId = Guid.NewGuid(); context.GroupMap.Add(sequenceExpression, correlationId); var bound = binder.Bind(lambda.Body); return CorrelatedAccumulatorRemover.Remove(bound, correlationId); }
protected internal override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.ElementName != null && node.SerializationInfo.ElementName.StartsWith(_oldName)) { return new SerializationExpression( node.Expression, node.SerializationInfo.WithNewName(GetReplacementName(node.SerializationInfo.ElementName))); } return base.VisitSerialization(node); }
public PipelineExpression(Expression source, SerializationExpression projector) : this(source, projector, null) { }
protected internal override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.Serializer.ValueType == _valueType) { _serializer = node.SerializationInfo.Serializer; return node; } return base.VisitSerialization(node); }
private BsonClassMap BuildClassMap(Type type, ProjectionMapping mapping) { if (type == null || type == typeof(object)) { return null; } var baseClassMap = BuildClassMap(type.BaseType, mapping); if (baseClassMap != null) { baseClassMap.Freeze(); } var classMap = new BsonClassMap(type, baseClassMap); foreach (var memberMapping in mapping.Members.Where(x => x.Member.DeclaringType == type)) { var serializationExpression = memberMapping.Expression as ISerializationExpression; if (serializationExpression == null) { var serializer = Build(memberMapping.Expression); var serializationInfo = new BsonSerializationInfo( memberMapping.Member.Name, serializer, GetMemberType(memberMapping.Member)); serializationExpression = new SerializationExpression( memberMapping.Expression, serializationInfo); } var memberMap = classMap.MapMember(memberMapping.Member) .SetSerializer(serializationExpression.SerializationInfo.Serializer) .SetElementName(memberMapping.Member.Name); if (classMap.IdMemberMap == null && serializationExpression is GroupIdExpression) { classMap.SetIdMember(memberMap); } } return classMap; }
protected internal virtual Expression VisitSerialization(SerializationExpression node) { return(node.Update(Visit(node.Expression))); }
protected virtual Expression VisitSerialization(SerializationExpression node) { return(node); }
private bool CompareSerialization(SerializationExpression a, SerializationExpression b) { return(Compare(a.Expression, b.Expression)); }
protected internal virtual Expression VisitSerialization(SerializationExpression node) { return node.Update(Visit(node.Expression)); }
private BsonValue BuildSerialization(SerializationExpression node) { if (string.IsNullOrWhiteSpace(node.SerializationInfo.ElementName)) { return BuildValue(node.Expression); } return "$" + node.SerializationInfo.ElementName; }