Search code examples
c#.netado.netsqldatareaderdatareader

Enforce only single row returned from DataReader


I seem to write this quite a lot in my code:

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

Is there some built in way to do this that I don't know about?


Solution

  • I don't know, but this code can be delegated into an extension method:

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

    to be used like that:

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

    Saving you from code duplication.