﻿# 解決 LINQ to SQL 針對更新大型物件的效率極差的問題

我有一個頁面是使用 DetailsView 進行資料的新增與更新動作，其中有個圖片欄位在資料庫中的資料格式為 VarBinary(MAX)，直接用來儲存圖檔的二進位內容，在新增資料的時候上傳檔案並存入資料庫中，在更新的時候直更新該欄位的內容，不過在更新的時候執行的時間都非常久，即便是上傳 10KB 左右的圖檔，在執行到 db.SubmitChanges(); 時都會執行個 30 秒以上，如果上傳幾 MB 的檔案就要執行好幾分鐘，所以常常會發生 Timeout 的情況。

這個問題大約困擾我將近一個月的問題，因為實在已經嘗試了太多作法（都是用 LINQ to SQL 的方式）都無法改善效能問題，直到今天用 MSN 問一個朋友這個狀況的時候，問題才剛問完自己就突然靈機一動想到了一個解決方法，也就是嘗試將該 VarBinary(MAX) 欄位設定 UpdateCheck="Never" 看看，結果就真的完全解決效能問題了。

> 有時候真的很奇怪，自己想不通的問題在問別人時通常會將問題重新思考過一遍，進而更了解問題本身。所以人家才會常說：「當你會問題的時候，問題就已經先解決一半」，我非常的感同身受。

首先，先開啟你的 \*.dbml 檔，找出這個欄位：

```
<Column Name="ContentData" Type="System.Data.Linq.Binary" DbType="VarBinary(MAX) NOT NULL" 
        CanBeNull="false" />
```

然後將該欄位加上 UpdateCheck="Never" 屬性，然後儲存。

```
<Column Name="ContentData" Type="System.Data.Linq.Binary" DbType="VarBinary(MAX) NOT NULL" 
        CanBeNull="false" UpdateCheck="Never" />
```

加上這個屬性之後，LINQ to SQL 對這個表格就會採用「閉式並行存取控制（Pessimistic Concurrency Control）」的方式進行更新作業，也就是說當 LINQ to SQL 在更新 Binary 格式的欄位時就不會在去判斷檔案的內容是否有異動，直接將更新的檔案內容直些寫入資料庫。

**相關連結**

-   [解決 LINQ to SQL 資料庫更新衝突的情形](/post/2008/05/24/Resolve-LINQ-to-SQL-Change-Conflict-Exception)
