Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use the AsQueryable method asynchronously with MongoDb C# Driver 2.1?

The release of version 2.1 of the MongoDb C# Driver has recently reintroduced the method AsQueryable, but I am struggling to find a way of calling it asynchronously.

With Entity Framework this would be achieved using QueryableExtensions.ToListAsync but I can't see an equivalent using MongoDb.

So given a repository method such as:

public IQueryable<MyType> GetFiltered(Expression<Func<MyType, bool>> predicate)
{
        return Database.GetCollection<MyType>(typeof(MyType).Name).AsQueryable().Where(predicate);
}

I wanted to do something like

var myTypes = await MyRepository.GetFiltered(t => t.Id == 1).ToListAsync();

Is this possible?

like image 983
rrrr-o Avatar asked Dec 02 '15 12:12

rrrr-o


4 Answers

You're returning the wrong type from the GetFiltered function. It should be returning an IMongoQueryable<MyType> instead of IQueryable<MyType>:

public IMongoQueryable<MyType> GetFiltered(Expression<Func<MyType, bool>> predicate)
{
    return Database.GetCollection<MyType>(typeof(MyType).Name).AsQueryable()
        .Where(predicate);
}

You can then successfully call it as:

var myTypes = await MyRepository.GetFiltered(t => t.Id == 1).ToListAsync();
like image 118
JohnnyHK Avatar answered Oct 28 '22 17:10

JohnnyHK


I am posting this later as an update for the newer versions of MongoDB driver.

In the newer versions of MongoDB, you can call it asynchronously. You need to include the MongoDB.Driver.Linq:

using MongoDB.Driver.Linq;
var myTypes = await Database.GetCollection<MyType>().AsQueryable()
.Where(t => t.Id == 1).ToListAsync();
like image 39
Amir Avatar answered Oct 28 '22 17:10

Amir


I up-voted the accepted answer.

If you need to abstract away the IMongoQueryable interface from the caller this little extension helper may be useful.

public static class MongoQueryableMixIn
{
    public static Task<List<T>> ToMongoListAsync<T>(this IQueryable<T> mongoQueryOnly)
    {
        return ((IMongoQueryable<T>) mongoQueryOnly).ToListAsync();
    }
}
like image 6
Dave Jellison Avatar answered Oct 28 '22 18:10

Dave Jellison


At first you must call ToCursorAsync() for IMonqoQuarable<T> object, and then call ToListAsync() for the awaited IAsyncCursor result:

public IMongoQueryable<MyType> GetFiltered(Expression<Func<MyType, bool>> predicate)
{
    return Database.GetCollection<MyType>(typeof(MyType).Name).AsQueryable()
        .Where(predicate);
}

And then

var myTypes = await(await MyRepository.GetFiltered(t => t.Id == 1).ToCursorAsync()).ToListAsync();
like image 1
Tselofan Avatar answered Oct 28 '22 17:10

Tselofan