[CSHARP-900] Support downcasting object in LINQ queries Created: 23/Jan/14  Updated: 14/Nov/19  Resolved: 18/Feb/14

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.8.3
Fix Version/s: 1.9

Type: Improvement Priority: Minor - P4
Reporter: Robert Stam Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CSHARP-613 LINQ queries don't work with fields/p... Closed

 Description   

It would be nice if given a class like:

public class C
{
    public int _id;
    public object F;
    public object[] L;
}

One could write LINQ queries like:

collection.AsQueryable<C>().Where(c => (int)c.F > 10);
// or
collection.AsQueryable<C>().Where(c => c.L.Any(o => (int)o > 10));

Normally we deduce the serialized form of the value from the type information of the field, but in this case we would have to deduce the desired type from the cast used in the query.

Not sure what all the ramifications of this feature are... it's possible that there is more to it than initially meets the eye and this might not turn out to be easily doable. So the first step is to properly research the feasability of this feature.



 Comments   
Comment by Sebastian Inones [ 14/Nov/19 ]

Ciao @Nicola Cassolato,

Sorry for the late late reply.

Truth be told, the issue was on my code (that was the most reasonable thing).
I post also a question on StackOverflow as I suspected that it had to do with my code when performing a Find. Thanks to the replies I got and the alternatives I was given I found a solution.
Here is the link just in case some else stumble against the same sort of scenario.

Sebastian
 

Comment by Nicola Cassolato [ 05/Aug/19 ]

ciao @Sebastian Inones,

 

I was able to solve using 'as' instead of doing a CAST.

Using my example, this kind of query works

 

var cursor = collectionExample.Find(x=> (x.Field as TextValue).FieldValue = "bar")

 

Hope this helps

Nicola

 

Comment by Sebastian Inones [ 01/Aug/19 ]

I have a quite similar issue as @Nicola Cassolato.
I have a class which implements 2 explicit interfaces as their members have the same signature (it has to be like that).    

 

 [BsonIgnore]
 ServiceCategory IPointerTo<ServiceCategory>.PointedCollection { get; set; }
 
 [BsonIgnoreIfNull]
 [BsonIgnoreIfDefault]
 [BsonElement("_p_ServiceCategoryObj")]
 [JsonProperty("serviceCategoryObj")]
 string IPointerTo<ServiceCategory>.Pointer { get; set; }
 
 [BsonIgnore]
 Company IPointerTo<Company>.PointedCollection { get; set; }
 
 [BsonIgnoreIfNull]
 [BsonIgnoreIfDefault]
 [BsonElement("_p_companyObj")]
 [JsonProperty("companyObj")]
 string IPointerTo<Company>.Pointer { get; set; }

For instance, the string Pointer member is the one that I will use for casting..

So, when I create a filter (in my wrapper) like the one below and then when the Find query gets executed I will throw the same type of exception as the comments above: *

{document} {PropertyValue}

) is not supported.*

var filterByPointer = MongoQueryBuilder.AddFilter<Offer>(offer => ((IPointerTo<Company>)offer).Pointer == PointedCollections.CompanyCollection.GetDescription() + companyId);

 

resultList = await dataBase.GetCollection<T>(resourceName).Find(filter).ToListAsync();

I just pasted the relevant parts of my code.
I would like to know if there's another way to do this. Maybe I'm doing something that's not correct.

Comment by Sudhir Thanki [ 05/Jun/18 ]

I have same issue while converting string value to datetime in a query. It throws following exception:

 

ToDateTime({document}{PropertyValue}) is not supported.

 

I used mongodb 2.6.0 nuget package

var dateFilter = Builders<MyCollection>.Filter.ElemMatch(x => x.Properties,  a => (a.PropertyName == "UpdatedOn" && Convert.ToDateTime(a.PropertyValue) >= date));
 
 var collection = _idb.GetCollection<MyCollection>("MyCollection");
 var filter = await collection.FindAsync(dateFilter);

 

Comment by Nicola Cassolato [ 18/Jan/18 ]

I'm sorry to re-open an old ticket but I feel this is the right place.

I've found a scenario where casting a field of type Interface to a specific type is not working.
Of course

public class Example {
    public IAttribute Field {get;set;}
}
 
public class TextValue: IAttribute {
    public string FieldValue {get;set;}
}
 
 
var cursor = collectionExample.Find(x=>  ((TextValue)x.Field).FieldValue = "bar")
 

The code in example will return an error 'Convert(

{document}

.TestProperty, TextValue).GlobalValue is not supported

Comment by Githook User [ 18/Feb/14 ]

Author:

{u'username': u'ddebilt', u'name': u'ddebilt', u'email': u'dan.debilt@gmail.com'}

Message: CSHARP-900: Support downcasting object in LINQ queries
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/f30acd6624e76dcfdab52ac948edae4a3a7e5f3c

Comment by Githook User [ 18/Feb/14 ]

Author:

{u'username': u'ddebilt', u'name': u'ddebilt', u'email': u'dan.debilt@gmail.com'}

Message: CSHARP-900: Support downcasting object in LINQ queries
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/585d50d1ee73e294157d6347198582986bd35707

Comment by Githook User [ 18/Feb/14 ]

Author:

{u'username': u'ddebilt', u'name': u'ddebilt', u'email': u'dan.debilt@gmail.com'}

Message: CSHARP-900: Support downcasting object in LINQ queries
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/4f4056e82e1ab0b076bb8346ee6bb4b4c2199afa

Comment by Githook User [ 18/Feb/14 ]

Author:

{u'username': u'ddebilt', u'name': u'ddebilt', u'email': u'dan.debilt@gmail.com'}

Message: CSHARP-900: Support downcasting object in LINQ queries
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/56a91ef1a7f3f67bfcf71b33fa31b0fada4653ab

Comment by Stefan [ 17/Feb/14 ]

Thanks Craig,

Just after I wrote this post I thought "bugger it I will patch it myself" only to go to github and see the existing pull request , tested that out and life is happy again, next time I will look at github issues first as there seems to be a disconnect between the two.

Cheers

Comment by Craig Wilson [ 17/Feb/14 ]

Hi Stefan,

Yes, it can be supported. We just had a pull request for this exact issue: https://github.com/mongodb/mongo-csharp-driver/pull/172. If you'd like, feel free to test out the pull request and let us know if it fixes your issue.

Craig

Comment by Stefan [ 17/Feb/14 ]

Do we have any more indication on this issue as to if it is something that can be supported? I am trying to write a custom query language > linq parser and need to be able to case a collection of IList<Property> where Property.Value is of type object, the only way I can do this at the moment is to replace:

(... && (int)prop.Value < 1)

with:

(... && Query.LT("Value", new BsonInt64(1)).Inject())

This works fine, but it removes the idea goal of being able to run the exact same queries over in memory objects as well as against the database.

Thanks
Stefan

Comment by Robert Stam [ 23/Jan/14 ]

Initially created in response to user feedback at:

http://stackoverflow.com/questions/21298311/casting-an-object-not-supported-in-net-mongodb-c-sharp-driver

Generated at Wed Feb 07 21:38:08 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.