Beispiel #1
0
        private static void ApplyPredicate <TEntity, TForeign>(AggregateQueryable <TEntity> aggregateQueryable, Expression predicate, string asFieldName)
        {
            if (predicate == null)
            {
                return;
            }

            var foreignType  = typeof(TForeign);
            var isEnumerable = typeof(TForeign).IsEnumerable();

            if (isEnumerable)
            {
                foreignType = foreignType.GetElementTypeOf();
            }

            //lamb = Expression.Lambda(methodCall.Arguments[0], Expression.Parameter(typeof(TEntity), "p"));
            var filterDefinitionBuilder = new FilterDefinitionBuilder <TEntity>();
            var param1Type = typeof(FieldDefinition <TEntity>);
            var param2Type = typeof(FilterDefinition <>).MakeGenericType(foreignType);

            var method = filterDefinitionBuilder.GetType()
                         .GetGenericMethod(nameof(filterDefinitionBuilder.ElemMatch), BindingFlags.Public | BindingFlags.Instance,
                                           new[] { foreignType }, new[] { param1Type, param2Type }, typeof(FilterDefinition <TEntity>));

            var expressionFilterDefinition = Activator.CreateInstance(typeof(ExpressionFilterDefinition <>).MakeGenericType(foreignType), predicate);
            var asField = new StringFieldDefinition <TEntity>(asFieldName);

            var elmMatch = (FilterDefinition <TEntity>)method.Invoke(filterDefinitionBuilder, new object[] { asField, expressionFilterDefinition });

            //Filter ($match) elements of TForeign using predicate
            aggregateQueryable.AggregateFluent = aggregateQueryable.AggregateFluent.Match(elmMatch);
        }
Beispiel #2
0
        private static void ApplyLookup <TEntity, TDeclaring, TProperty>(AggregateQueryable <TEntity> aggregateQueryable,
                                                                         MemberInfo navigationMember, string previousNavigationName, out string navigationElementName, out string asFieldName)
        {
            var declaringType = typeof(TDeclaring);
            var propertyType  = typeof(TProperty);
            var isEnumerable  = propertyType.IsEnumerable();

            if (isEnumerable)
            {
                propertyType = propertyType.GetElementTypeOf();
            }

            var associatedMember      = AssociatedMemberFinder.GetAssociatedMember(navigationMember);
            var associatedElementName = associatedMember.GetBsonElementName();

            var elementName = navigationMember.Name;

            navigationElementName = AppendPreviousNavigationName(elementName);
            asFieldName           = AppendPreviousNavigationName(isEnumerable ? elementName : $"__{elementName}__");

            var    collectioName = CollectionNameFinder.GetCollectionName(propertyType);
            string localField;
            string foreignField;

            var isInside = associatedMember.DeclaringType == declaringType;

            if (isInside)
            {
                localField   = AppendPreviousNavigationName(associatedElementName);
                foreignField = BsonClassMap.LookupClassMap(propertyType).IdMemberMap.ElementName;
            }
            else
            {
                localField   = BsonClassMap.LookupClassMap(declaringType).IdMemberMap.ElementName;
                foreignField = AppendPreviousNavigationName(associatedElementName);
            }

            aggregateQueryable.AggregateFluent = aggregateQueryable.AggregateFluent
                                                 .Lookup <TProperty, TDeclaring>(collectioName, localField, foreignField, asFieldName)
                                                 .As <TEntity>();

            string AppendPreviousNavigationName(string input)
            {
                if (previousNavigationName == null)
                {
                    return(input);
                }
                return(previousNavigationName + "." + input);
            }
        }
Beispiel #3
0
        private static void ApplyProjection <TEntity, TProperty>(AggregateQueryable <TEntity> aggregateQueryable, string asFieldName, string navigationElementName)
        {
            var isEnumerable = typeof(TProperty).IsEnumerable();

            if (!isEnumerable)
            {
                //Set first element as navigation field
                PipelineStageDefinition <TEntity, TEntity> addFields = "{ \"$addFields\": { \"" + navigationElementName + "\": { \"$arrayElemAt\": [\"$" + asFieldName + "\", 0] } } }";
                //Exclude temp @as field
                PipelineStageDefinition <TEntity, TEntity> project = "{ \"$project\" : { \"" + asFieldName + "\" : 0 } }";

                aggregateQueryable.AggregateFluent = aggregateQueryable.AggregateFluent
                                                     .AppendStage(addFields)
                                                     .AppendStage(project);
            }
        }
 public AggregateQueryableIncluded(AggregateQueryable <TEntity> aggregateQueryable, string navigationElementName)
     : base(aggregateQueryable)
 {
     NavigationElementName = navigationElementName.NotNull(nameof(navigationElementName));
 }