以正确的方式从SQL Server获取单个记录

我正在使用Ado通过id检索单个记录。 注意:

public async Task GetImage(int id) { var image = new Image(); using (SqlConnection conn = new SqlConnection(ConnectionString)) { conn.Open(); string sql = @" SELECT * FROM Images where id = @id"; using (SqlCommand comm = new SqlCommand(sql, conn)) { comm.Parameters.AddWithValue("@id", id); var reader = await comm.ExecuteReaderAsync(); int ordId = reader.GetOrdinal("id"); int ordName = reader.GetOrdinal("name"); int ordPath = reader.GetOrdinal("path"); while (reader.Read()) { image.Id = reader.GetInt32(ordId); image.Name = reader.GetString(ordName); image.Path = reader.GetString(ordPath); } return image; } } } 

正如您所看到的,我正在使用While来遍历记录。 因为虽然表示可能有多个记录要迭代,但我相信这可能是获取单个记录的错误方法。 考虑到ADO对于一行一个字段具有ExecuteScalar,它们可能具有针对一行多个字段的指定方式。 是否有指定的方法来获取ADO中的单个记录?

我会采用你当前的方法,除了我消除了while循环。 如果要确保只返回一个记录,请执行额外的Read以确保它返回false。 这类似于LINQ Single运算符的语义。

 if (!reader.Read()) throw new InvalidOperationException("No records were returned."); image.Id = reader.GetInt32(ordId); image.Name = reader.GetString(ordName); image.Path = reader.GetString(ordPath); if (reader.Read()) throw new InvalidOperationException("Multiple records were returned."); 

假设数据库中的id列是主键(唯一),则无需在SQL查询中指定TOP子句; SQL Server查询优化器将推断出由于WHERE子句,最多只返回一条记录。 但是,如果id列上没有主键或唯一索引/约束,则应发出TOP (2)子句以限制返回的行数。 您应该避免使用TOP (1)因为您将无法检测(并引发错误)额外匹配。

 string sql = @"SELECT TOP (2) * FROM Images WHERE id = @id" 

如果您只阅读一次怎么办:

 using (SqlConnection conn = new SqlConnection(ConnectionString)) { conn.Open(); string sql = @" SELECT id, name, path FROM Images where id = @id"; using (SqlCommand comm = new SqlCommand(sql, conn)) { comm.Parameters.AddWithValue("@id", id); using (var reader = await comm.ExecuteReaderAsync()) { if (!reader.Read()) throw new Exception("Something is very wrong"); int ordId = reader.GetOrdinal("id"); int ordName = reader.GetOrdinal("name"); int ordPath = reader.GetOrdinal("path"); image.Id = reader.GetInt32(ordId); image.Name = reader.GetString(ordName); image.Path = reader.GetString(ordPath); return image; } } } 

PS:我还更改了select语句,只在select语句中选择了必需的字段和包装的reader。

在这种情况下,您可以在查询中使用Top(1)从数据库中仅获取单个记录:

 SELECT Top(1) * FROM Images where id = @id order by id desc -- will get the latest record