Reputation: 1691
I need to construct a query using as a FilterDefinition an explicit Interface but it throws an exception saying :
System.InvalidOperationException
Message={document}.Pointer is not supported.
Source=MongoDB.Driver
I have tried this with normal Interface implementation and it works as expected. But I need to implement an Interface explicitly as I'm having 2 interfaces with the same property names as shown in the code below:
public class Offer : OfferBase, IPointerTo<ServiceCategory>,
IPointerTo<Company>
{
[BsonElement("_p_ServiceCategoryObj")]
[JsonProperty("serviceCategoryObj")]
string IPointerTo<ServiceCategory>.Pointer { get; set; }
[BsonElement("_p_companyObj")]
[JsonProperty("companyObj")]
string IPointerTo<Company>.Pointer { get; set; }
}
So, I create a FilterDefinition that I will use in a Find.
As I mentioned before, this works fine if it were not an explicit interface
implementation. For instance: if just use one of them normally implemented and the other explicitly it will work when querying for the normal one. But having the above code constraints and creating the filter like this:
FilterDefinition<Offer> innnerFilter = MongoQueryBuilder.AddFilter<Offer>
(offer =>string.IsNullOrEmpty((offer as
IPointerTo<ServiceCategory>).Pointer));
So when the Find with that filter is being executed the exception stated above is being thrown.
Note: MongoQueryBuilder.AddFilter is just a wrapper that I did to make it easier but that it's not the issue as all the other queries work fine using that.
I would expect to get the results as I get them when just having one of the interfaces implemented normally and querying with that Interface member but in my current scenario I need to have them both implemented and thus they must be implemented explicitly.
I may not be doing something properly or using it as I should but I haven't been to find any solution to this.
Edit: (thanks to @Lakerfield answer)
I was not able to find Pointer as I was asking for Offer and as Pointer it's an explicit interface
it was not being able to publicly find it.
So, I was able to solve it like this:
public class Offer : OfferBase, IPointerTo<ServiceCategory>, IPointerTo<Company>
{
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
[BsonElement("_p_ServiceCategoryObj")]
[JsonProperty("serviceCategoryObj")]
public string ServiceCategoryPointer
{
get => (this as IPointerTo<ServiceCategory>).Pointer;
set => (this as IPointerTo<ServiceCategory>).Pointer = value;
}
[BsonIgnore]
string IPointerTo<ServiceCategory>.Pointer { get; set; }
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
[BsonElement("_p_companyObj")]
[JsonProperty("companyObj")]
public string CompanyPointer
{
get => (this as IPointerTo<Company>).Pointer;
set => (this as IPointerTo<Company>).Pointer = value;
}
[BsonIgnore]
string IPointerTo<Company>.Pointer { get; set; }
And then doing the query like this: (Now I'm use Linq instead of FilterDefinition but that is not relevant for the sake of this solution)
private static Expression<Func<Offer, bool>> InnerQueryServiceCategory(string serviceCategoryId)
{
return offer => (offer.IsDeleted == false || !offer.IsDeleted.HasValue) && offer.ServiceCategoryPointer == PointedCollections.ServiceCategoryCollection.GetDescription() + serviceCategoryId;
}
offer.ServiceCategoryPointer is publicly available and it's a member of Offer.
Upvotes: 0
Views: 412
Reputation: 1091
The problem is the duplicate Pointer
property name. In MongoDB a object must have unique propertynames.
Workaround just use two seperate properties with different names, forward your explicit interfaces to those, and use the new properties in your query.
public class Offer : OfferBase, IPointerTo<ServiceCategory>, IPointerTo<Company>
{
public string ServiceCategoryPointer { get; set; }
public string CompanyPointer { get; set; }
string IPointerTo<ServiceCategory>.Pointer
{
get => ServiceCategoryPointer;
set => ServiceCategoryPointer = value;
}
string IPointerTo<Company>.Pointer
{
get => CompanyPointer;
set => CompanyPointer = value;
}
}
Upvotes: 1