Skip to main content

.NET Core and MongoDB generic library

Hello all, you all must have come across lot of code suggestions, answers for your various queries regarding reusable libraries of server side languages and NoSql Databases. But many of those suggestions have code which is specific to that Database, tables, collections. How about writing library which is dynamic and can work with any collection, any field to query upon ?

Yes below is an example of .Net Core and MongoDB reusable dynamic library which is generic and you can use it with any collection. It can be the base for your .net core mongodb generic repository.

Please note that this is not for how to fetch values from config cause you know that better than me. This place is to discuss Coding, Sql, NoSql, Technology, Nuclear Warfare and many more and not to repeat what we have already.

So let's start learning,
Server side language : C#
Framework : .Net Core 2.1
Database : MongoDB
MongoDB Database first,

> use PlayersDB
switched to db PlayersDB
> show tables
tblPlayers
> db.tblPlayers.find();
{ "_id" : 1, "strName" : "Virat", "strPosition" : "One Down", "intAge" : 30, "intMatches" : 100 }
{ "_id" : 2, "strName" : "Rohit", "strPosition" : "Opening", "intAge" : 32, "intMatches" : 120 }
{ "_id" : 3, "strName" : "Virat", "strPosition" : "Last", "intAge" : 25, "intMatches" : 150 }
>

Library class as follows,
Before moving to code, please add required packages for Mongo. 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using MongoDB.Bson;
using MongoDB.Driver;

using NetCoreMongo.Interfaces;

namespace NetCoreMongo.Model
{
    public class clsMongoDAL : IMongo
    {
        protected static IMongoClient objMdbClient;
        protected static IMongoDatabase objMongoDB;
        protected IMongoCollection<BsonDocument> mongoCollection;
        protected string strMongoDBConnectionstring;
        protected string strMongoDataBase;
        public List<BsonDocument> lstDocuments = null;

        public clsMongoDAL(string strConnectionstring, string strDataBase)
        {
            strMongoDBConnectionstring = strConnectionstring;
            strMongoDataBase = strDataBase;
            objMdbClient = new MongoClient(strConnectionstring);
            objMongoDB = objMdbClient.GetDatabase(strDataBase);
        }

        public IEnumerable<dynamic> GetAll(string strCollectionName)
        {
            try
            {
                mongoCollection = objMongoDB.GetCollection<BsonDocument>(strCollectionName);
                var collections = mongoCollection.Find(new BsonDocument());
                lstDocuments = collections.ToList<BsonDocument>();
            }
            catch (Exception ex) { }
            return (IEnumerable<dynamic>)lstDocuments;
        }
        public IEnumerable<dynamic> GetAllMatching(string strCollectionName, string strField, object strValue)
        {
            var varFilter = Builders<BsonDocument>.Filter.Eq(strField, strValue);
            try
            {
                mongoCollection = objMongoDB.GetCollection<BsonDocument>(strCollectionName);
                var results = mongoCollection.Find(varFilter).ToCursor();
                lstDocuments = results.ToList<BsonDocument>();
            }
            catch (Exception ex) { }
            return (IEnumerable<dynamic>)lstDocuments;
        }
        public async Task<List<BsonDocument>> GetAllMachingAsync(string strCollectionName, string strField, string strValue)
        {
            var varFilter = Builders<BsonDocument>.Filter.Eq(strField, strValue);
            try
            {
                mongoCollection = objMongoDB.GetCollection<BsonDocument>(strCollectionName);
                var results = await mongoCollection.Find(varFilter).ToCursorAsync();
                lstDocuments = results.ToList<BsonDocument>();
            }
            catch (Exception ex) { }
            return lstDocuments;
        }

        public async Task<List<BsonDocument>> GetAllMachingMultiFields(string strCollectionName, FilterDefinition<BsonDocument> filterDefinitions)
        {
            try
            {
                mongoCollection = objMongoDB.GetCollection<BsonDocument>(strCollectionName);
                var results = await mongoCollection.Find(filterDefinitions).ToCursorAsync();
                lstDocuments = results.ToList<BsonDocument>();
            }
            catch (Exception ex) { }
            return lstDocuments;
        }
    }
}

Demo of GetAll and GetAllMatching methods which are generic,

      var connectionString = "mongodb://localhost:27017";
            string strDatabase = "PlayersDB"; 
            string strCollection = "tblPlayers";
            List<clsPlayers> objPlayersList = new List<clsPlayers>();
            clsPlayers objclsPlayers = null;
            try
            {
                clsMongoDAL mongoData = new clsMongoDAL(connectionString, strDatabase);
                //var mongoCollection = mongoData.GetAll(strCollection);
                var mongoCollection = mongoData.GetAllMatching(strCollection, "strName", "Virat");
                
                /// Note : Above line code shows dynamic field name and param can be passed. 
                
                foreach (var strData in mongoCollection)
                {
                    objclsPlayers = new clsPlayers
                    {
                        strName = Convert.ToString(strData.GetValue("strName")),
                        strPosition = Convert.ToString(strData.GetValue("strPosition")),
                        intAge = Convert.ToInt32(strData.GetValue("intAge")),
                        intMatches = Convert.ToInt32(strData.GetValue("intMatches"))
                    };
                    objPlayersList.Add(objclsPlayers);
                }
            }
            catch (Exception ex) { }
            return (objPlayersList != null ? JsonConvert.SerializeObject(objPlayersList) : "");

Now Demo of AND Query i.e. secondary search, please note that the index need to be there on each and every field on which we gonna query.
         var connectionString = "mongodb://localhost:27017";
            string strDatabase = "PlayersDB";
            string strCollection = "tblPlayers";
            List<clsPlayers> objPlayersList = new List<clsPlayers>();
            clsPlayers objclsPlayers = null;
            try
            {
                clsMongoDAL mongoData = new clsMongoDAL(connectionString, strDatabase);

                var varFilter1 = Builders<BsonDocument>.Filter.Eq("strName", "Virat");
                var varFilter2 = Builders<BsonDocument>.Filter.Eq("strPosition", "Last");
                var varFilter3 = Builders<BsonDocument>.Filter.And(varFilter1, varFilter2); 
                Task<List<BsonDocument>> mongoCollection = mongoData.GetAllMachingMultiFields(strCollection, varFilter3);

                //mongoCollection.Wait();   /// Note : optional 

                var varResults = mongoCollection.Result;

                for (int count = 0; count < varResults.Count; count++)
                {
                    objclsPlayers = new clsPlayers
                    {
                        strName = Convert.ToString(varResults[count].GetValue("strName")),
                        strPosition = Convert.ToString(varResults[count].GetValue("strPosition")),
                        intAge = Convert.ToInt32(varResults[count].GetValue("intAge")),
                        intMatches = Convert.ToInt32(varResults[count].GetValue("intMatches"))
                    };
                    objPlayersList.Add(objclsPlayers);
                }
            }
            catch (Exception ex) { }
            return (objPlayersList != null ? JsonConvert.SerializeObject(objPlayersList) : ""); 

Off course we need to handle Null and Not Empty in Result sets but this blog is not about that as you know that better. Thanks for reading.

Popular posts from this blog

LINQ Update List with JOIN with AND Condition

LINQ Update List using JOIN with AND Condition There is a direct way to update a collection list by joining with another but that is based on only one column and which will be ultimate thing to JOIN on. But how we can update if we need to compare more than one column ? We can join using AND query for which we need to join with first column and then where clause with second column to update. Below is detailed example for JOIN and Update based on 2 columns. Demo of same is given below.  Classes definition public class clsPlayers { public int intId { get ; set ; } = 0 ; public string strPlayerName { get ; set ; } = "" ; public string strPosition { get ; set ; } = "" ; public string strRole { get ; set ; } = "" ; public string strGrade { get ; set ; } = "" ; } public class clsPositions { public string strGrade { get ; set ; } = "" ; ...

Interface vs abstract class

Many of you are still in confusion that when I should use Interface and when Abstract Class while developing applications or for preparing for an interviews. As these are part of core concepts of Object oriented programming languages, all of us should know exact use case. As you all know bookish definitions of both concepts, we will jump to simple example directly to explain the actual use cases of both. Imagine you are working on a system which is representing list of Colleges which will have Engineering Colleges, Medical Colleges and regular degree colleges. Now there are few things which are must when it comes to any college like Black(green) Board, Classrooms which we can have in our Interface, it will be implemented later based on types of colleges i.e. Classes which will be implementing that Interface. But if all the colleges are having this then what does Abstract Class does ?? Big question right.. Here is the answer of that, Abstract class is for some common behavior t...