仅强制从DataReader返回单行

fea*_*net 14 .net c# ado.net datareader sqldatareader

我似乎在我的代码中写了这么多:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

有一些内置的方法可以做到这一点我不知道吗?

flq*_*flq 16

我不知道,但是这段代码可以委托给一个扩展方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

这样使用:

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

从代码复制中拯救你.


bub*_*ing 11

根据您的目标,这可能会有所帮助,也可能没有帮助.如果您需要检测返回多行以便抛出适当的异常,那么这将无济于事.

如果您只想确保只返回一个结果,则可以使用此方法获得性能提升.据我所知,数据提供者可以使用它来优化查询,以预测单行结果.

在任何情况下,您要做的是使用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());
    }
}
Run Code Online (Sandbox Code Playgroud)