当对数据源执行一组 LINQ 查询时(我使用的是 LINQ-to-SQL,但这里也只使用List<string>
对象),我最终在检查结束时得到了不同的结果。
具体来说,下面的代码试图查找主机名列表中是否存在完全限定域名 (FQDN)(并非所有主机名都是 FQDN 或位于同一域中,但主机标识符对我来说很重要) 。搜索试图找出是否"host-6.domain.local"
或其任何子组件存在(即"host-6.domain"
or "host-6"
)在列表中,但他们没有。在 for 循环内,我们得到了预期的结果,但是一旦 for 循环完成,我得到的结果是all列表的内容,对我来说,这听起来像是试图找到与空字符串匹配的元素。
void MyMethod()
{
string fqdn = "host-6.domain.local";
string[] splitFqdn = fqdn.Split('.');
List<string> values = new List<string>();
values.add("host-1");
values.add("host-2.domain.local");
values.add("host-3.domain.local");
values.add("host-4");
values.add("host-5.other.local");
IEnumerable<string> queryResult = null;
for (int i = splitFqdn.Length; i > 0; i--)
{
result =
from value in values
where value.StartsWith(
string.Join(".", splitFqdn.Take(i)))
select value;
Console.WriteLine(
"Inside for loop, take " + i + ": " + result.Count());
}
Console.WriteLine();
Console.WriteLine(
"Outside for loop: " + result.Count());
}
为什么会发生这种情况?如何获得在 for 循环完成后仍然可以访问的准确结果?
您被 LINQ 的惰性执行和关闭所困扰。
当您像在这里所做的那样创建一个枚举时......
result =
from value in values
where value.StartsWith(
string.Join(".", splitFqdn.Take(i)))
select value;
直到你做了一些强制它被评估的事情,它才会被评估......例如当你这样做时result.count()
然后当您再次评估它时在循环之外result.count()
使用 for 循环中存在的 i 的最后一个值进行评估,该值没有给你你想要的。
尝试通过执行强制评估.ToList()
像这样在你的枚举上...此代码显示了两个值,以便你可以进行比较。
void MyMethod()
{
string fqdn = "host-6.domain.local";
string[] splitFqdn = fqdn.Split('.');
List<string> values = new List<string>();
values.add("host-1");
values.add("host-2.domain.local");
values.add("host-3.domain.local");
values.add("host-4");
values.add("host-5.other.local");
IEnumerable<string> queryResult = null;
List<string> correctResult = null;
for (int i = splitFqdn.Length; i > 0; i--)
{
queryResult =
from value in values
where value.StartsWith(
string.Join(".", splitFqdn.Take(i)))
select value;
correctResult = queryResult.ToList();
Console.WriteLine(
"Inside for loop, take " + i + ": " + queryResult.Count());
}
Console.WriteLine();
Console.WriteLine(
"Outside for loop queryResult: " + queryResult.Count());
Console.WriteLine(
"Outside for loop correctResult: " + correctResult.Count());
}
编辑:谢谢nlips指出我没有完全回答这个问题...并对转换为方法语法表示歉意,但转换为查询语法需要更长的时间。
void MyMethod()
{
string fqdn = "host-6.domain.local";
string[] splitFqdn = fqdn.Split('.');
List<string> values = new List<string>();
values.Add("host-1");
values.Add("host-2.domain.local");
values.Add("host-3.domain.local");
values.Add("host-4");
values.Add("host-5.other.local");
values.Add("host-5.other.local");
IEnumerable<string> queryResult = null;
List<string> correctResult = new List<string>();
for (int i = splitFqdn.Length; i > 0; i--)
{
correctResult = correctResult
.Union(values.Where(
value => value.StartsWith(string.Join(".", splitFqdn.Take(i)))))
.ToList();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)