c#-在System.Data.Entity.Database上第二次调用ExecuteSqlCommand时出错
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c#-在System.Data.Entity.Database上第二次调用ExecuteSqlCommand时出错,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3070字,纯文字阅读大概需要5分钟。
内容图文
![c#-在System.Data.Entity.Database上第二次调用ExecuteSqlCommand时出错](/upload/InfoBanner/zyjiaocheng/881/0f6c6f9951554cacade3f02717e601e6.jpg)
我使用的是EF5代码优先,因此我有一个DbContext,它的Database属性的类型为System.Data.Entity.Database.
我发现的问题是,当使用相同的参数多次调用相同的SP时,它会引发异常消息:“该SqlParameter已被另一个SqlParameterCollection包含”.
这可以用下面的代码演示.首先创建一个DbContext派生并将其连接到数据库.代码中的存储过程不必存在.对SP的第一次调用将错误地指出SP不存在,但是,第二个例外是我们感兴趣的那个.
var pa = new SqlParameter[]
{
new SqlParameter("@Name", SqlDbType.NVarChar) { Value = "test" }
};
var dc = new MyWebContext(); // derived from DbContext
try
{
dc.Database.ExecuteSqlCommand("spImport @Name", pa);
}
catch { }
dc.Database.ExecuteSqlCommand("spImport @Name", pa); // fails with "The SqlParameter is already contained by another SqlParameterCollection"
我确实有时需要两次或多次调用具有相同参数的同一SP.这是一个有效的要求.我的假设是,调用ExecuteSqlCommand是非常短暂的,应该可以在同一上下文中多次执行.
似乎上下文挂在第一个调用的参数信息上,从而导致第二个问题.
这是堆栈跟踪:
at System.Data.SqlClient.SqlParameterCollection.Validate(Int32 index, Object value)
at System.Data.SqlClient.SqlParameterCollection.AddRange(Array values)
at System.Data.Objects.ObjectContext.CreateStoreCommand(String commandText, Object[] parameters)
at System.Data.Objects.ObjectContext.ExecuteStoreCommand(String commandText, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlCommand(String sql, Object[] parameters)
at System.Data.Entity.Database.ExecuteSqlCommand(String sql, Object[] parameters)
at EF5ExecuteSqlCommandBugReproduction.Program.Main(String[] args) in c:\EF5ExecuteSqlCommandBugReproduction\EF5ExecuteSqlCommandBugReproduction\Program.cs:line 26
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
我将不胜感激.如果您认为这是EF的错误,那么我将向您报告.
非常感谢
解:
将参数列表创建和ExecuteSqlCommand打包到一个内联函数中,然后重新调用它,而不是重新调用ExecuteSqlCommand.这将确保创建新的SqlParameter数组.
var dc = new SpondleWebContext(); //衍生自DbContext
Action act = () =>
{
var pa = new SqlParameter[] { new SqlParameter("@Name", SqlDbType.NVarChar) { Value = "test" } };
dc.Database.ExecuteSqlCommand("spImport @Name", pa);
};
try { act(); } catch { }
act();
解决方法:
我没有在这里安装EntityFramework,但是我非常确定ExecuteStoreCommand方法每次都会创建一个新的DbCommand对象.您要传递的参数集合不在框架内创建,而是由多个命令重用.因此,您会收到错误.
您将必须在第二次调用之前克隆参数.
内容总结
以上是互联网集市为您收集整理的c#-在System.Data.Entity.Database上第二次调用ExecuteSqlCommand时出错全部内容,希望文章能够帮你解决c#-在System.Data.Entity.Database上第二次调用ExecuteSqlCommand时出错所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。