Как использовать Generic с SqlDataReader - PullRequest
0 голосов
/ 02 сентября 2018

Я пытаюсь найти способ просто загрузить таблицу из SQL Server в класс, не сообщая ему ничего. По сути, просто создайте класс и пусть он знает, что загружать, основываясь на этом. Вот что у меня есть.

Мой вопрос заключается в том, есть ли какой-то способ избежать необходимости жесткого кодирования типов, чтобы вызвать reader.readString, reader. readInt32 и т. д. на основе FieldType?

 private Int32? readInt32(SqlDataReader reader, string columnName)
    {
        Int32? result = null;


        if (!reader.IsDBNull(reader.GetOrdinal(columnName)))
        {
            result = reader.GetInt32(reader.GetOrdinal(columnName));
        };

        return result;
    }

  public List<T> readTable(string table, string wherecls, string connStr)
    {
        List<T> result = new List<T>();
        using (SqlConnection connection = new SqlConnection(connStr))
        {
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = "select * from " + table;
                if (wherecls.Length > 0) command.CommandText += " where " + wherecls;
                connection.Open();
                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Object i = Activator.CreateInstance(typeof(T));

                        System.Reflection.FieldInfo[] fieldInfoList = typeof(T).GetFields();
                        foreach (System.Reflection.FieldInfo f in fieldInfoList)
                        {
                            if (f.FieldType == typeof(string)) f.SetValue(i, readString(reader, f.Name));
                            if (f.FieldType == typeof(Int32)) f.SetValue(i, readInt32(reader, f.Name));
                            if (f.FieldType == typeof(Int16)) f.SetValue(i, readInt16(reader, f.Name));
                            if (f.FieldType == typeof(byte)) f.SetValue(i, readByte(reader, f.Name));
                            if (f.FieldType == typeof(short)) f.SetValue(i, readShort(reader, f.Name));
                        }
                        result.Add((T)i);
                    }
                }
            }
        }
        return result;
    }

Спасибо, Дэн Чейз

1 Ответ

0 голосов
/ 02 сентября 2018

То, что вы описываете, - это большая работа ... и это именно то, что инструменты типа "dapper" уже делают . Так что мое предложение здесь: использовать dapper :

// Dapper adds a Query<T>(this DbConnection, ...) extension method
var data = connection.Query<T>(sql, args).AsList();

Я будет , однако, скажу, что string wherecls посылает дрожь по моему позвоночнику - это звучит как кошмар SQL-инъекции. Но ... это зависит от вас.

...