Entity Framework枚举SqlQuery结果

19

当我尝试查看SqlQuery的结果时,出现了奇怪的错误:

var sql = "SELECT @someParam";
var someParamSqlParameter = new SqlParameter("someParam", "Some Value");
var result = _dbContext.SqlQuery<string>(sql, someParamSqlParameter);
var containsAnyElements = result.Any();

当调试器执行到最后一行时,我尝试展开result的结果视图,它显示了期望的result("Some Value"),但在调用最后一行时,却抛出了异常。

"The SqlParameter is already contained by another SqlParameterCollection.".

似乎当我尝试打开result的结果视图时,它会再次调用此查询。如果这种行为是正确的,请解释一下为什么会发生这种情况。

1个回答

35

看起来当我尝试打开结果视图时,它会再次调用此查询

你说得很对 - 你正在看到延迟执行的影响。

Database.SqlQuery<T>返回一个IEnumerable<T>对象,实际上是一种类型:

System.Data.Entity.Internal.InternalSqlQuery<T>

所以你的result对象实际上只是查询的描述信息,而不是查询结果。
只有当您尝试查看查询结果时,SQL查询才会在数据库上实际执行。
你看到的情况是发生了两次:一次是当你的代码调用.Any(),另一次是调试器枚举结果集时。
你可以通过使用.ToList()显式地告诉EF何时运行查询来解决这个问题:
var result = _dbContext.SqlQuery<string>(sql, someParamSqlParameter).ToList();
result 的类型现在是 List<string>,其中包含您的查询结果。

非常好的解释。非常感谢您如此快速和清晰的回答。 - Vladimirs
太好了,伙计。我都快疯了,其他关于同一主题的答案都没有任何帮助。 - alessalessio
2
我真的想不出这个问题是如何导致报告的错误消息的。 - Jonathan Wood
严肃地说...我刚刚花了6个小时...结果答案就是使用.ToList()??太棒了! - Fred

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接