[CSHARP-932] Querying for BsonObjectId == null causes errors Created: 19/Mar/14 Updated: 02/Apr/16 Resolved: 22/Apr/14 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Serialization |
| Affects Version/s: | 1.8.3 |
| Fix Version/s: | 1.9.1 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Einar Egilsson | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Description |
|
We are trying to upgrade from version 1.7.1 of the driver to 1.8.3. One of the problems we have run into is that BsonObjectId can no longer be saved as null in the database, instead it's saved as { _csharpnull : true }. I don't understand why this change was made. BsonObjectId is a class, and can be null, so why shouldn't it be represented as null in the database? One example of things that break now is: public class TestClass } [Test] _collection.Insert(new TestClass { SomeId = null }); //Breaks completely because BsonObjectId null can't be serialized So the driver is perfectly happy to save documents with a BsonObjectId property that is null to the database, but if you try to query them again to get the ones where the id is null that breaks completely. I could create a query to explicitly check for SomeId._csharpnull = True, but that just seems weirdly csharp specific. The LINQ query thing above is clearly a bug, although I don't see how it can be fixed. But my main question is, what would you recommend? We have millions of records that can have null values in fields of type BsonObjectId. Should we change them to a Nullable<ObjectId> instead in our CSharp code? Or something else? Create our own Id type that is not a BsonValue? I tried to force the 1.8 driver to behave like 1.7.1 but since it's not possible to register a custom serializer for BsonObjectId, and the serialization writes the {_csharpnull:true} thing before checking the member map I wasn't able to change it back. Thanks in advance, |
| Comments |
| Comment by Githook User [ 23/Apr/14 ] | ||||||||
|
Author: {u'name': u'rstam', u'email': u'robert@10gen.com'}Message: | ||||||||
| Comment by Githook User [ 22/Apr/14 ] | ||||||||
|
Author: {u'name': u'rstam', u'email': u'robert@10gen.com'}Message: | ||||||||
| Comment by Robert Stam [ 20/Mar/14 ] | ||||||||
|
I'm linking this ticket to I'm not calling it a duplicate because this ticket is also about the Query builder failing. | ||||||||
| Comment by Robert Stam [ 19/Mar/14 ] | ||||||||
|
The LINQ issue can actually be reproduced using the Query builder alone:
| ||||||||
| Comment by Einar Egilsson [ 19/Mar/14 ] | ||||||||
|
Yes, that's a fair point. Anyway, many thanks for the quick responses. | ||||||||
| Comment by Robert Stam [ 19/Mar/14 ] | ||||||||
|
I see... sorry I misunderstood. For better or for worse, we've put a lot of emphasis on 100% fidelity in our serialization. We want to make sure that when you deserialize an object you get back exactly what you started with. | ||||||||
| Comment by Einar Egilsson [ 19/Mar/14 ] | ||||||||
|
Yes, I realize that. I just think that it would be an acceptable special case if it worked like:
I.e. I think it would be acceptable that a csharp null will come back from the database as BsonNull.Value if your field is of type BsonValue. I would guess that having properties of type BsonValue on your objects is less common than having properties of type BsonObjectId. Anyway, that was just to explain what I meant. I realize that it's not likely to be changed back to 1.7.1 behavior at this point. | ||||||||
| Comment by Robert Stam [ 19/Mar/14 ] | ||||||||
|
Just to clarify, if you deserialize:
the value of V is BsonNull.Value (not C# null), assuming your property is declared as a BsonValue (and not some subclass). That's why we need an alternate representation for C# null values. | ||||||||
| Comment by Einar Egilsson [ 19/Mar/14 ] | ||||||||
|
Thanks for the answer. I actually think it would have been better if whenever you had a property of type BsonValue and you deserialized { Prop : null }from the database it would just become BsonNull.Value. It would be a weird special case, yes, but I think it's even weirder now that any property of type BsonObjectId, BsonDocument and other BsonValue derived type can be null in csharp, but can't be compared to null in a query, and has a very programming language specific representation in the database. But everything is a tradeoff I guess. We'll switch to ObjectId? or a custom Id class that doesn't inherit from BsonValue instead. |