2

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);
            }
        }
2
  • So by "this" you mean context.{entityType}.ToList(); and _mongoConnect.Database.GetCollection<entityType>? DbContext.Set<T>() and some reflection might help. Commented May 24, 2016 at 10:33
  • @CodeCaster I didn't follow you. Was that a question or comment? I would like to be able to do a read using context.<entityType>.ToList(); and do the same with _mongoConnect.Database.GetCollection<entityType Commented May 24, 2016 at 10:40

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.