Mongo C# driver: how to compose complex queries using native API

时间:2017-10-12 09:38:35

标签: c# mongodb linq

Using Linq in C#, one can write code such as:

public static class MyEntityExtensions {
    public static IQueryable<MyEntity> ByCodeSystem(IQueryable<MyEntity> items, int codeSystemId) {
        return items.Where(o => o.CodeSystemId == codeSystemId);
    }

    public static IQueryable<MyEntity> NotDeleted(IQueryable<MyEntity> items) {
        return items.Where(o => !o.Deleted);
    }
}

and then use it like this:

DbSet<MyEntity> allMyEntities = myDbContext.MyEntities;
var myFilteredEntities = allMyEntities
    .ByCodeSystem(42)
    .NotDeleted()
    .Select(e => new { Id = e.Id, Name: e.Name })
    .ToArray(); // Materialize only the filtered ones and project only the needed data

How can one do this when querying MongoDb and its native API? I know that a collection can be used exactly like this by using IMongoCollection.AsQueryable(), but certain mongo operators are more directly mapped by the native API (i.e.: Builders.Filter., Builders.Sort. ecc).

1 个答案:

答案 0 :(得分:3)

You can do the same with extension methods to extend the mongo filter builder, for your linq examples we could have:

public static class MyModelFilterDefinitionBuilderExtentions
{
    public static FilterDefinition<MyModel> IsNotDeleted(this FilterDefinitionBuilder<MyModel> filter)
    {
        return filter.Eq(x => x.Deleted, false);
    }

    public static FilterDefinition<MyModel> ByCodeSystem(this FilterDefinitionBuilder<MyModel> filter, int codeSystemId)
    {
        return filter.Eq(x => x.CodeSystemId, codeSystemId);
    }
}

We could then apply it using

mongoCollection.Find(Builders<MyModel>.Filter.IsNotDeleted());

Or apply multiple

var filter = Builders<MyModel>.Filter.IsNotDeleted() & Builders<MyModel>.Filter.ByCodeSystem(10);
mongoCollection.Find(filter);