在阅读Stefan Gossner's post关于处理对象和Cross method dispose patterns这个问题后,我发现我犯了意外重新打开一些SPWebs的罪行。我知道在Stefan Gossner的帖子中他提到你应该在完成任何子对象之后处理SPWeb。但是,microsoft documentation提到缓存SPListItemCollection对象。以下代码是否正确?返回的SPListItemCollection会重新打开SPWeb对象吗?有什么方法可以肯定吗?
// is this correct????
private SPListItemCollection GetListItems()
{
SPListItemCollection items = null;
try
{
using (SPSite site = new SPSite(GetListSiteUrl()))
{
using (SPWeb web = site.OpenWeb())
{
// retrieve the list
SPList list = web.Lists[_ListName];
// more code to create the query...
items = list.GetItems(query);
}
}
}
catch (Exception e)
{
// log error
}
return items;
}
编辑09/09/09
我主要是指Stefan Grossner's post的这一部分:
您应该处置SPWeb或SPSite 最后一次访问后的对象 这个对象的子对象。
我相信他所说的是,如果我在处理过去的SPWeb之后使用SPListItemCollection ...... SPWeb将自动重新打开。
答案 0 :(得分:4)
我在asking Stefan directly之后发现SPListItemCollection确实可以在你处理后重新打开SPWeb。这意味着上面发布的代码是INCORRECT,我只能在使用SPListItemCollection后处理SPWeb。
更新:最好将SPListItemCollection转换为其他内容,然后返回。
private DataTable GetListItems()
{
DataTable table = null;
try
{
SPListItemCollection items = null;
using (SPSite site = new SPSite(GetListSiteUrl()))
{
using (SPWeb web = site.OpenWeb())
{
// retrieve the list
SPList list = web.Lists[_ListName];
// more code to create the query...
items = list.GetItems(query);
// convert to a regular DataTable
table = items.GetDataTable();
}
}
}
catch (Exception e)
{
// log error
}
return table;
}
答案 1 :(得分:1)
据我所知,答案是否定的,但我会编写类似
的代码private void FetchItems(Action<SPListItemCollection> action)
{
using(...)
{
var items = list.GetItems(query);
action(items);
}
}
通过执行此操作,要调用此方法,您需要向(委托)发送应该使用SPListItemCollection的方法,例如:
FetchItems(items =&gt; ....)或FetchItems(DoStuffWithItems(SPListItemCollection))
答案 2 :(得分:0)
如果您在谈论在使用SPListItemCollection时是否需要同一范围内的SPWeb时,我认为答案是否定的。
例如,我经常做以下事情:
private IEnumerable<SPListItem> AllItems;
public void GetItems()
{
var results = SPContext.Current.Web.Lists[ListName].Items.Cast<SPListItem>();
this.AllItems = results;
}
然后我在所有地方使用AllItems,它工作正常。
如果你想知道,演员阵容已经完成,我可以在结果集上使用Linq - 比向列表提交查询要快得多,特别是如果你在数据上做了多个子选择。