Enforce only single row returned from DataReader

梦想与她 提交于 2019-12-12 10:29:24

问题


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?


回答1:


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.




回答2:


This may or may not help depending on what your goal is. If you need to detect that multiple rows were returned in order to throw an appropriate exception, then this won't help.

If you just want to make sure that only one result is returned, you can potentially get a performance bump by using this method. From what I understand, data providers can use this to optimize the query in anticipation of a single row result.

In any case, what you'll want to do is use SqlCommand.ExecuteReader to create your data reader, but pass in an argument from the CommandBehavior enumeration (specifically CommandBehavior.SingleRow). ExecuteReader is overloaded to accept this.

CommandBehavior enum

SqlCommand.ExecuteReader overload

So your code might look like this:

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



回答3:


If you are using a sql to fetch your'e data this might help by letting you remove that kind of coding in every instance that you need to use a data reader.

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

EX:

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

Another tip use stored procedures, Using them could minimize the repetition of SQL query and unnecessary coding.



来源:https://stackoverflow.com/questions/7836517/enforce-only-single-row-returned-from-datareader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!