Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将linq与Sharepoint一起使用并处理对象_Linq_Sharepoint - Fatal编程技术网

将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#迭代器可以为您处理处理。使用my
AsSafeEnumerable()
扩展方法,您的代码编写起来相对安全,如下所示:

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,以查询列表和项目。享受吧!