簡體   English   中英

如何訪問存儲在SQL Server FileTable中的文件?

[英]How to access files stored in SQL Server's FileTable?

據我所知,自2012版以來的SQL Server具有一項新功能FileTable 它使我們可以將文件存儲在文件系統中,並可以通過T-SQL使用它們。

我正在嘗試使用此功能,我不知道如何正確執行。

通常,我不知道如何訪問文件表中存儲的文件。 假設我有asp.net MVC應用程序,並且在網頁上的img標簽中顯示了很多圖像。 我想將這些圖像存儲在Filetable中,並從文件系統中以文件形式訪問它們。 但是我不知道這些文件存儲在哪里以及如何將它們用作文件。 現在,我的圖像存儲在Web應用程序目錄中的文件夾圖像中,我編寫如下內容:

<img src='/images/mypicture.png' />

如果我將圖像移動到文件表,應該在src中寫什么?

<img src='path-toimage-in-filetable' />

我假設FileTable實際上是指FileStream。 關於此的一些注意事項:

  1. 如果您的文件實際上是文件,則最好使用此功能
  2. 文件平均應大於1mb-盡管此規則可能會有例外,但是如果文件平均小於1mb,則最好使用VARBINARY(MAX)XML數據類型。 如果圖像平均很小(只有幾個KB),請考慮使用VARBINARY(MAX)列。
  3. 訪問這些文件將需要一個打開的事務,並且已為FILESTREAM正確配置了數據庫
  4. 通過告訴SQL Server您要直接訪問文件,可以繞過常規SQL引擎/數據庫文件的數據訪問方法,可以獲得一些顯着的優勢,但是,這並不意味着直接訪問文件系統上的文件並且嘗試這樣做可以破壞SQL對這些文件的管理(事務一致性,跟蹤,鎖定等)。
  5. 如果您確實需要SQL,則很有可能通過使用CDN並在表中存儲圖像URL來更好地滿足您的用例。 可以使用FILESTREAM來執行此操作(有關一種實現,請參見下面的代碼示例),但是除非您將圖像存儲在瀏覽器可以正常緩存的其他位置,否則您將為每個請求重用SQL Server(我的示例不這樣做)那)-如果您將它們存儲在其他位置以在瀏覽器中呈現,則最好將它們存儲在此處(這些圖像一旦復制到其他驅動器/磁盤/位置,就不會具有事務一致性) )。

綜上所述,這是一個如何使用ADO.NET訪問FILESTREAM數據的示例:

public static string connectionString = ...; // get your connection string from encrypted config

// assumes your FILESTREAM data column is called Img in a table called ImageTable
const string sql = @"
    SELECT            
        Img.PathName(),
        GET_FILESTREAM_TRANSACTION_CONTEXT()
      FROM ImageTagble
      WHERE ImageId = @id";

public string RetreiveImage(int id)
{
    string serverPath;
    byte[] txnToken;
    string base64ImageData = null;
    using (var ts = new TransactionScope())
    {
        using (var conn = new SqlConnection(connectionString))
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand(sql, conn))
            {
                cmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
                using (SqlDataReader rdr = cmd.ExecuteReader())
                {
                    rdr.Read();
                    serverPath = rdr.GetSqlString(0).Value;
                    txnToken = rdr.GetSqlBinary(1).Value;
                }
            }
            using (var sfs = new SqlFileStream(serverPath, txnToken, FileAccess.Read))
            {
            // sfs will now work basically like a FileStream.  You can either copy it locally or return it as a base64 encoded string
               using (var ms = new MemoryStream())
               {
                  sfs.CopyTo(ms);
                  base64ImageData = Convert.ToBase64String(ms.ToArray());
               }
            }
        }
        ts.Complete();
        // assume this is PNG image data, replace PNG with JPG etc. as appropraite.  Might store in table if it will vary...
        return "data:img/png;base64," + base64ImageData;
    }
}

顯然,如果您要處理大量圖像,這不是理想的方法-請勿嘗試將SQL Server實例轉換為應使用CDN的對象。...但是,如果您確實有其他有充分的理由,您應該嘗試在單個請求/事務中獲取盡可能多的圖像(例如,如果您知道在一個頁面上顯示50張圖像,請使用單個交易范圍獲取全部50張圖像,而不使用50個交易范圍-此代碼將無法處理)。

我認為您仍然不需要這個,反正我會將答案發布給其他感興趣的人。 首先,文件表仍然是表,因此,如果要從中訪問數據,則需要使用Select SQL語句。 因此,您需要以下內容:

select name, file_stream from filetable_name 
where 
name = 'file_name',
file_type = 'file_extension'

只需在asp.net應用中執行這樣的語句,然后獲取結果並使用file_stream列即可獲取存儲文件的二進制數據。 如果要從HTML檢索文件,則首先需要在控制器中創建一個操作,該操作將返回檢索到的文件:

public ActionResult GetFile(){
..
return File(file.file_stream,file.file_type);
}

之后,在您的HTML標記中添加以下內容:

<img src="/controller/GetFile" />

希望這會有所幫助! 如果您想了解文件表的架構,請參見此處

暫無
暫無

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

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