C# Linq中的Linq导致序列不返回结果
以下是我的课程:C# Linq中的Linq导致序列不返回结果,c#,linq,linq-to-objects,C#,Linq,Linq To Objects,以下是我的课程: public class XDetail { public string Name { get; set; } public int ID { get; set; } } public class X { public int XID { get; set; } public int ID { get; set; } } ID在它们之间共享,以链接X和XDetail(一对多关系)。我使用以下linq查询读入一个文件,并形成一个匿名类型: va
public class XDetail
{
public string Name { get; set; }
public int ID { get; set; }
}
public class X
{
public int XID { get; set; }
public int ID { get; set; }
}
ID在它们之间共享,以链接X和XDetail(一对多关系)。我使用以下linq查询读入一个文件,并形成一个匿名类型:
var results = from line in File.ReadAllLines(file)
select new
{
XID = int.Parse(line.Substring(0, 8).TrimStart('0')),
Name = line.Substring(8, 255).Trim()
};
此数据用于对照现有的X/X详细信息进行检查,以进行适当的更改或添加新记录。XList是一个列表,XDetailList是一个列表
从这里,我尝试使用一个奇特的linq查询来匹配适当的项:
var changedData = from x in XList
join xDetail in XDetailList on x.ID equals xDetail.ID
where
(!results.Any(p => p.XID.Equals(x.XID))
|| !results.Any(p => p.Name.Equals(xDetail.Name)))
select new
{
XValue = x,
XDetailValue = xDetail,
Result = (from result in results
where result.Name.Equals(xDetail.Name)
select result).Single() // This line is my bane
};
因此,我可以得到我正在寻找的结果,并将其转化为新的匿名类型,但当我尝试添加该结果=。。。内部linq查询我的整个集合变成:序列不包含任何元素。如果我删除它,我会得到我想要的结果集。X/XDetail实际上是类型化的数据行,我需要使用匹配的结果进一步处理这些数据行,但是如果没有这个结果,我需要稍后执行linq查询来查找匹配项。我希望用一种很酷的一步式方法来做
我试图改变结果,使其没有where子句,我可以得到一个结果,但我希望这个结果能与之匹配。是否有更好的方法编写此文件或使结果集再次工作?一个问题是,结果是一个
IEnumerable
-因此每次都要重新查询它,从而导致执行文件.ReadAllLines(File)
-实际上是调用文件.ReadAllLines(File)
N
听起来不健康的次数
相反,您希望将此枚举一次性放入内存-使用ToList()
强制执行:
尝试将.Single更改为.SingleOrDefault。您可能正在查找一行,其中给定的x.Detail.Name不在结果集中
(从注释移动到答案,以便适当标记)这里的
结果是什么?它的类型是什么?结果是第一个查询中的匿名类型,我正在解析该文件的XID和名称。我不明白你说的是xDetail中的xDetail,xDetail
是一个类,不是一个填充了任何数据的对象吗?你是怎么做到的?(我只是在问。)@AteşGÜRAL是的,我似乎很快就把它忘了,现在看起来应该好一点了。我觉得在list中加一行是一个的列表很有意思,但是这很有帮助。在这种情况下调用.Equals而不是仅仅使用==运算符有什么好处吗?使用==对我来说更具可读性。当文件没有行时,这仍然会崩溃
var results = (from line in File.ReadAllLines(file)
select new
{
XID = int.Parse(line.Substring(0, 8).TrimStart('0')),
Name = line.Substring(8, 255).Trim()
}).ToList();