private static bool TryTranslateDateTimeProperty(MemberExpression expression, AggregationExpression container, MemberInfo memberInfo, out AggregationExpression result) { result = null; if (container.Expression.Type == typeof(DateTime) && memberInfo is PropertyInfo propertyInfo) { AstExpression ast; IBsonSerializer serializer; if (propertyInfo.Name == "DayOfWeek") { ast = AstExpression.Subtract(AstExpression.DatePart(AstDatePart.DayOfWeek, container.Ast), 1); serializer = new EnumSerializer <DayOfWeek>(BsonType.Int32); } else { AstDatePart datePart; switch (propertyInfo.Name) { case "Day": datePart = AstDatePart.DayOfMonth; break; case "DayOfWeek": datePart = AstDatePart.DayOfWeek; break; case "DayOfYear": datePart = AstDatePart.DayOfYear; break; case "Hour": datePart = AstDatePart.Hour; break; case "Millisecond": datePart = AstDatePart.Millisecond; break; case "Minute": datePart = AstDatePart.Minute; break; case "Month": datePart = AstDatePart.Month; break; case "Second": datePart = AstDatePart.Second; break; case "Week": datePart = AstDatePart.Week; break; case "Year": datePart = AstDatePart.Year; break; default: return(false); } ast = AstExpression.DatePart(datePart, container.Ast); serializer = new Int32Serializer(); } result = new AggregationExpression(expression, ast, serializer); return(true); } return(false); }
public static AggregationExpression Translate(TranslationContext context, MemberExpression expression) { var containerExpression = expression.Expression; var member = expression.Member; if (member is PropertyInfo property) { switch (property.Name) { case "HasValue": return(HasValuePropertyToAggregationExpressionTranslator.Translate(context, expression)); case "Value": return(ValuePropertyToAggregationExpressionTranslator.Translate(context, expression)); default: break; } } var containerTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, containerExpression); if (containerTranslation.Serializer is IWrappedValueSerializer wrappedValueSerializer) { var unwrappedValueAst = AstExpression.GetField(containerTranslation.Ast, wrappedValueSerializer.FieldName); containerTranslation = new AggregationExpression(expression, unwrappedValueAst, wrappedValueSerializer.ValueSerializer); } if (!DocumentSerializerHelper.HasFieldInfo(containerTranslation.Serializer, member.Name)) { if (member is PropertyInfo propertyInfo && propertyInfo.Name == "Length") { return(LengthPropertyToAggregationExpressionTranslator.Translate(context, expression)); } if (TryTranslateCollectionCountProperty(expression, containerTranslation, member, out var translatedCount)) { return(translatedCount); } if (TryTranslateDateTimeProperty(expression, containerTranslation, member, out var translatedDateTimeProperty)) { return(translatedDateTimeProperty); } } var fieldInfo = DocumentSerializerHelper.GetFieldInfo(containerTranslation.Serializer, member.Name); var ast = AstExpression.GetField(containerTranslation.Ast, fieldInfo.ElementName); return(new AggregationExpression(expression, ast, fieldInfo.Serializer)); }
private static bool TryTranslateCollectionCountProperty(MemberExpression expression, AggregationExpression container, MemberInfo memberInfo, out AggregationExpression result) { result = null; var memberName = memberInfo.Name; if ((memberName == "Count" || memberName == "LongCount") && memberInfo is PropertyInfo propertyInfo) { var containerType = container.Expression.Type; if (containerType.Implements(typeof(ICollection)) || containerType.Implements(typeof(ICollection <>))) { var ast = AstExpression.Size(container.Ast); var serializer = BsonSerializer.LookupSerializer(propertyInfo.PropertyType); result = new AggregationExpression(expression, ast, serializer); return(true); } } return(false); }