Вызовите метод EF Core с типом generi c из имени типа - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть приложение, регистрирующее список запросов, которые будут выполнены позже. Итак, у меня есть список, содержащий что-то вроде этого:

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

И мне нужно выполнить их как:

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();
}

Но, конечно, это не работает.

Я не настолько знаком с рефлексией. До сих пор я был в состоянии получить dbSet с этим:

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);
}

Что, конечно, не работает, потому что:

enter image description here

Я, вероятно, должен делать что-то вроде этого:

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);
}

Но как мне получить тип результата method.Invoke?

Или есть способ избежать всего эти вызовы и просто приведите результат первого вызова вправо DbSet<elementType> и продолжайте оттуда без размышлений?

Заранее спасибо за любую помощь!

1 Ответ

1 голос
/ 20 апреля 2020

Вы выяснили, как вызывать единственный обобщенный метод c с помощью рефлексии, и это все, что вам нужно. Просто введите RunQuery<TEntity> и назовите это.

EG

    public static List<object> RunQuery(QuerySpec query, DbContext db)
    {
        Type elementType = Type.GetType(query.entityTypeFullName);
        var rv = typeof(Program).GetMethod("RunQuery2", BindingFlags.Static | BindingFlags.NonPublic)
                                .MakeGenericMethod(elementType)
                                .Invoke(null, new object[] { query, db });
        return (List<Object>)rv;

    }
    private static List<object> RunQuery2<T>(QuerySpec query, DbContext db) where T : class
    {
        var rv = db.Set<T>().FromSqlRaw(query.sql, query.parameters)
                   .Select( e=>(object)e )
                   .ToList();
        return rv;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...