Skip to content

Commit 92d5316

Browse files
committed
CSHARP-5572: Work in progress
1 parent adf84bd commit 92d5316

File tree

3 files changed

+56
-20
lines changed

3 files changed

+56
-20
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/KnownSerializerFinders/KnownSerializerFinderVisitMember.cs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
using System.Collections;
1818
using System.Collections.Generic;
1919
using System.Linq.Expressions;
20-
using System.Reflection;
2120
using MongoDB.Bson;
2221
using MongoDB.Bson.Serialization;
2322
using MongoDB.Bson.Serialization.Options;
2423
using MongoDB.Bson.Serialization.Serializers;
2524
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
26-
using MongoDB.Driver.Support;
25+
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
2726

2827
namespace MongoDB.Driver.Linq.Linq3Implementation.KnownSerializerFinders;
2928

@@ -50,6 +49,8 @@ protected override Expression VisitMember(MemberExpression node)
5049
_ when declaringType == typeof(BsonValue) => GetBsonValuePropertySerializer(),
5150
_ when IsCollectionCountOrLengthProperty() => GetCollectionCountOrLengthPropertySerializer(),
5251
_ when declaringType == typeof(DateTime) => GetDateTimePropertySerializer(),
52+
_ when declaringType.IsConstructedGenericType && declaringType.GetGenericTypeDefinition() == typeof(Dictionary<,>) => GetDictionaryPropertySerializer(),
53+
_ when declaringType.IsConstructedGenericType && declaringType.GetGenericTypeDefinition() == typeof(IDictionary<,>) => GetIDictionaryPropertySerializer(),
5354
_ when declaringType.IsNullable() => GetNullablePropertySerializer(),
5455
_ when IsTupleOrValueTuple(declaringType) => GetTupleOrValueTuplePropertySerializer(),
5556
_ => GetPropertySerializer()
@@ -136,6 +137,42 @@ IBsonSerializer GetDateTimePropertySerializer()
136137
};
137138
}
138139

140+
IBsonSerializer GetDictionaryPropertySerializer()
141+
{
142+
if (containingSerializer.Unwrapped() is not IBsonDictionarySerializer dictionarySerializer)
143+
{
144+
throw new ExpressionNotSupportedException(node, because: "DictionarySerializer does not implement IBsonDictionarySerializer");
145+
}
146+
147+
var keySerializer = dictionarySerializer.KeySerializer;
148+
var valueSerializer = dictionarySerializer.ValueSerializer;
149+
150+
return memberName switch
151+
{
152+
"Keys" => DictionaryKeyCollectionSerializer.Create(keySerializer, valueSerializer),
153+
"Values" => DictionaryValueCollectionSerializer.Create(keySerializer, valueSerializer),
154+
_ => throw new ExpressionNotSupportedException(node, because: $"Unexpected member name: {memberName}")
155+
};
156+
}
157+
158+
IBsonSerializer GetIDictionaryPropertySerializer()
159+
{
160+
if (containingSerializer is not IBsonDictionarySerializer dictionarySerializer)
161+
{
162+
throw new ExpressionNotSupportedException(node, because: "IDictionarySerializer does not implement IBsonDictionarySerializer");
163+
}
164+
165+
var keySerializer = dictionarySerializer.KeySerializer;
166+
var valueSerializer = dictionarySerializer.ValueSerializer;
167+
168+
return memberName switch
169+
{
170+
"Keys" => ICollectionSerializer.Create(keySerializer),
171+
"Values" => ICollectionSerializer.Create(valueSerializer),
172+
_ => throw new ExpressionNotSupportedException(node, because: $"Unexpected member name: {memberName}")
173+
};
174+
}
175+
139176
IBsonSerializer GetNullablePropertySerializer()
140177
{
141178
return memberName switch

src/MongoDB.Driver/Linq/Linq3Implementation/KnownSerializerFinders/KnownSerializerFinderVisitMethodCall.cs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,6 @@ void DeduceMethodCallSerializers()
794794
case "Atan": DeduceAtanMethodSerializers(); break;
795795
case "Atanh": DeduceAtanhMethodSerializers(); break;
796796
case "Atan2": DeduceAtan2MethodSerializers(); break;
797-
case "CompareTo": DeduceCompareToMethodSerializers(); break;
798797
case "Concat": DeduceConcatMethodSerializers(); break;
799798
case "Constant": DeduceConstantMethodSerializers(); break;
800799
case "Contains": DeduceContainsMethodSerializers(); break;
@@ -889,6 +888,11 @@ void DeduceMethodCallSerializers()
889888
DeduceCeilingOrFloorMethodSerializers();
890889
break;
891890

891+
case "Compare":
892+
case "CompareTo":
893+
DeduceCompareOrCompareToMethodSerializers();
894+
break;
895+
892896
case "Count":
893897
case "LongCount":
894898
DeduceCountMethodSerializers();
@@ -1440,31 +1444,21 @@ void DeduceCeilingOrFloorMethodSerializers()
14401444
}
14411445
}
14421446

1443-
void DeduceCompareToMethodSerializers()
1447+
void DeduceCompareOrCompareToMethodSerializers()
14441448
{
1445-
if (IsCompareToMethod())
1449+
if (method.IsStaticCompareMethod() ||
1450+
method.IsInstanceCompareToMethod() ||
1451+
method.IsOneOf(StringMethod.StaticCompare, StringMethod.StaticCompareWithIgnoreCase))
14461452
{
1447-
var objectExpression = node.Object;
1448-
var valueExpression = arguments[0];
1449-
1450-
DeduceSerializers(objectExpression, valueExpression);
1453+
var valueExpression = method.IsStatic ? arguments[0] : node.Object;
1454+
var comparandExpression = method.IsStatic ? arguments[1] : arguments[0];
1455+
DeduceSerializers(valueExpression, comparandExpression);
14511456
DeduceReturnsInt32Serializer();
14521457
}
14531458
else
14541459
{
14551460
DeduceUnknownMethodSerializer();
14561461
}
1457-
1458-
bool IsCompareToMethod()
1459-
{
1460-
return
1461-
method.IsPublic &&
1462-
method.IsStatic == false &&
1463-
method.ReturnType == typeof(int) &&
1464-
method.Name == "CompareTo" &&
1465-
arguments.Count == 1 &&
1466-
arguments[0].Type == node.Object.Type;
1467-
}
14681462
}
14691463

14701464
void DeduceConcatMethodSerializers()

src/MongoDB.Driver/Linq/Linq3Implementation/Misc/IBsonSerializerExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,9 @@ serializer is IBsonDocumentSerializer documentSerializer &&
157157
valueSerializer = null;
158158
return false;
159159
}
160+
161+
public static IBsonSerializer Unwrapped(this IBsonSerializer serializer)
162+
{
163+
return serializer is IWrappedValueSerializer wrappedValueSerializer ? wrappedValueSerializer.ValueSerializer.Unwrapped() : serializer;
164+
}
160165
}

0 commit comments

Comments
 (0)