使用块防止对象在内部处置
Prevent object dispose inside using block
工作流程:
我有一个有两种形式的 winform 应用程序,在第一种形式中,我查询 liteDB
并在 using
块中操作 IEnumerable<T>
实例 检索到的数据。
IEnumerable<student> searchResult;
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
searchResult = col.Find(x => x.contact.phone == "123456789");
}
Form2 frm2 = new Form2();
Form2.profileData = searchResult.AtElement(index);
问题:
然后,我需要将 searchResult<student>
的元素发送到第二个表单以向用户显示,正如您在上面代码的最后两行中看到的那样。
但是因为它在 using
块内,所以我得到 System.ObjectDisposedException
.
数据类型和异常:
studentCollection.Find()
:
searchResult
:
例外:
加法:
我已经想到的可能的方法是:
覆盖并取消现有的 dispose()
方法,然后在完成后调用我自己实现的方法;这基本上等于没有 using
块,除了我不必处理上面 using
块中的其他对象,而只需要 searchResult<student>
.
P.S:
I'm newbie at whole thing, appreciate the help and explanation
我不熟悉 LiteDb,但我认为它 return 是数据库的代理对象。所以当数据库被处理掉后,proxy-object就不再可用了。
避免该问题的简单方法是在.Find(...)
之后添加.ToList()
。这会将proxy-list转换为内存中的实际List<T>
,并在数据库处理后才能使用。列表中的 student
对象可能是 也是 代理,如果是这种情况,这将失败。
如果是这种情况,您要么需要找到某种方法使数据库 return 成为真实的 non-proxy 对象,要么将数据库的生命周期延长到比您的表单更长的生命周期, 例如
IList<student> myIList;
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
myIList = col.Find(x => x.contact.phone == "123456789");
using(var frm2 = new Form2()){
frm2.profileData = myIList.AtElement(index);
frm2.ShowDialog(this);
}
}
注意 .ShowDialog
的用法,这将阻塞直到第二个表单关闭。这不是绝对必要的,但可以更轻松地管理数据库的生命周期。
您需要在退出 using 块之前访问该元素。
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
var searchResult = col.Find(x => x.contact.phone == "123456789");
Form2 frm2 = new Form2();
Form2.profileData = searchResult.AtElement(index);
}
工作流程:
我有一个有两种形式的 winform 应用程序,在第一种形式中,我查询 liteDB
并在 using
块中操作 IEnumerable<T>
实例 检索到的数据。
IEnumerable<student> searchResult;
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
searchResult = col.Find(x => x.contact.phone == "123456789");
}
Form2 frm2 = new Form2();
Form2.profileData = searchResult.AtElement(index);
问题:
然后,我需要将 searchResult<student>
的元素发送到第二个表单以向用户显示,正如您在上面代码的最后两行中看到的那样。
但是因为它在 using
块内,所以我得到 System.ObjectDisposedException
.
数据类型和异常:
studentCollection.Find()
:
searchResult
:
例外:
加法:
searchResult
:
我已经想到的可能的方法是:
覆盖并取消现有的 dispose()
方法,然后在完成后调用我自己实现的方法;这基本上等于没有 using
块,除了我不必处理上面 using
块中的其他对象,而只需要 searchResult<student>
.
P.S: I'm newbie at whole thing, appreciate the help and explanation
我不熟悉 LiteDb,但我认为它 return 是数据库的代理对象。所以当数据库被处理掉后,proxy-object就不再可用了。
避免该问题的简单方法是在.Find(...)
之后添加.ToList()
。这会将proxy-list转换为内存中的实际List<T>
,并在数据库处理后才能使用。列表中的 student
对象可能是 也是 代理,如果是这种情况,这将失败。
如果是这种情况,您要么需要找到某种方法使数据库 return 成为真实的 non-proxy 对象,要么将数据库的生命周期延长到比您的表单更长的生命周期, 例如
IList<student> myIList;
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
myIList = col.Find(x => x.contact.phone == "123456789");
using(var frm2 = new Form2()){
frm2.profileData = myIList.AtElement(index);
frm2.ShowDialog(this);
}
}
注意 .ShowDialog
的用法,这将阻塞直到第二个表单关闭。这不是绝对必要的,但可以更轻松地管理数据库的生命周期。
您需要在退出 using 块之前访问该元素。
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
var searchResult = col.Find(x => x.contact.phone == "123456789");
Form2 frm2 = new Form2();
Form2.profileData = searchResult.AtElement(index);
}