簡體   English   中英

以正確的方式從SQL Server獲取單個記錄

[英]Get a single record from SQL Server the correct way

我正在使用Ado通過id檢索單個記錄。 注意:

public async Task<Image> 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來遍歷記錄。 因為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM