请原谅任何天真,我是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为null,这对于站点的主页是正确的。这引出了一个问题:
为什么此查询会在我的查询中将主页变为p
?我误解了什么?
答案 0 :(得分:4)
你的第一行
WebPages = (FROM p in CrmContext.Adx_webpageSet WHERE p.Adx_HiddenFromSitemap != true SELECT p).ToArray();
将返回您站点地图中未隐藏的所有页面。但这也包括没有父ID的主页。因此,当您的第二个查询枚举此集合时,它将尝试访问此属性,该属性为null并抛出空引用异常。您只需在查询中满足此要求。
Adx_webpage[] childPages =
(FROM p in WebPages WHERE
p.adx_parentpageid.Id != null &&
p.adx_parentpageid.Id == page.Id SELECT p).ToArray();
答案 1 :(得分: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循环迭代数组中的每个元素相同,因此您必须担心检查第一个查询返回的可能空值。
答案 2 :(得分: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();