Enforce only single row returned from DataReader

fearofawhackplanet picture fearofawhackplanet · Oct 20, 2011 · Viewed 31.2k times · Source

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?

Answer

flq picture flq · Oct 20, 2011

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.