6

I am having trouble making my filters work with MongoDB .NET Driver, I get this error:

Unsupported filter: Invoke(value(System.Func2 [Role,System.Boolean]), {document}{Model}).

When trying to run this code:

public virtual async Task<PartitionedModel<T>> GetByAsync(Func<T, bool> filter)
{
    Expression<Func<PartitionedModel<T>, bool>> filt = (i) => filter(i.Model);
    PartitionedModel<T> item = (await collection.FindAsync(filt)).FirstOrDefault();
    return item;
}

and the class PartitionedModel look like this:

public class PartitionedModel<T> where T : IModel
{
    public ObjectId Id { get; set; }
    public PartitionOffset PartitionOffset { get; set; }
    public T Model { get; set; }
}

I did a refacto of my code working from having collections handling IModel directly to working with PartitionedModel which is a holding class for my IModel, the GetByAsync function worked correctly before I subclassed IModel

I found little to no informations about this problem except this: Dynamic Linq Predicate throws "Unsupported Filter" error with C# MongoDB Driver

But it seems like my version of the MongoDB C# Driver doesnt accept Func<> in parameter as filter, I can only pass Builder<> or Expression<> as a filter into the Find functions

Can someone enlighten me a bit about this error ?

EDIT:

I tried to run this code by replacing the FindAsync(filt) with FindAsync(_ => true) and it actually works

Also, here is the code that is used to retrieve the collection

protected readonly IMongoCollection<PartitionedModel<T>> collection;

public GenericRepository(IMongoDatabase dbContext, string collectionName)
{
    collection = dbContext.GetCollection<PartitionedModel<T>>(collectionName);
}

and the version of my driver seems to be 2.7.0 driver version

EDIT 2: I've made my query works using this:

PartitionedModel<T> item = collection.AsQueryable().FirstOrDefault(filt);

But i'm not sure what is the implication of using a non-async version, can anyone tell me if this is wrong or if this will be a problem ?

2 Answers 2

2

Seems like current implementation of c# mongo driver is not supported delegate-based filters.

https://github.com/mongodb/mongo-csharp-driver/blob/da0cff54c67208d979b030abb160f958d3276925/src/MongoDB.Driver/Linq/Translators/PredicateTranslator.cs#L76

The switch doesn't contain a ExpressionType.Invoke (the type of expression in delegate-based filter) case.

Sign up to request clarification or add additional context in comments.

Comments

1

Mongo doesn't work with invocation filters. You can pass that invocation filter to LINQKit's expression expander and it will replace it with a predicate that the Mongo driver can then fully understand.

Magic is here

See it in action here

2 Comments

Do you have more explanation sources on usage? Can't get it working, I saw your answer on another post but still.
Given any Expression just invoke the .Expand() extension method provided by LINQKit before you send it to any of the Mongo functions. The 2nd link takes both a selector expression from a sub document and chains together an and clause via predicate builder. I feed that expanded expression into Mongo on every single query I run against my databases transactional documents. I actually wrote that test for LINQKit when it blew up last summer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.