我似乎在我的代码中写了很多这样的内容:
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");
}
}
有一些内置的方法可以做到这一点我不知道吗?
答案 0 :(得分:15)
我不知道,但是这段代码可以委托给扩展方法:
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()))
}
免于代码重复。
答案 1 :(得分:10)
根据您的目标,这可能会有所帮助,也可能不会有所帮助。如果您需要检测返回多行以便抛出适当的异常,那么这将无济于事。
如果您只想确保只返回一个结果,则可以使用此方法获得性能提升。据我所知,数据提供者可以使用它来优化查询,以预测单行结果。
在任何情况下,您要做的是使用SqlCommand.ExecuteReader创建数据读取器,但从CommandBehavior枚举(特别是CommandBehavior.SingleRow)传入参数。重载ExecuteReader以接受此操作。
SqlCommand.ExecuteReader overload
所以你的代码可能如下所示:
using (var reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (reader.Read())
{
result = new User((int)reader["UserId"], reader["UserName"].ToString());
}
}
答案 2 :(得分:1)
如果您使用sql来获取您的数据,这可能有助于您在每个需要使用数据读取器的实例中删除这种编码。
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'
另一个提示使用存储过程,使用它们可以最大限度地减少SQL查询的重复和不必要的编码。