Reputation: 14317
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
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