(LINQ to SQL):foreach调用GetEnumerator()方法所产生的疑惑
刚接触LINQ,故而在学习过程中,产生了些许疑惑,希望能得到探讨....
大家知道,linq查询表达式,只是一种表达式的描述,真正执行查询的是通过foreach循环,来调用GetEnumerator()方法,执行linq查询表达式,所以这也就产生了LINQ的延迟执行问题,先看下面两个例子:
示例一:
IQueryable<Category> result = from c in db.Categorys
where c.Name.Length > 1
select c;
foreach (Category item in result)
{
Debug.WriteLine(item.Name);
}
Debug.WriteLine("-------------------");
foreach (Category item in result)
{
Debug.WriteLine(item.Name);
}
上代码中,是对单一表Categorys进行查询操作,取出其Name属性长度大于1的结果来,使用了两个foreach循环,在其两个foreach之间插入一个断点,运行后,程序被断在断点处,此时,已执行了第一个foreach循环,得出数据"FISH",然后直接修改数据库表,将"FISH"修改为"SMALLFISH",修改成功后,继续运行代码,如果每个foreach循环都调用一次GetEnumerator(),那么第二个foreach也会调用,也就是说对数据库执行第二次查询操作,所以第二个foreach执行结果应该为数据库表修改后的"SMALLFISH"才正确,可示例结果依然为"FISH",也就是说第二个foreach并未真正进行重新查询,而好像是从第一个foreach查询缓存中直接取出数据,所以才造成这个结果.
示例二:
IQueryable<Product> result =
(from c in db.Categorys
where c.CategoryId == "FISH"
from p in c.Products
select p);
foreach (Product item in result)
{
Debug.WriteLine(item.ProductId);
}
Debug.WriteLine("-----------------");
foreach (Product item in result)
{
Debug.WriteLine(item.ProductId);
}
示例二,同示例一类似,唯一不同的是,进行了多表操作,也就是将表Category 和 Product表通过"CategoryId"进行关联,查询出,Product中,CategoryId为"FISH"的产品信息出来.在运行代码时,和示例的操作完全相同,也在两个foreach间插入断点,在执行完第一个foreach后,直接修改数据库表,然后再接着执行第二个foreach操作,然后两次foreach出来的结果不同,换句话说,第二个foreach查询出来的是数据库表修改后的结果,也就是说第二个foreach还是重新调用了一次GetEnumerator()方法,所以取出的结果是修改后的结果.
问题:LINQ TO SQL 是通过foreach调用GetEnumerator()方法来执行LINQ查询表达式的,所以,按道理,示例中,不管操作一个表还是多个表,每个foreach均需要调用GetEnumerator()方法来执行查询,从而得出的结果应该是不同的,可现在出现的情况是,操作单一表,第二个foreach并未重新执行查询,操作多表时,第二个foreach才会重新执行查询,请问各位朋友,这个问题该如何来解释??小弟万谢~~~