ObjectDataSource with Linq to SQL (DataContext disposed error)
架構上, 我們會有一個Business的Object去handle商業邏輯,
所以為類別增加…
using System.ComponentModel;
[DataObject(true),Serializable()]
public class ...
並希望能夠reuse DataContext,
internal DataClassesDataContext context;
public BizObject() {
context = new DataClassesDataContext();
context.Log = new DebugTextWriter();
}
public BizObject(DataClassesDataContext context)
{
this.context = context;
}
public BizObject(Utilities u) {
context = u.context;
}
為了怕 DataContext沒有release,
public class BizObject :IDisposable
{
#region IDisposable 成員
public void Dispose() {
try {
if (context != null)
context.Dispose();
} catch (Exception) { }
}
#endregion
在使用者界面上, 使用GridView 並引用ObjectDataSource來 binding,
在預設狀況, 因為ObjectDataSource 在做Select operation後會將 DataObject Dispose掉,
所以, 就會收到這樣的錯誤
無法存取已處置的物件。
例外詳細資訊: System.ObjectDisposedException: 無法存取已處置的物件。 |
故, 我們得接管ObjectDataSource的生命週期
(1) 宣告全域變數, 並於初始階段, 建立物件
internal BizObject utilities;
protected void Page_Init(object sender, EventArgs e) {
utilities = new BizObject();
}
(1) oncreating, 指定物件實體為全域變數之物件
aspx:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
onobjectcreating="ObjectDataSource1_ObjectCreating" />
cs:
protected void ObjectDataSource1_ObjectCreating(object sender, ObjectDataSourceEventArgs e) {
e.ObjectInstance = utilities;
}
(2) onobjectdisposing, 取消預設程序
protected void ObjectDataSource1_ObjectDisposing(object sender, ObjectDataSourceDisposingEventArgs e) {
e.Cancel=true;
}
(3) 最後是釋放, (註: for postback only)
protected void Page_Unload(object sender, EventArgs e) {
Release();
}
protected void Page_Error(object sender, EventArgs e) {
Release();
}
private void Release() {
try {
if (utilities != null)
utilities.Dispose();
} catch (Exception) {
}
}
BTW, ObjectDataSource + GridView + LinqToSql 個人覺得並不好用,
因為Update時, LinqToSql 需要將DataContext取回的物件做PropertyChange, 才能SubmitChange(),
但這樣的架構下, 因為GridView的Update event是將資料bind到一個自建的資料物件, 所以無法正常變更, 必須另外加取物件 + PropertyChange 有點麻煩
Deleted 時也是同樣情況, 但 ObjectDataSource_OnDeleting事件並不能對InputParameter進行修改(唯讀),
以上導致原本的BizObject 得為這些狀況另外Coding …
如果有什麼好解決方案, 請各位大大不吝指教, 謝謝