Linq 内部的 Linq 导致序列不返回结果
这是我的类:
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/XDetail 以进行适当的更改或添加新记录。 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
};
这样我就可以获得我正在寻找的结果,形成新的匿名类型,但是当我尝试添加 Result = ... 内部 linq 查询时,我的整个set 变为:序列不包含元素。如果我删除它,我会得到我想要的结果集。 X/XDetail 实际上是类型化的 DataRows,我需要在使用匹配的 Result 进行进一步处理时使用它们,但如果没有该 Result,我将需要执行稍后的 linq 查询来查找匹配项。我希望以一种伪酷的一步法来做到这一点。
我尝试将 Result 更改为没有 where 子句,并且可以获得结果,但我希望结果能够匹配。有没有更好的方法来编写这个或让结果集再次工作的方法?
Here are my classes:
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; }
}
The ID is shared between them to link X and XDetail (one to many relationship). I read in a file using the following linq query and shape an anonymous type:
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()
};
This data is used to check against existing X/XDetail to make appropriate changes or add new records. XList is a List and XDetailList is a List.
From there I attempt a fancy linq query to match up the appropriate items:
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
};
So I can get the results I'm looking for shaped into that new anonymous type, but when I tried adding in that Result = ... inner linq query my whole set turns to: Sequence contains no elements. If I remove it I get the result set I was intending. X/XDetail are really typed DataRows that I need to use in processing farther down using the matched Result, but without that Result I will need to do a later linq query to find the match. I was hoping to do it in a psuedo-cool one step way.
I have tried changing Result to have no where clause and I can get a result, but the result I'm hoping to match on. Is there a better way to write this or a way to get the result set working again?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个问题是结果是一个
IEnumerable
- 所以你每次都重新查询它,这会导致File.ReadAllLines(file)
执行 - 实际上你正在调用File.ReadAllLines(file)
N
次,这听起来不太健康。相反,您希望将此枚举放入内存一次 - 使用
ToList()
强制急切执行:One problem is that results is an
IEnumerable
- so you are re-querying it every time which causes theFile.ReadAllLines(file)
to execute - effectively you are callingFile.ReadAllLines(file)
N
times which does not sound healthy.Instead you want to bring this enumeration into memory once - force eager execution with
ToList()
:尝试将 .Single 更改为 .SingleOrDefault。您可能会发现给定的 x.Detail.Name 不在结果集中的行。
(从评论转移到答案,以便可以对其进行适当标记)
Try changing your .Single to .SingleOrDefault. It is possible you are finding a row where the given x.Detail.Name isn't in your results set.
(Moving from a comment to answer so that it can be marked appropriately)