Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.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
C# LINQ查询中的WHERE子句似乎失败_C#_Linq_Dynamics Crm 2011_Sitemapprovider - Fatal编程技术网

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

C# LINQ查询中的WHERE子句似乎失败,c#,linq,dynamics-crm-2011,sitemapprovider,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 S

请原谅我的天真,我对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();
}
稍后,我尝试查询网页[],如下所示:

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
?我误解了什么?

问题在于您第一次查询时的.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循环迭代数组中的每个元素相同,因此您必须担心检查第一次查询返回的可能的空值。

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

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

Adx_webpage[] childPages = (FROM p in WebPages
                            WHERE p.adx_parentpageid != null &&
                                  p.adx_parentpageid.Id == page.Id
                            SELECT p).ToArray();
你的第一行

    WebPages = (FROM p in CrmContext.Adx_webpageSet WHERE p.Adx_HiddenFromSitemap != true SELECT p).ToArray();
将返回站点地图中未隐藏的所有页面。但这也包括没有父id的主页。因此,当第二个查询在此集合上枚举时,它将尝试访问此null属性并引发null引用异常。您只需要在查询中考虑到这一点

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

您是否懒得加载实体?如果子对象都为空,则可能需要加载它们。主页是否从站点地图中隐藏?p.adx_parentpageid.Id的数据类型是什么?我认为它实际上是p.adx_parentpageid,它是空的,并且它与您一起抛出,试图访问Id属性。如果p.adx_parentpageid可以为空,则需要为该条件编写代码。@JonC-我不知道什么是“延迟加载”。@saturdayplace抱歉,我没有添加更多信息。之前这里有一篇文章专门针对CRM 2011讨论这一点,好的,这很有意义。我只想访问数据库一次,这就是为什么我要进行第一次查询以获取数据库中的所有页面,然后再查询生成的数组;林克似乎对此很有意义。有更好的方法吗?Linq to Objects就可以了。您只需要记住,它只是在下面运行.net代码,并且不会像本机查询那样屏蔽空引用。如果一个对象没有关系,它不会被简单地排除,它会抛出一个空引用异常。