Dapper сильно типизированная коллекция от Type

c# dapper

Вопрос

В моем приложении я использую Dapper для доступа к базе данных.

У меня есть следующий пример кода:

public IEnumerable GetByParentId(Type childType, string table) 
{
    IDbConnection _connection = _dbProvider.GetConnection();

    var _sqlString = "select * from " + table;

    IEnumerable _ret = _connection.Query(_sqlString).ToList(); 
    //return IEnumerable<Dapper.SqlMapper.FastExpando> 

    return _ret;
}

Можно ли FastExpando элемент FastExpando к моему childType или заставить Dapper возвращать строго типизированную коллекцию?

Я не могу изменить свою подпись метода!

Принятый ответ

Вы можете вызвать метод запроса через отражение и предоставить общий аргумент TItem вашего childType. Затем Dapper вернет IEnumerable, и вы сможете его бросить. Кроме того, вы можете форк Dapper (он не очень большой) и сделать очень простой перегруз Query, который будет включать (Type childType) аргумент и вызвать надлежащие методы внутри.

С вами сталкивается проблема C # при работе с дженериками. Будучи статически типизированным языком, C # плохо работает с динамическими типами. Если вы хотите работать динамично, вы всегда оказываетесь в отражении.

Вот пример того, как вы могли бы вызвать метод запроса с аргументами типа. Возможно, вам придется немного поправить это:

    public IEnumerable GetByParentId(Type childType, string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();

        var _sqlString = "select * from " + table;

        var t = typeof(SqlMapper);
        var genericQuery = t.GetMethods().Where(x => x.Name == "Query" && x.GetGenericArguments().Length == 1).First(); // You can cache this object.
        var concreteQuery = genericQuery.MakeGenericMethod(childType); // you can also keep a dictionary of these, for speed.
        var _ret = (IEnumerable)concreteQuery.Invoke(null, new object[] { _connection, _sqlString });

        return _ret;
    }

Append:

Кроме того, здесь я вижу более общую проблему с дизайном. Вы хотите указать тип динамически, но затем хотите получить статически типизированные объекты, которые вы сможете использовать (я предполагаю статически, или вы хотите продолжить отражение?). Затем ... Почему вы создаете динамический интерфейс в первую очередь? Вы говорите, что вы не можете изменить интерфейс, но это выглядит немного глупо. Кажется, что весь ваш контекст статически типизирован, но по какой-то причине у вас есть один динамически типизированный метод. Если вы знаете типы во время компиляции (или через общие аргументы во время выполнения), вы должны просто изменить свой метод на что-то вроде этого:

    public IEnumerable<T> GetByParentId<T>(string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();
        var _sqlString = "select * from " + table;
        var _ret = _connection.Query<T>(_sqlString);
        return _ret;
    }


Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему