首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

SqlDataSource 控制項處理 Image/VarBinary(MAX) 欄位完整解決方案

     編輯:關於.NET

問題背景

使用 SqlDataSource 綁定預存程序新增資料時,若資料表含 Image 或 VarBinary(MAX) 欄位,精靈產生的參數類型為 Type="Object",運行時拋出:

「sql_variant 類型無法轉換為 Image 類型」 或 「Parameter '@ImageData' exceeds the size limit for the sql_variant datatype」

原因:Object 對應 sql_variant,最大 8000 位元組,不支援大型二進位資料。

解決方案:Inserting 事件手動建立 SqlParameter

1. 移除自動產生的錯誤參數

<asp:SqlDataSource ID="studentDataSource" runat="server" 
    ConnectionString="<%$ ConnectionStrings:ConnStr %>"
    InsertCommand="spStudentRecordAdd" InsertCommandType="StoredProcedure">
    <InsertParameters>
        <asp:Parameter Name="StudentName" Type="String" />
        <asp:Parameter Name="StudentID" Type="Int32" />
        <!-- 移除這行:<asp:Parameter Name="Photo" Type="Object" /> -->
    </InsertParameters>
</asp:SqlDataSource>

2. 在 Inserting 事件中注入正確參數

protected void studentDataSource_Inserting(object sender, SqlDataSourceCommandEventArgs e)
{
    // 取得 FileUpload 控件(假設在 FormView 模板中)
    FileUpload fu = FormView1.FindControl("FileUpload1") as FileUpload;
    byte[] imageData = new byte[0];

    if (fu != null && fu.HasFile)
    {
        imageData = fu.FileBytes;
    }

    // 關鍵:建立 SqlDbType.Image 參數
    SqlParameter photoParam = new SqlParameter("@Photo", SqlDbType.Image);
    photoParam.Value = imageData;

    // 加入命令參數集合
    e.Command.Parameters.Add(photoParam);
}

為什麼用 SqlDataSource.Inserting 而非 FormView.ItemInserting?

  • FormView.ItemInserting 僅能存取 e.Values 字典,無法直接操作 DbCommand 參數集合。
  • SqlDataSource.Inserting 提供 SqlDataSourceCommandEventArgs,暴露 e.Command 完整命令物件,可直接添加強型別參數。

完整頁面代碼片段

<asp:FormView ID="FormView1" runat="server" DataSourceID="studentDataSource" DefaultMode="Insert">
    <InsertItemTemplate>
        學生姓名: <asp:TextBox ID="txtName" runat="server" Text='<%# Bind("StudentName") %>' /><br/>
        學號: <asp:TextBox ID="txtID" runat="server" Text='<%# Bind("StudentID") %>' /><br/>
        照片: <asp:FileUpload ID="FileUpload1" runat="server" /><br/>
        <asp:LinkButton ID="InsertButton" runat="server" CommandName="Insert" Text="新增" />
    </InsertItemTemplate>
</asp:FormView>

<asp:SqlDataSource ID="studentDataSource" runat="server" 
    OnInserting="studentDataSource_Inserting"
    ... />

效能與架構建議

方案優點缺點
資料庫儲存二進位交易一致性、備份完整、權限集中資料庫膨脹、備份慢、串流效能差
檔案系統儲存 + 路徑存 DB資料庫輕量、串流快、CDN 友善交易一致性難、檔案權限管理、備份分離
Filestream / FileTable (SQL 2008+)結合兩者優點、NTFS 串流、全文檢索設定複雜、需特定版本/版本

建議:除非資料量極小且強調 ACID,優先考慮檔案系統或雲端儲存(Blob Storage),資料庫僅存 URL/路徑。

總結

SqlDataSource 處理大型二進位欄位的關鍵在於:移除 Type="Object" 參數,在 Inserting 事件中手動建立 SqlDbType.Image(或 VarBinary)參數並注入 e.Command.Parameters。此技巧同樣適用於 UpdateParameters 與 Updating 事件。

本文出自「王傑瑞的技術部落格」:原文連結

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved