LINQ查询中的WHERE子句似乎失败了

时间:2011-12-06 21:46:27

标签: c# linq dynamics-crm-2011 sitemapprovider

请原谅任何天真,我是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?我误解了什么?

3 个答案:

答案 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();