[CSHARP-526] LINQ queries against AsQueryable<T> where T is an interface aren't supported Created: 13/Jul/12 Updated: 20/Mar/14 Resolved: 16/Jul/12 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | None |
| Affects Version/s: | 1.5 |
| Fix Version/s: | 1.6 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Gabriel Figueroa | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | bson | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
| Description |
|
When you want to deserialize an object using an interface using this setup. It crashes with BsonSerializationException "No serializer found for type X". The way i have mongo setup is like this. MongoRepository<TObject> public TObject Find(Expression<Func<TObject,bool>> predicate) { return _mongoCollection.AsQueryable().FirstOrDefault(predicate); }} When TObject is an Interface type it crashes with BsonSerializationException. A fix that works pretty well on git commit 6a30fd35ea2d45b3aa8f2c7b176a24e90980f150 in the BsonSerializer.cs file line 589 in the LookupSerializer method near where the exception is thrown i put this snippet in if(serializer == null) } it will allow AsQueryable to use an interface type and deserialize it properly. |
| Comments |
| Comment by Robert Stam [ 16/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Closing this issue, at least for now, as works as designed. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Gabriel Figueroa [ 14/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Yeah you are right i'll just have to see about writing my code so that i can get AsQueryable<> to have the concrete type before i pass it on to MongoDB. Thats probably easier to do than to come up with a general solution to work inside of the driver. In the simple case my snippet works fine but the second you need any of the advance features of the class mapper it falls apart. Thank You for your time, keep up the great work. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 14/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I don't think we can implement LINQ queries in terms of interfaces, because some of the information we need to translate a LINQ query to a MongoDB query is attached to the classes. Consider the following interface and classes:
and the following LINQ query:
We can't map this LINQ query to a MongoDB query because we don't know the element name that X is mapped to unless we know the class. Depending on the actual class in use, the MongoDB query might be either one of these:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Gabriel Figueroa [ 14/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Your sample application is the exact error that i am seeing. You are correct that my little snippet could have problems if more than one class that implements that interface is registered with the driver. Your workaround would work in all other cases but for me
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 13/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Here's the line from the test program that throws an exception:
Where IC is an interface. The following slightly different line of code would work:
because C is not an interface. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 13/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I've edited the summary description to more accurately describe what I believe is the root issue. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 13/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Also wanted to comment that your proposed fix is probably dangerous. There may be multiple potential hits and you are arbitrarily grabbing the first one. That probably worked in your test environment, but might not be safe in general. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 13/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
This is the stack trace from running the attached test program. Note that the exception is coming during translation of the LINQ query and not during actual deserialization of a real document. The LINQ translation layer needs serialization information because it needs to know the corresponding element name in the document and how the corresponding values are serialized.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 13/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I've attached a small console program that I believe reproduces the issue you are describing. Take a look, and if you feel it adequately reproduces your issue then you don't need to provide any additional information. Thanks. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Stam [ 13/Jul/12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Can you provide the following additional information: 1. sample interface definition It would be really nice if you could provide a standalone console application that reproduces the exception. |