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

Posted

技术标签:

【中文标题】需要知道使用 AsEnumerable 的这段代码的工作原理【英文标题】:Need to know the working of this code which uses AsEnumerable 【发布时间】:2014-04-11 20:24:45 【问题描述】:

当我运行这段代码时:

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

它给了我一个错误:

SqlParameter 已经在 SqlParameterCollection 中

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

谁能解释一下 AsEnumerable 和这段代码的工作原理吗?

【问题讨论】:

ExecuteDataTable返回的数据类型是什么? @ScottChamberlain 返回了一个数据表 检查此解决方案是否对您有帮助。 ***.com/q/6289607/1733852 你给我们看的代码不应该抛出那个错误,你确定这个错误没有在ExecuteDataTable内部发生吗? 【参考方案1】:

相当于你的代码如下

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);。尝试像上面那样重写你的代码,看看你的错误发生在哪一行,也许它会给你下一步的方向。

【讨论】:

【参考方案2】:

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

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

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

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

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

【讨论】:

他没有IQueryable 他有DataTable,他呼叫的AsEnumerable() 是this version 不是this version

以上是关于需要知道使用 AsEnumerable 的这段代码的工作原理的主要内容,如果未能解决你的问题,请参考以下文章

python的这段代码怎么运行

我是不是误解了 LINQ to SQL .AsEnumerable()?

我是不是误解了 LINQ to SQL .AsEnumerable()?

为啥使用类变量的这段代码不能像在 Java 中那样工作? [复制]

如何解决随机行走问题中的这段代码?[关闭]

为啥数组中的这段代码不合适?