我开发了一个带插件的wpf主机应用程序并希望共享它们SqlConnection,但是当我尝试通过Remoting传递SqlConnection的对象时,我收到一个错误:
remoting cannot find field 'objectid' on type 'system.data.sqlclient.sqlconnection'
谷歌和SO没有帮助我,我找到的唯一主题是链接断开:(
我可以以某种方式传递SqlConnection吗?问题是我已经有了基于ado.net的应用程序,我没有可能重写它们。而另一方面,我需要提供不同的插件访问相同的连接,因为它们可以通过临时表互操作。
异常信息:
(last error: Remoting cannot find field 'ObjectID' on type 'System.Data.SqlClient.SqlConnection'.).
StackTrace:
Server stack trace:
at System.Object.GetFieldInfo(String typeName, String fieldName)
at System.Object.FieldGetter(String typeName, String fieldName, Object& val)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.Object.FieldGetter(String typeName, String fieldName, Object& val)
at System.Data.SqlClient.SqlCommand.set_Connection(SqlConnection value)
at LSSample.SampleUserControl.ExecuteSqlLocal() in c:\Users\voskresenskiy\Documents\Visual Studio 2013\Projects\UIContainer\WpfHost\LSSample\SampleUserControl.xaml.cs:line
我会感激任何帮助
答案 0 :(得分:2)
从异常调用堆栈和使用Reflector我可以看到SqlCommand.set_Connection
正在尝试访问SqlConnection.ObjectID
。 SqlConnection.ObjectID
被标记为内部,只有公共成员可通过远程处理获得。
不是SqlConnection
使用池来最小化数据库连接的数量吗? SQL Server Connection Pooling
你是否有一个与数据库对话的进程,然后所有其他进程都会从中请求数据,只需将查询字符串传递给它?
答案 1 :(得分:1)
我们最近遇到了同样的问题,我认为问题是通过调用它的构造函数在本地创建SqlCommand
。然后,当它为它分配连接时,它会尝试在本地克隆连接,但由于某些内部属性无法通过远程处理,它会失败。
为我们提供技巧的解决方法是在连接上调用CreateCommand()
,如此
void MethodRunningInAppDomainB(SqlConnection connectionFromAppDomainA, SqlTransaction transactionFromAppDomainA)
{
using (var cmd = connectionFromAppDomainA.CreateCommand())
{
cmd.CommandText = "this is my query";
cmd.Transaction = transaction;
cmd.Parameters.Add(...);
...
cmd.ExecuteNonQuery();
}
}
基本上,连接和事务来自主app,它传递给在不同的AppDomain中运行的插件(因此可以卸载),它可以在主查询的上下文中执行一些自定义命令。
我怀疑是在连接上调用CreateCommand()
会重新启动回调并在连接所在的同一app域中创建命令,并且您获取的创建命令可能是代理,这就是为什么这种方式有效。
不确定我对问题的解释是否100%正确但对我来说听起来有点合乎逻辑,无论如何它为我们解决了问题。