为什么C#EXE可以访问SQL Server数据源但DLL被阻止?

时间:2020-02-19 09:58:05

标签: c# sql-server data-binding

TL; DR

使用数据绑定到数据源的C#DLL中的

WinForms似乎被阻止访问SQL Server数据库,但是原始SQL查询仍然有效。我在做什么错了?


详细的问题描述

我们有一个C#WinForms .Net Framework 4应用程序,其中包括: -EXE工程 -DLL项目,由EXE调用

应用程序访问SQL Server数据库。

EXE和DLL都包含一些使用Visual Studio设计器创建的Windows窗体。为了在表单控件中显示数据,这些控件是通过“数据源”面板中的拖放操作添加到表单中的。也就是说,数据访问通过以XSD文件存储(在Visual Studio项目中)的数据集。

在开发机器上,一切正常,我们可以打开各种表格并查看数据。 但是在同时安装和运行SQL Server的测试系统上,只有EXE中的表单才能访问数据库。如果从DLL中打开表单,则会使应用程序挂起几秒钟,然后出现错误:

System.Data.SqlClient.SqlException(0x80131904):无法打开登录请求的数据库“ MyDatabaseName”。登录失败。 用户'\'登录失败。

在通话中:

System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling, SqlAuthenticationProviderManager sqlAuthProviderManager)

app.config中的连接字符串正确,并且应用程序已经连接到数据库,因为原始SQL查询/更新工作正常。

奇怪的是,如果我进入VS并重新创建数据源(使用向导),而是在测试机而不是开发机上使用数据库,然后重新编译,那么一切都可以在测试机上正常工作。感觉好像连接字符串中的参数几乎被“编译”到DLL中的某个位置,但是到目前为止,我仍无法弄清出什么问题了。

我们正在使用SQL Server 2016和Visual Studio2013。该应用程序是针对.Net 4.0编译的。

正在使用的连接字符串:

Data Source=192.168.0.1;Initial Catalog=MyDatabaseName;Integrated Security=True

也尝试过:

Data Source=.\SQLEXPRESS;Initial Catalog=MyDatabaseName;Integrated Security=True

对冗长的解释表示抱歉(感谢您阅读本文!),但确实有些奇怪。有人知道这是怎么回事吗?预先感谢您的任何提示!

1 个答案:

答案 0 :(得分:0)

好的,我终于可以使用它了,这个链接特别有用:

http://jstawski.com/post/2007/01/24/connectionstring-on-a-dataset-datatable-with-dataadapter

在我的项目中,我更改了连接字符串。而不是将(localdb)用作我的服务器,而是输入了另一台配置了SQL Server的计算机的IP(IP 192.168.0.224)。我能够继续在IDE中调试程序。

当我将应用程序部署到另一台计算机(IP 192.168.0.35)时,所有原始SQL查询都在数据库中为Nr 35工作。但是,涉及XSD数据集的任何内容都会更改另一台PC(192.168.0.224)上的数据我在app.config中的连接字符串设置为192.168.0.35!

当使用VS向导为项目创建数据集时,在向导开始时会要求您提供连接字符串。尽管当项目是EXE时一切正常,但如果您正在编译DLL(如我所愿),则似乎此连接字符串(如开发PC上所示)已以某种方式硬编码到DLL中。

解决方案

DLL项目有一个设置文件,可以在其中设置连接字符串。解决方案是通过覆盖此设置来欺骗VS。

我的原始文件:

    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

        public static Settings Default {
            get {
                return defaultInstance;
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=192.168.0.224;Initial Catalog=My_Database_Development;Integrated" +
            " Security=True")]
        public string MyDatabaseConnectionString {
            get {
                return ((string)(this["MyDatabaseConnectionString"]));
            }
        }
    } 

更改的部分如下:

       public string MyDatabaseConnectionString {
            get {
                //return ((string)(this["MyDatabaseConnectionString"])); // <-- this is the cause of the trouble!
                return getConnectionString();
            }
        }

        private string getConnectionString()
        {
            // This is a method I wrote elsewhere in my program which always queries the app.config file
            return ConnectionStringUtility.GetConnectionString();
        }

注意:我的程序中有一个实用程序类,其中包含一个返回连接字符串的方法,因此我可以在Settings.Designer.cs

中在此处调用我的实用程序类。

摘要

这是一种非常奇怪的情况,仅在将包含DataSet(XSD)的C#项目编译为DLL时发生。

解决方案是覆盖调用以在Settings.designer.cs中获取连接字符串

相关问题