需要知道使用AsEnumerable的这段代码的工作原理

时间:2014-03-08 15:35:17

标签: c# ienumerable enumeration enumerable

当我运行此代码时:

return dbAccess.ExecuteDataTable(dbAccess)
               .AsEnumerable()
               .Select(r => r.Field<int>("Id"))
               .ToList();                       

它给了我一个错误:

  

SqlParameter已经在SqlParameterCollection

虽然我知道AsEnumerable可以在延迟执行或延迟加载这个概念上运行,但是这个概念仍然没有在我脑海中占据一席之地。

任何人都可以解释一下AsEnumerable和这段代码的工作原理吗?

2 个答案:

答案 0 :(得分:0)

您的代码等效于以下

var retVal = new List<int>();
var dataTable = dbAccess.ExecuteDataTable(dbAccess);
foreach(DataRow r in dataTable.Rows)
{
    var rowResult = (int)r["Id"]; //`(int)r["Id"]` is equivalent to `r.Field<int>("Id")`
    retVal.Add(rowResult);
}
return retVal;

您不必担心代码的执行不同,因为您在最后放置.ToList(),因此它会在您向我们展示的位置运行代码。如果你把它排除在外,那么在不使用yield return的情况下显示“等效代码”会更加困难,而这可能让你更加困惑。

上面说的是,上面代码中唯一可以抛出我看到的错误的是dbAccess.ExecuteDataTable(dbAccess);。尝试重写上面的代码,看看你的错误发生在哪一行,也许它会给你指明下一步的方向。

答案 1 :(得分:0)

  

AsEnumerable只是将对象强制转换为IEnumerable(来自   IQeuriable),这意味着您将使用的任何LINQ运算符   为该接口声明的运算符(IEnumerable)。

     

这意味着不要将运算符转换为SQL,而是让它   服务器处理它,整个表将枚举(从中检索)   DB),然后在内存中进行操作。

正如@Scott Chamberlain所提到的,我所回答的内容与您的代码无关,因为它使用的是DataTable,而不是IQueriableAsEnumerable只为DataTable创建可枚举的包装器,一次检索每一行,并允许您在DataTable上使用LINQ。这与例外无关。

另一件事,调用ToList强制执行查询,因此不会延迟执行。

要回答关于异常的问题,如果您提供向查询添加参数的代码,将会很有帮助。