将linq与Sharepoint一起使用并处理对象
如何在下面的查询中处理对子网站的引用将linq与Sharepoint一起使用并处理对象,linq,sharepoint,Linq,Sharepoint,如何在下面的查询中处理对子网站的引用 using (SPSite spSite = Utility.GetElevatedSite(_rootUrl)) { from SPWeb web in spSite.AllWebs where web.ServerRelativeUrl.ToLower() == path from SPWeb subWeb in web.Webs select subWeb } 如
using (SPSite spSite = Utility.GetElevatedSite(_rootUrl))
{
from SPWeb web in spSite.AllWebs
where web.ServerRelativeUrl.ToLower() == path
from SPWeb subWeb in web.Webs
select subWeb
}
如果iam已经在Using语句中包装了spSite,我甚至需要担心处理子网站吗
编辑:
在这种情况下,调用垃圾收集也是一个好主意吗?不幸的是,您这样做了。
问题源于SPSite.AllWebs属性。
SPWeb.Web属性也不安全
阅读您需要担心处理SharePoint对象的情况
(我建议将其添加到SharePoint备忘单中)
因此,我觉得当前的SharePoint对象模型不能安全地与LINQ语法一起使用
您的代码需要重新编写,并中断各种隐含循环,以便可以显式地处理所涉及的对象
编辑:
SPDisposeCheck工具是一个命令行控制台应用程序,它将扫描您的.NET程序集,并根据上述最佳实践指导原则警告您未发现的引用。看看吧
原始问题的技术答案是一个限定的“否”:从
SPSite
打开的所有SPWeb
对象在SPSite
被释放时自动被释放。但是,在实践中,最好在使用完SPWeb
后立即处理它,以减少内存压力,尤其是在使用这样的代码时,它会打开多个SPWeb
对象
在C#中,为LINQ实现这个dispose-safe行为实际上非常简单。您可以在中找到完整的详细信息,但简短的版本是C#迭代器可以为您处理处理。使用myAsSafeEnumerable()
扩展方法,您的代码编写起来相对安全,如下所示:
using (SPSite spSite = Utility.GetElevatedSite(_rootUrl))
{
var sw = from SPWeb web in spSite.AllWebs.AsSafeEnumerable()
where web.ServerRelativeUrl.ToLower() == path
from SPWeb subWeb in web.Webs.AsSafeEnumerable()
select subWeb;
foreach(SPWeb aSubWeb in sw)
{
// Do something
}
}
现在,我分配给sw
的查询结果是IEnumerable
类型的惰性迭代器。在对该结果进行枚举时,当枚举器移动到下一项时,每个SPWeb
都将被处理。这意味着在foreach
循环之外使用该SPWeb
引用或由此创建的任何SP*对象(SPList
等)是不安全的。另外,sw
在使用
块之外使用也不安全,因为迭代器的SPWebCollections
将绑定到现在处理的SPSite
这就是说,像这样在所有Web上枚举(两次!)的代码非常昂贵。如果只使用spSite.AllWebs[path]
而不是从/where
执行,几乎可以肯定有一种更有效的方法可以实现这一点
关于垃圾收集,这些对象需要处理,因为分配了GC甚至不知道的非托管内存
最后,请注意“GetElevatedSite”实用程序。如果在助手方法中使用RunWithElevatedPrivileges
来获取提升的SPSite
,那么从提升的上下文返回SPSite
可能会遇到许多问题。如果可能的话,我建议改用SPSite
模拟-我的首选方法如下所述。Sahrepoint放在一边,我认为在一般情况下使用linq时不可能使用任何外部资源,对吗?SharePoint的问题是,托管部分非常小。但是SPWeb和SPSite实例持有对非托管SPRequest对象的引用,该对象可能为1-2MB。当GC速度不够快时,SharePoint会耗尽内存。我的理解是,当我们将LINQ与DataContext一起使用时,在LINQ使用完之后,您会对整个DataContext进行处理,从而释放外部资源。所以,是的,这将是我的假设,LINQ不会为开发人员处理。干杯,伙计,非常有用的东西!另一个问题,在这种情况下,你会调用/使用垃圾收集吗?干杯,伙计,真的很有帮助。每当我使用linq查询时,我通常会[选择进入某个对象]。我无法想象在没有linq的情况下编程对象模型。IF分支将有多个级别的深度!但我想这两种方法都有赞成/反对的地方……当然,我真的开始着手研究。只要您选择了非SharePoint内容,您就可以了,您就不能返回依赖于现在处理的web的对象。您可以在下面添加更多LINQ,以查询列表和项目。享受吧!