dimanche 19 avril 2020

call ef core method with generic type from type name

I have an application logging a list of query to be executed at a later time. So I have a list containing something like this:

class QueryToBeExecutedLater
{
  string sql { get; set; }
  object[] parameters { get; set; }
  string entityTypeFullName { get; set; }
}

And I need to execute them like:

List<QueryToBeExecutedLater> allQueries = ...
foreach(var q in allQueries )
{
    Type elementType = Type.GetType(q.entityTypeFullName);
    var result = await db.Set<elementType>.FromSqlRaw(q.sql,q.parameters).ToListAsync();
}

But of course it doesn't work. I am not all that familiar with reflection. So far I have been able to get the dbSet with this:

List<QueryToBeExecutedLater> allQueries = ...
foreach(var q in allQueries )
{
    Type elementType = Type.GetType(q.entityTypeFullName);
    MethodInfo method = typeof(myDbContext).GetMethod("Set",
                                  BindingFlags.Public | BindingFlags.Static);
    method = method.MakeGenericMethod(elementType);
    var _dbSet = method.Invoke(db,null);

    var result = _dbSet.FromSqlRaw(q.sql,q.parameters);
}

Which of course doesn't work, because: enter image description here

I probably should be doing something like this:

List<QueryToBeExecutedLater> allQueries = ...
foreach(var q in allQueries )
{
    Type elementType = Type.GetType(q.entityTypeFullName);
    MethodInfo method = typeof(myDbContext).GetMethod("Set",
                                  BindingFlags.Public | BindingFlags.Static);
    method = method.MakeGenericMethod(elementType);
    var _dbSet = method.Invoke(db,null);

    var typeReturnedByInvoke_type_of_dbset = **...How Do I Get this type?...**
    MethodInfo _method = typeReturnedByInvoke_type_of_dbset.GetMethod("FromSqlRaw",
                                  BindingFlags.Public | BindingFlags.Static);

    object[] frontParameter = { sql };
    var allParameters = frontParameter.Concat(parameters).ToArray();

    // The "null" is because it's a static method
    var result = _method.Invoke(_dbSet, allParameters);
}

But how do I get the type of the result of method.Invoke? Or is there a way to avoid all these invokes and just cast the result of the first invoke to the right DbSet<elementType> and continue from there without reflection?

Thank you in advance for any help!





Aucun commentaire:

Enregistrer un commentaire