MongoDB context implementation in C# as neat as Entity Framework

1. Model configurations

BsonClassMap.RegisterClassMap<User>(cm => {
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
cm.MapIdField(x => x.UserId);
});

2. Index definition:

var database = client.GetDatabase("MyApplication");
var collection = database.GetCollection<User>("Users");

var searchByIdentifier = new CreateIndexModel<User>(Builders<User>.IndexKeys
.Ascending(x => x.ContactDetails.Email)
.Ascending(x => x.ContactDetails.PhoneNumber));

var searchByUserId = new CreateIndexModel<User>(Builders<User>.IndexKeys
.Ascending(x => x.UserId));

collection.Indexes.CreateManyAsync(new []{ searchByIdentifier, searchByUserId});

3. Mapping Collection to the Model

var database = client.GetDatabase("MyApplication");
var collection = database.GetCollection<User>("Users");

Solution: Use out MongoContext

Install-Package ParkBee.MongoDb
public class MyApplicationContext : MongoContext  
{
public DbSet<User> Users { get; set; }
protected override async Task OnConfiguring()
{
await OptionsBuilder.Entity<User>(async entity =>
{
var usersCollection = entity.ToCollection("ApplicationUsers");
var searchByEmail = new CreateIndexModel<Permit>(Builders<User>.IndexKeys
.Ascending(u => u.Email));

await permitsCollection.Indexes.CreateOneAsync(searchByEmail);

entity.HasKey(p => p.UserId);
});
}
public MyApplicationContext(IMongoContextOptionsBuilder optionsBuilder) : base(optionsBuilder)
{
}
}
Install-Package ParkBee.MongoDb.DependencyInjection
services.AddMongoContext<MyApplicationContext>(options =>
{
options.ConnectionString = "mongodb://localhost";
options.DatabaseName = "MyApplication";
});
public class UsersController : ControllerBase
{
private readonly MyApplicationContext _context;
public UsersController(MyApplicationContext context)
{
_context = context;
}

[HttpGet]
public async Task<IActionResult> GetUsers([FromQuery]SearchUsersRequest request, [FromQuery]QueryOptions queryOptions, CancellationToken cancellationToken)
{
var users = await _context.Users.ToListAsync(cancellationToken);

return Ok(users);
}
}

Explaining the context code

Configuration Options

ToCollection

MapBson

await OptionsBuilder.Entity<InternalUser>(async b =>
{
b.MapBson(cm =>
{
cm.AutoMap();
cm.SetDiscriminator(nameof(InternalUser));
cm.MapField("_products").SetElementName(nameof(InternalUser.Products));
cm.SetIgnoreExtraElements(true);
});
});

HasKey

FindByKey

var user = await _context.Users.FindByKey("userid");

UpdateByKey

var user = await _context.Users.UpdateByKey("userid", Builders<User>.Update.Set(p => p.FirstName, "New Name"));

ReplaceByKey

var user = await _context.Users.ReplaceByKey("userid", new User{ UserId = "userid", FirstName = "New Name"});

DeleteByKey

var user = await _context.Users.DeleteByKey("userid");

HasIndex

var searchByIdentifier = new CreateIndexModel<User>(Builders<User>.IndexKeys
.Ascending(x => x.ContactDetails.Email)
.Ascending(x => x.ContactDetails.PhoneNumber));

var searchByUserId = new CreateIndexModel<User>(Builders<User>.IndexKeys
.Ascending(x => x.UserId));
b.HasIndex(searchByIdentifier, searchByUserId);

And that's it

We are ParkBee.
A scale-up with a mission

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mahdi Haji

Mahdi Haji

I'm full stack .Net Angular developer in short. It's over than 15 years working as a developer and architect and I've used many technologies and frameworks