- Notifications
You must be signed in to change notification settings - Fork5
It's a modern and generic data access structure for .NET and MongoDB. It supports UnitOfWork, Repository and QueryBuilder patterns. It also includes DbContext, IdGenerators and transactions support with replica set.
License
ffernandolima/mongo-db-data-access
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
It's a modern and generic data access structure for .NET and MongoDB. It supports UnitOfWork, Repository and QueryBuilder patterns. It also includes DbContext, IdGenerators and transactions support with replica set.
If you like or are using this project to learn or start your solution, please give it a star. Thanks!
MongoDB.DataAccess is available on Nuget.
Install-Package MongoDB.Data.Infrastructure.Abstractions -Version 1.8.5Install-Package MongoDB.Data.QueryBuilder.Abstractions -Version 1.8.5Install-Package MongoDB.Data.Repository.Abstractions -Version 1.8.5Install-Package MongoDB.Data.UnitOfWork.Abstractions -Version 1.8.5Install-Package MongoDB.Data.Generators -Version 1.8.5Install-Package MongoDB.Data.Infrastructure -Version 1.8.5Install-Package MongoDB.Data.QueryBuilder -Version 1.8.5Install-Package MongoDB.Data.Repository -Version 1.8.5Install-Package MongoDB.Data.UnitOfWork -Version 1.8.5P.S.: MongoDB.Data.UnitOfWork depends on the other packages, so installing this package is enough.
First of all, please register the dependencies into the MS Built-In container:
publicclassBloggingContext:MongoDbContext{publicBloggingContext(IMongoClientclient,IMongoDatabasedatabase,IMongoDbContextOptionsoptions):base(client,database,options){}}// Register the DbContextservices.AddMongoDbContext<IMongoDbContext,BloggingContext>(connectionString:Configuration.GetValue<string>("MongoSettings:Blogging:ConnectionString"),databaseName:Configuration.GetValue<string>("MongoSettings:Blogging:DatabaseName"),setupFluentConfigurationOptions: options=>options.ScanningAssemblies=new[]{typeof(BloggingContext).Assembly});// Register the UnitOfWorkservices.AddMongoDbUnitOfWork<BloggingContext>();
For multiple databases:
publicclassBloggingContext:MongoDbContext{publicBloggingContext(IMongoClientclient,IMongoDatabasedatabase,IMongoDbContextOptionsoptions):base(client,database,options){}}publicclassAccountingContext:MongoDbContext{publicAccountingContext(IMongoClientclient,IMongoDatabasedatabase,IMongoDbContextOptionsoptions):base(client,database,options){}}// Register the DbContextsservices.AddMongoDbContext<IMongoDbContext,BloggingContext>(connectionString:Configuration.GetValue<string>("MongoSettings:Blogging:ConnectionString"),databaseName:Configuration.GetValue<string>("MongoSettings:Blogging:DatabaseName"),setupFluentConfigurationOptions: options=>options.ScanningAssemblies=new[]{typeof(BloggingContext).Assembly});services.AddMongoDbContext<IMongoDbContext,AccountingContext>(connectionString:Configuration.GetValue<string>("MongoSettings:Accounting:ConnectionString"),databaseName:Configuration.GetValue<string>("MongoSettings:Accounting:DatabaseName"),setupFluentConfigurationOptions: options=>options.ScanningAssemblies=new[]{typeof(AccountingContext).Assembly});// Register the UnitOfWorkservices.AddMongoDbUnitOfWork<BloggingContext>();services.AddMongoDbUnitOfWork<AccountingContext>();
For multi-tenancy:
P.S: There are many approaches to implementing multi-tenancy in applications (Discriminator, Database per tenant, Schema per tenant...) and this one is just an example.
publicclassBloggingContext:MongoDbContext{publicBloggingContext(IMongoClientclient,IMongoDatabasedatabase,IMongoDbContextOptionsoptions):base(client,database,options){}}// Register the DbContextsservices.AddMongoDbContext<IMongoDbContext,BloggingContext>(connectionString:Configuration.GetValue<string>("MongoSettings:Blogging:TenantA:ConnectionString"),databaseName:Configuration.GetValue<string>("MongoSettings:Blogging:TenantA:DatabaseName"),setupDbContextOptions: options=>options.DbContextId=$"{nameof(BloggingContext)} - TenantA",setupFluentConfigurationOptions: options=>options.ScanningAssemblies=new[]{typeof(BloggingContext).Assembly});services.AddMongoDbContext<IMongoDbContext,BloggingContext>(connectionString:Configuration.GetValue<string>("MongoSettings:Blogging:TenantB:ConnectionString"),databaseName:Configuration.GetValue<string>("MongoSettings:Blogging:TenantB:DatabaseName"),setupDbContextOptions: options=>options.DbContextId=$"{nameof(BloggingContext)} - TenantB",setupFluentConfigurationOptions: options=>options.ScanningAssemblies=new[]{typeof(BloggingContext).Assembly});// Register the UnitOfWorkservices.AddMongoDbUnitOfWork<BloggingContext>();// Orservices.AddMongoDbUnitOfWork<BloggingContext>("BloggingContext - TenantA");services.AddMongoDbUnitOfWork<BloggingContext>("BloggingContext - TenantB");
After that, use the structure in your code like that:
privatereadonlyIMongoDbUnitOfWork<BloggingContext>_unitOfWork;// InjectionpublicBlogsController(IMongoDbUnitOfWork<BloggingContext> unitOfWork)=> _unitOfWork=unitOfWork??thrownewArgumentNullException(nameof(unitOfWork),$"{nameof(unitOfWork)} cannot be null.");// Or// Factory for multi-tenancypublicBlogsController(IMongoDbUnitOfWorkFactory<BloggingContext> unitOfWorkFactory,ITenantProvider tenantProvider){if(unitOfWorkFactoryisnull){thrownewArgumentNullException(nameof(unitOfWorkFactory),$"{nameof(unitOfWorkFactory)} cannot be null.");}if(tenantProviderisnull){thrownewArgumentNullException(nameof(tenantProvider),$"{nameof(tenantProvider)} cannot be null.");}vartenantId=tenantProvider.GetTenantId();_unitOfWork=unitOfWorkFactory.Create(tenantId);}// Or// If the TenantId is known and constantpublicBlogsController([FromKeyedServices("BloggingContext - TenantA")]IMongoDbUnitOfWork<BloggingContext> unitOfWork)=>_unitOfWork=unitOfWork??thrownewArgumentNullException(nameof(unitOfWork),$"{nameof(unitOfWork)} cannot be null.");publicvoidGetAllBlogs(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.MultipleResultQuery();varblogs=repository.Search(query);}publicvoidGetAllBlogsProjection(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.MultipleResultQuery().Select(selector=>new{Name=selector.Title,Link=selector.Url,Type=selector.Type.Description});varblogs=repository.Search(query);}publicvoidGetAllOrderedBlogs(){varrepository=_unitOfWork.Repository<Blog>();IMongoDbQuery<Blog>query;IList<Blog>blogs;query=repository.MultipleResultQuery().OrderByDescending("Id");blogs=repository.Search(query);query=repository.MultipleResultQuery().OrderByDescending(blog=>blog.Id);blogs=repository.Search(query);}publicvoidGetTopBlogs(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.MultipleResultQuery().Top(10);varblogs=repository.Search(query);}publicvoidGetPagedBlogs(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.MultipleResultQuery().Page(1,20);varblogs=repository.Search(query);}publicvoidGetBlogsPagedList(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.MultipleResultQuery().Page(1,20);varblogs=repository.Search(query).ToPagedList(query.Paging.PageIndex,query.Paging.PageSize,query.Paging.TotalCount);}publicvoidGetFilteredBlogs(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.MultipleResultQuery().AndFilter(blog=>blog.Url.StartsWith("/a/")).AndFilter(blog=>blog.Title.StartsWith("a")).AndFilter(blog=>blog.Posts.Any());varblogs=repository.Search(query);}publicvoidGetUrls(){varrepository=_unitOfWork.CustomRepository<ICustomBlogRepository>();varurls=repository.GetAllBlogUrls();}publicvoidGetBlogByUrl(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.SingleResultQuery().AndFilter(blog=>blog.Url.StartsWith("/a/")).OrderByDescending(blog=>blog.Id);varblogResult=repository.FirstOrDefault(query);}publicvoidGetBlogById(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.SingleResultQuery().AndFilter(blog=>blog.Id==1);varblogResult=repository.SingleOrDefault(query);}publicvoidGetBlogByIdProjection(){varrepository=_unitOfWork.Repository<Blog>();varquery=repository.SingleResultQuery().AndFilter(blog=>blog.Id==1).Select(selector=>new{selector.Id,Name=selector.Title,Link=selector.Url,Type=selector.Type.Description});varblogResult=repository.SingleOrDefault(query);}publicvoidExistsBlog(){varrepository=_unitOfWork.Repository<Blog>();varexists=repository.Any(blog=>blog.Url.StartsWith("/a/"));}publicvoidGetBlogCount(){varrepository=_unitOfWork.Repository<Blog>();varcount=repository.Count();varlongCount=repository.LongCount();}publicvoidMaxBlogId(){varrepository=_unitOfWork.Repository<Blog>();varid=repository.Max(blog=>blog.Id);}publicvoidMinBlogId(){varrepository=_unitOfWork.Repository<Blog>();varid=repository.Min(blog=>blog.Id);}publicvoidAddBlog(){varrepository=_unitOfWork.Repository<Blog>();repository.InsertOne(Seeder.SeedBlog(51));_unitOfWork.SaveChanges();}publicvoidUpdateBlog(){varrepository=_unitOfWork.Repository<Blog>();repository.ReplaceOne(x=>x.Id==id,model);_unitOfWork.SaveChanges();}publicvoidDeleteBlog(){varrepository=_unitOfWork.Repository<Blog>();repository.DeleteOne(x=>x.Id==id);_unitOfWork.SaveChanges();}publicvoidUpdateManyBlogs(){varrepository=_unitOfWork.Repository<Blog>();repository.UpdateMany( blog=>blogIds.Contains(blog.Id),newDictionary<Expression<Func<Blog,object>>,object>{{ blog=>blog.Title,"updated-title"}});_unitOfWork.SaveChanges();}publicvoidBulkWriteBlogs(){varrepository=_unitOfWork.Repository<Blog>();varrequests=newList<WriteModel<Blog>>();foreach(varblogIdinblogIds){varfilter=Builders<Blog>.Filter.Eq(blog=>blog.Id,blogId);vardefinition=Builders<Blog>.Update.Set(blog=>blog.Title,$"a{blogId}-updated-title");requests.Add(newUpdateOneModel<Blog>(filter,definition));}repository.BulkWrite(requests);_unitOfWork.SaveChanges();}
The operations above are also available as async.
Please check some available sampleshere
If you want to help with the project, feel free to open pull requests and submit issues.
If you would like to show your support for this project, then please feel free to buy me a coffee.
About
It's a modern and generic data access structure for .NET and MongoDB. It supports UnitOfWork, Repository and QueryBuilder patterns. It also includes DbContext, IdGenerators and transactions support with replica set.
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.
