HaBo
HaBo

Reputation: 14317

Generic Method to read data from SQL Table and Export to MongoDB using C# Driver

I would like to come up with a generic method to read all data for each table in my SQL Server using EntityFramework and export that data to MongoDB using MongoDB C# Driver.

Here is what I am trying to do

using (MyEntities context = new MyEntities())
            {
                var projects = context.Projects.ToList();
                foreach (var project in projects)
                {
                    var entityType = Type.GetType($"NameSpace.Imp{project.Id}", false);
                    var entityTypeResults = context.{entityType}.ToList();
                    var entityTypeMongoCollection = _mongoConnect.Database.GetCollection<entityType>("MyCollectionName");
                    entityTypeMongoCollection.InsertMany(entityTypeResults);
                }
            }

How can I accomplish this, so that I don't have to repeat these steps for each table.

All my tables are named Imp{Id} and I have ID list in project variable, so I have list of table names.

I am using C#.NET 4.6.1, Entity Framework 6.0, MongoDB C# Driver 3.0

Thanks to @CodeCaster, here is the full working code, if someone is looking for similar help.


 public void ExporAll()
        {
            MethodInfo openMethod = typeof(MyCurrentClassName).GetMethod("CopyEntitiesToMongo");
            using (MyEntities context = new MyEntities())
            {
                var projects = context.Projects.ToList();
                Assembly assembly = Assembly.Load("NameSpace");
                foreach (var project in projects)
                {
                    var entityType = assembly.GetType($"NameSpace.Imp{project.Id}", false);
                    MethodInfo boundGenericMethod = openMethod.MakeGenericMethod(entityType);
                    if (_mongoConnect?.Database != null)
                        boundGenericMethod.Invoke(this, new object []{context, _mongoConnect.Database, "MyCollectionName"});
                }
            }
        }


        public void CopyEntitiesToMongo<TEntity>(DbContext context,
                                         IMongoDatabase mongoDatabase,
                                         string collectionName) where TEntity : class
        {
            if (context != null)
            {
                var entityTypeResults = context.Set<TEntity>().ToList();
                var entityTypeMongoCollection = mongoDatabase.GetCollection<TEntity>(collectionName);
                entityTypeMongoCollection.InsertMany(entityTypeResults);
            }
        }

Upvotes: 2

Views: 326

Answers (1)

CodeCaster
CodeCaster

Reputation: 151720

DbContext has a Set<T>() method which returns you the DbSet of the requested entity type.

So if you put that code in a generic method:

public void CopyEntitiesToMongo<TEntity>(DbContext entityFrameworkContext,
                                         MongoDatabase mongoDatabase, 
                                         string collectionName)
    where TEntity : class
{
    var entityTypeResults = context.Set<TEntity>().ToList();
    var entityTypeMongoCollection = mongoDatabase.GetCollection<TEntity>(collectionName);
    entityTypeMongoCollection.InsertMany(entityTypeResults);
}

Then you can call that method for each of your Imp... types using reflection, see How do I use reflection to call a generic method?.

So you use it like this:

MethodInfo openMethod = typeof(ClassContainingTheAboveMethod).GetMethod("CopyEntitiesToMongo");

using (MyEntities context = new MyEntities())
{
    var projects = context.Projects.ToList();
    foreach (var project in projects)
    {
         var entityType = Type.GetType($"NameSpace.Imp{project.Id}", false);
         MethodInfo boundGenericMethod = openMethod.MakeGenericMethod(entityType);

         boundGenericMethod.Invoke(this, new object[] { context, _mongoConnect.Database, "Tickets" });
    }
}

You need to do it like this, because you can't directly use variables as generic arguments.

Upvotes: 1

Related Questions