[CSHARP-785] Custom/unsupported collections with their own impl of .Contains(...) causes a LINQ error Created: 20/Jul/13 Updated: 12/Aug/13 Resolved: 12/Aug/13 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | David Pfeffer | Assignee: | Unassigned |
| Resolution: | Cannot Reproduce | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Description |
|
When a .NET collection type, such as ISet, defines its own Contains method, the C# compiler will (rightly) choose this implementation over the Enumerable.Contains extension method. When the collection type is unsupported by MongoDB natively, however, Mongo's client driver for C# will throw an exception because it doesn't know how to translate the Contains method invocation into a query. The workaround at the moment is not too bad – calling Enumerable.Contains(collection, item to check) rather than collection.Contains(item to check) translates properly by the driver. However, this is a bit hackish and is definitely not easy to read. I think this is a situation where "if it looks like a duck and quacks like a duck, its a duck" applies. If a type implements IEnumerable<T>, defines a method called Contains, and that method takes one argument of type T, you should translate it just like you would do with the extension method or one of the supported collection types' Contains method. |
| Comments |
| Comment by David Pfeffer [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
That's strange, because it does work for me too now that I've tried your sample code. Unfortunately it was a member of my team that generated the error originally, not me. I should be able to get him to reproduce it sometime this weekend and post back. | |||||||||||||||||||||||||||
| Comment by Craig Wilson [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
I initially used ISet<T> and the query was generated appropriately (I couldn't deserialize for lack of a custom serializer). See below. Could you provide the exception you are receiving? Also, could you post your custom serializer? Your custom serializer needs to implement IBsonArraySerializer in order to provide serialization information for the items contained. If you have not implemented IBsonArraySerializer, you will receive an exception with a message like " {0}requires that the serializer specified for {1}support items by implementing {2}and returning a non-null result. {3}is the current serializer."
| |||||||||||||||||||||||||||
| Comment by David Pfeffer [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
Change Ages in your example to ISet<int> and use a custom serializer to load it into a custom set type, and it fails. | |||||||||||||||||||||||||||
| Comment by Craig Wilson [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
#1 is covered by this issue. #2 is not. However, #2 already works correctly. Below is a sample program used to demonstrate this... Perhaps you could provide a sample of what isn't working?
| |||||||||||||||||||||||||||
| Comment by David Pfeffer [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
I'm actually talking about #2 above, whereas the other issue ( | |||||||||||||||||||||||||||
| Comment by Craig Wilson [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
Hi David. In tracking this down, we already have this issue reported and it has already been corrected in master and will either be a part of a soon-to-be-released 1.8.2 or 1.9. | |||||||||||||||||||||||||||
| Comment by Craig Wilson [ 20/Jul/13 ] | |||||||||||||||||||||||||||
|
Could you identify which of the below you are referring to.
|