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
C# 调试复杂的linq查询_C#_Linq_Debugging_Visual Studio 2013 - Fatal编程技术网

C# 调试复杂的linq查询

C# 调试复杂的linq查询,c#,linq,debugging,visual-studio-2013,C#,Linq,Debugging,Visual Studio 2013,我正在处理一个复杂的linq查询,如下所示,它在运行时引发System.NullReferenceException。不幸的是,visual studio没有提供任何其他信息,我无法对值执行QuickWatch,以检查哪个值为空。有没有一种方法可以调试这种查询,这样我就可以看到哪里出了问题 var dataSource = (from c in session.Query<PortChannel>() select new PortChanne

我正在处理一个复杂的
linq
查询,如下所示,它在运行时引发
System.NullReferenceException
。不幸的是,visual studio没有提供任何其他信息,我无法对值执行
QuickWatch
,以检查哪个值为空。有没有一种方法可以调试这种查询,这样我就可以看到哪里出了问题

var dataSource = (from c in session.Query<PortChannel>()
        select
            new PortChannelData
            {
                Location = c.Port.MagazineSlot.SiteMagazine.Site.SiteName,
                MagazineName =
                    String.Format("{0}-{1}", c.Port.MagazineSlot.SiteMagazine.MagazineType.MagazineName,
                        c.Port.MagazineSlot.SiteMagazine.MagazineNo),
                SlotNo = c.Port.MagazineSlot.SlotNo,
                PortNo = c.Port.PortNo,
                Klm = c.Klm,
                StmNo = c.StmNo,
                Label = c.SiteName == null ? null : String.Format("{0}_{1}", c.SiteName, c.E1No),
                ChannelFullName = c.ChannelFullName,
                BscRncPort = c.BscRncPort,
                MgwPort = c.MgwPort,
                ReservedBy = c.ReservedBy,
                CrossFullName = c.CrossConnection == null ? null : c.CrossConnection.ChannelFullName
            }).ToList();
}
var dataSource=(来自session.Query()中的c)
选择
新PortChannelData
{
位置=c.Port.MagazineSlot.SiteMagazine.Site.SiteName,
马加齐尼奈=
String.Format(“{0}-{1}”),c.Port.MagazineSlot.SiteMagazine.MagazineType.MagazineName,
c、 Port.MagazineSlot.SiteMagazine.MagazineNo),
SlotNo=c.Port.MagazineSlot.SlotNo,
端口号=c.Port.PortNo,
Klm=c.Klm,
StmNo=c.StmNo,
Label=c.SiteName==null?null:String.Format(“{0}{1}”,c.SiteName,c.E1No),
ChannelFullName=c.ChannelFullName,
BscRncPort=c.BscRncPort,
MgwPort=c.MgwPort,
ReservedBy=c.ReservedBy,
CrossFullName=c.CrossConnection==null?null:c.CrossConnection.ChannelFullName
}).ToList();
}

我以前也遇到过同样的问题,下面的技术对我帮助很大

我已将提取的值定义为我的
select
表达式中的属性,在执行
new ObjectName()
提取语句之前,这样,当发生错误时,visual studio会将我指向导致空引用的特定部分

考虑以下示例:

var returnNews = reportResult.Select(n =>
            {
                var createdBy = allUsersInfoForReport.FirstOrDefault(u => u.ID == n.CreatedBy);
                var publishedBy = allUsersInfoForReport.FirstOrDefault(u => u.ID == n.Publishedby);
                var modifiedBy = allUsersInfoForReport.FirstOrDefault(u => u.ID == n.LastModifiedBy);

                newsViewCountEntity = newsViewCountCollection.FirstOrDefault(nv => nv.News_ID == n.ID);
                newsCommentsCount = newsCommentsCollection.Count(s => s == n.ID);

                return new ReportItemViewModel()
                {
                    ID = n.ID,

                    AddedBy = createdBy != null ? createdBy.UserName : "",
                    UserSectionName = createdBy != null ? createdBy.RelatedSectionName : "",
                    PublishedBy = publishedBy != null ? publishedBy.UserName : "",
                    LastModifiedBy = modifiedBy != null ? modifiedBy.UserName : "",
                }
});
在此示例中,如果以下任一属性(
createdBy
-
publishedBy
-
modifiedBy
)未能获取有效值,则会引发异常,但会正确高亮显示该行,而不是高亮显示整个LINQ表达式


尝试使用相同的技术,并让我知道结果。

您可以在
新PortChannelData
行上放置一个断点,并像往常一样进行调试(每次执行select语句时,即针对
会话.Query()中的每个元素,都会命中断点)

如果将
select
newportchanneldata
放在同一行上,则设置断点将在Linq查询的开始处设置断点。该断点仅在执行查询之前命中一次,并且不允许您“跳入”查询。但是,您可以在Visual Studio中更改断点的位置,方法是右键单击边沟中的红色断点点并选择“位置…”。将位置设置为
newportchanneldata
的起始行和字符,断点将放在select语句中


您还可以向断点添加条件,使其仅在满足条件时激活。如果
session.Query()
返回大量端口通道,则检查正在访问的任何属性或字段是否为空的条件可以节省一些时间。

在查询中,可以使用
let
关键字存储子表达式的结果。然后在创建新的
PortChannelData
对象时分配结果

var dataSource = 
    (from c in session.Query<PortChannel>()
        let flName = c.CrossConnection == null ? null : c.CrossConnection.ChannelFullName
        let magName = String.Format("{0}-{1}", c.Port.MagazineSlot.SiteMagazine.MagazineType.MagazineName,
                    c.Port.MagazineSlot.SiteMagazine.MagazineNo)
        // and so on
        select new PortChannelData
        {
            MagazineName = magName,
            CrossFullName = flName,
            // ...
        }).ToList();
var数据源=
(来自session.Query()中的c)
让flName=c.CrossConnection==null?null:c.CrossConnection.ChannelFullName
让magName=String.Format(“{0}-{1}”),c.Port.MagazineSlot.SiteMagazine.MagazineType.MagazineName,
c、 Port.MagazineSlot.SiteMagazine.MagazineNo)
//等等
选择新端口通道数据
{
MagazineName=magName,
CrossFullName=flName,
// ...
}).ToList();

这样,当您调试并进入查询(
F11
是标准的Visual Studio快捷方式)时,您将看到每个子表达式的结果。

您尝试过吗?@Luca Nope我将查看它,谢谢!这个LINQ查询几乎没有什么复杂之处请注意在查询结束时的.ToList()调用-这会覆盖延迟执行,允许您单步执行代码(有关更多信息,请参阅:),因此即使在复杂的LINQ查询中也常常忘记F11