Принудительно использовать только одну строку, возвращаемую DataReader

Мне кажется, это довольно много написано в моем коде:

using (var reader = cmd.ExecuteReader())
{
    if (reader.Read())
    {
        result = new User((int)reader["UserId"], reader["UserName"].ToString());
    }

    if (reader.Read())
    {
        throw new DataException("multiple rows returned from query");
    }
}

Есть ли встроенные способы сделать это, о которых я не знаю?

Ответы

Ответ 1

Я не знаю, но этот код можно делегировать в метод расширения:

public static R Single<R>(this DataReader reader, Func<DataReader,R> selector) {
    R result = default(R);
    if (reader.Read())
        result = selector(reader);
    if (reader.Read())
        throw new DataException("multiple rows returned from query");
    return result;
}

для использования следующим образом:

using (var reader = cmd.ExecuteReader())
{
    User u = reader.Single(r => new User((int)r["UserId"], r["UserName"].ToString()))
}

Сохранение от дублирования кода.

Ответ 2

Это может или не может помочь в зависимости от вашей цели. Если вам нужно обнаружить, что несколько строк были возвращены, чтобы создать соответствующее исключение, это не поможет.

Если вы просто хотите удостовериться, что возвращается только один результат, вы можете получить балл производительности с помощью этого метода. Насколько я понимаю, поставщики данных могут использовать это для оптимизации запроса в ожидании результата одной строки.

В любом случае то, что вам нужно сделать, это использовать SqlCommand.ExecuteReader для создания вашего устройства чтения данных, но передайте аргумент из перечисления CommandBehavior (в частности CommandBehavior.SingleRow). ExecuteReader перегружен, чтобы принять это.

перечисление CommandBehavior

Перегрузка SqlCommand.ExecuteReader

Итак, ваш код может выглядеть так:

using (var reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
    if (reader.Read())
    {
        result = new User((int)reader["UserId"], reader["UserName"].ToString());
    }
}

Ответ 3

Если вы используете sql для извлечения ваших данных, это может помочь, позволяя вам удалить этот вид кодирования в каждом случае, который вам нужен для чтения данных.

SELECT TOP ([Number of rows you want to be selected]) 
FROM [Table Name] 
WHERE [Condition]

Пример:

SELECT TOP (1)
FROM tblUsers
WHERE Username = 'Allan Chua'

Другие советы использовать хранимые процедуры, использование их может свести к минимуму повторение SQL-запроса и ненужное кодирование.