我需要对一堆文件进行循环,并通过LINQ查询吐出日志条目:
foreach (string file in Directory.EnumerateFiles(TextBoxLogDirectory.Text, "*.log"))
{
FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
using (LogReader reader = new LogReader(stream))
{
var events = (from x in reader.Parse().Where(y => y.IsInRange(range) && (y.EventNo == 1180 || y.EventNo == 1187) && y.GetDefaultMessageField().Contains(":Outbound/"))
group x by x.GetDefaultMessageField() into grouping
select new
{
ID = grouping.Key,
Event1180 = grouping.LastOrDefault(z => z.EventNo == 1180),
Event1187 = grouping.LastOrDefault(z => z.EventNo == 1187)
}).ToList();
}
}
此查询必须一次在单个文件上运行,并且上述工作正常,但我需要继续将查询结果附加到foreach
循环之外的对象。这样的事情(虽然不幸的是,这并不起作用):
dynamic events; // I want to append to this object outside of the loop's scope.
foreach (string file in Directory.EnumerateFiles(TextBoxLogDirectory.Text, "*.log"))
{
FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
using (LogReader reader = new LogReader(stream))
{
events = (from x in reader.Parse().Where(y => y.IsInRange(range) && (y.EventNo == 1180 || y.EventNo == 1187) && y.GetDefaultMessageField().Contains(":Outbound/"))
group x by x.GetDefaultMessageField() into grouping
select new
{
ID = grouping.Key,
Event1180 = grouping.LastOrDefault(z => z.EventNo == 1180),
Event1187 = grouping.LastOrDefault(z => z.EventNo == 1187)
}).ToList().Concat(events);
}
}
我怎样才能实现这种行为?
不确定是否有帮助,我上面的查询将返回(string)ID, (LogEvent)Event1180, and (LogEvent)Event1187.
答案 0 :(得分:2)
您可以尝试这样的事情:
Directory.EnumerateFiles(TextBoxLogDirectory.Text, "*.log")
.SelectMany(ParseFile);
其中ParseFile
定义为
IEnumerable<string> ParseFile(string file)
{
using (FileStream stream =
new FileStream(file, FileMode.Open, FileAccess.Read,
FileShare.ReadWrite | FileShare.Delete))
using (LogReader reader = new LogReader(stream))
{
return (from x in reader.Parse()
.Where(y => y.IsInRange(range) &&
(y.EventNo == 1180 || y.EventNo == 1187) &&
y.GetDefaultMessageField().Contains(":Outbound/"))
group x by x.GetDefaultMessageField() into grouping
select new
{
ID = grouping.Key,
Event1180 = grouping.LastOrDefault(z => z.EventNo == 1180),
Event1187 = grouping.LastOrDefault(z => z.EventNo == 1187)
}).ToList();
}
}
如果您愿意,也可以内联辅助函数。
这会生成一个IEnumerable<string>
,您可能应该立即使用ToList
来实现。{/ p>
编辑:哦,我知道,我们的类型不匹配。
有两种解决方法:要么命名匿名类型并使函数返回IEnumerable<that type>
,要么将函数内容内联到lambda中:
Directory.EnumerateFiles(TextBoxLogDirectory.Text, "*.log")
.SelectMany(file =>
{
using (FileStream stream =
new FileStream(file, FileMode.Open, FileAccess.Read,
FileShare.ReadWrite | FileShare.Delete))
using (LogReader reader = new LogReader(stream))
{
return (from x in reader.Parse()
// ...
}).ToList();
}
}
);