Skip to content

Commit 98538f6

Browse files
committed
CSHARP-1604: support downcasting.
1 parent b536191 commit 98538f6

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

src/MongoDB.Driver.Tests/UpdateDefinitionBuilderTests.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2010-2015 MongoDB Inc.
1+
/* Copyright 2010-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -509,6 +509,18 @@ public void Set_Typed()
509509
Assert(subject.Set("Age", 1), "{$set: {age: 1}}");
510510
}
511511

512+
[Test]
513+
public void Set_Typed_with_cast()
514+
{
515+
var subject = CreateSubject<Message>();
516+
517+
Assert(subject.Set(x => ((SmsMessage)x).PhoneNumber, "1234567890"), "{$set: {pn: '1234567890'}}");
518+
519+
var subject2 = CreateSubject<Person>();
520+
521+
Assert(subject2.Set(x => ((SmsMessage)x.Message).PhoneNumber, "1234567890"), "{$set: {'m.pn': '1234567890'}}");
522+
}
523+
512524
[Test]
513525
public void SetOnInsert()
514526
{
@@ -576,12 +588,25 @@ private class Person
576588
public DateTime LastUpdated { get; set; }
577589
[BsonElement("pets")]
578590
public List<Pet> Pets { get; set; }
591+
592+
[BsonElement("m")]
593+
public Message Message { get; set; }
579594
}
580595

581596
private class Pet
582597
{
583598
[BsonElement("name")]
584599
public string Name { get; set; }
585600
}
601+
602+
private abstract class Message
603+
{
604+
}
605+
606+
private class SmsMessage : Message
607+
{
608+
[BsonElement("pn")]
609+
public string PhoneNumber { get; set; }
610+
}
586611
}
587612
}

src/MongoDB.Driver/Linq/Expressions/FieldAsDocumentExpression.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2015 MongoDB Inc.
1+
/* Copyright 2015-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ public override IBsonSerializer Serializer
6060

6161
public override Type Type
6262
{
63-
get { return _expression.Type; }
63+
get { return _serializer.ValueType; }
6464
}
6565

6666
public override string ToString()

src/MongoDB.Driver/Linq/Processors/SerializationBinder.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,44 @@ protected override Expression VisitUnary(UnaryExpression node)
187187
var newNode = (UnaryExpression)base.VisitUnary(node);
188188
if (newNode.NodeType == ExpressionType.Convert || newNode.NodeType == ExpressionType.ConvertChecked)
189189
{
190+
// handle unnecessary convert expressions
190191
if (newNode.Method == null && !newNode.IsLiftedToNull && newNode.Type.IsAssignableFrom(newNode.Operand.Type))
191192
{
192193
return newNode.Operand;
193194
}
195+
196+
// handle downcast convert expressions
197+
if (newNode.Operand.Type.IsAssignableFrom(newNode.Type))
198+
{
199+
var serializationExpression = newNode.Operand as SerializationExpression;
200+
if (serializationExpression != null)
201+
{
202+
var serializer = _bindingContext.GetSerializer(newNode.Type, newNode);
203+
switch (serializationExpression.ExtensionType)
204+
{
205+
case ExtensionExpressionType.ArrayIndex:
206+
return new ArrayIndexExpression(
207+
((ArrayIndexExpression)serializationExpression).Array,
208+
((ArrayIndexExpression)serializationExpression).Index,
209+
serializer);
210+
case ExtensionExpressionType.Collection:
211+
return new CollectionExpression(
212+
((CollectionExpression)serializationExpression).CollectionNamespace,
213+
serializer);
214+
case ExtensionExpressionType.Document:
215+
return new DocumentExpression(serializer);
216+
case ExtensionExpressionType.Field:
217+
return new FieldExpression(
218+
((FieldExpression)serializationExpression).FieldName,
219+
serializer);
220+
case ExtensionExpressionType.FieldAsDocument:
221+
return new FieldAsDocumentExpression(
222+
((FieldAsDocumentExpression)serializationExpression).Expression,
223+
((FieldAsDocumentExpression)serializationExpression).FieldName,
224+
serializer);
225+
}
226+
}
227+
}
194228
}
195229

196230
return newNode;

0 commit comments

Comments
 (0)