2

请原谅任何天真,我是 C# 世界的新手。如果我遗漏了有用的信息,请告诉我。

我正在为 Dynamics CRM 2011 的客户门户构建一个自定义 SiteMapProvider。首先我初始化一个数组:

public Adx_webpage[] WebPages;

这样就被填充了:

public MyProvider()
{
    WebPages = (FROM p in CrmContext.Adx_webpageSet WHERE p.Adx_HiddenFromSitemap != true SELECT p).ToArray();
}

后来,我尝试像这样查询 WebPages[]:

Adx_webpage[] childPages = (FROM p in WebPages WHERE p.adx_parentpageid.Id == page.Id SELECT p).ToArray();

当我通过调试器运行它时,我得到一个 NullReferenceException,它指向我的 WHERE 子句中的条件,说 p.adx_parentpageid.Id 为空,这对于网站的主页是正确的。这导致了一个问题:

为什么这个查询会在我的查询中显示主页p?我有什么误解?

4

3 回答 3

4

你的第一行

    WebPages = (FROM p in CrmContext.Adx_webpageSet WHERE p.Adx_HiddenFromSitemap != true SELECT p).ToArray();

将返回您站点地图中未隐藏的所有页面。但这也包括您没有父 ID 的主页。因此,当您的第二个查询枚举此集合时,它将尝试访问此为空的属性并引发空引用异常。您只需要在查询中满足这一点。

Adx_webpage[] childPages = 
(FROM p in WebPages WHERE 
p.adx_parentpageid.Id != null &&
p.adx_parentpageid.Id == page.Id SELECT p).ToArray();
于 2011-12-06T23:26:55.467 回答
1

问题是您第一次查询时的 .ToArray() 。此 linq 查询正在为您的 CrmContext 提供程序创建本机查询:

WebPages = (FROM p in CrmContext.Adx_webpageSet WHERE p.Adx_HiddenFromSitemap != true SELECT p).ToArray();  

.ToArray() 导致 linq 查询立即运行并返回一个普通的旧对象数组。该数组未附加到您的 CrmContext 对象。

但是,此查询使用Linq to Objects迭代第一次调用中返回的数组。它不会为您的 CrmContext 提供程序生成本机查询。

Adx_webpage[] childPages = (FROM p in WebPages WHERE p.adx_parentpageid.Id == page.Id SELECT p).ToArray());    

它实际上与使用 foreach 循环遍历数组中的每个元素相同,因此您必须担心检查第一个查询返回的可能的空值。

于 2011-12-06T23:16:30.513 回答
1

我不明白你的问题。您是说主页是一个网页,并且不会从站点地图中隐藏,那么您为什么希望主页在您的查询中显示为p?

无论如何,您可以简单地跳过任何内容p == null

Adx_webpage[] childPages = (FROM p in WebPages
                            WHERE p.adx_parentpageid != null &&
                                  p.adx_parentpageid.Id == page.Id
                            SELECT p).ToArray();
于 2011-12-06T23:24:24.213 回答