Почему C# EXE-доступ SQL Источник данных сервера, но DLL заблокирована? - PullRequest
1 голос
/ 19 февраля 2020

TL; DR

WinForms в C# DLL с использованием привязки данных к источнику данных, по-видимому, заблокированы для доступа к базе данных SQL Server, но необработанные запросы SQL Работа. Что я делаю не так?


Подробное описание проблемы

У нас есть C# WinForms. Net Приложение Framework 4, состоящее из: - EXE Проект - проект DLL, вызываемый EXE

Приложение обращается к SQL базе данных сервера.

В EXE и DLL содержатся несколько Windows форм, созданных с помощью конструктора Visual Studio , Для отображения данных в элементах управления формы элементы управления были добавлены в форму путем перетаскивания с панели «Источники данных». т. е. доступ к данным осуществляется через набор данных, сохраненный (в проекте Visual Studio) в виде файла XSD.

На компьютере разработчика все работает нормально, и мы можем открывать различные формы и просматривать данные. Но в тестовой системе, где SQL Сервер также установлен и работает, только формы в 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 верна, и приложение уже подключено к БД, поскольку raw SQL запросы / обновления работают нормально.

Странно то, что если я go в VS и воссоздаю источник данных (с помощью мастера) и вместо этого использую базу данных на тестовой машине вместо машины разработки , а затем перекомпилируйте, затем все работает на тестовой машине. Такое ощущение, что параметры в строке подключения где-то «скомпилированы» в DLL, но пока я не могу понять, что не так.

Мы используем SQL Server 2016 и Visual Studio 2013. Приложение скомпилировано для. 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 голосов
/ 24 февраля 2020

ОК, наконец-то я получил это на работу, и эта ссылка была особенно полезна:

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

В своих проектах я изменил строку подключения , Вместо (localdb) в качестве моего сервера я ввел IP-адрес другого компьютера (IP 192.168.0.224), на котором настроен SQL Сервер. Я смог продолжить отладку своей программы в IDE.

Когда я развернул свое приложение на другом компьютере (IP 192.168.0.35), все необработанные запросы SQL работали в базе данных для Nr 35. Но все, что угодно использование набора данных XSD изменило данные на другом P C (192.168.0.224), несмотря на то, что мои строки подключения в app.config были установлены для 192.168.0.35!

Когда вы создаете набор данных для своего проекта с помощью Мастер VS запрашивает строку подключения в начале мастера. Хотя все работает так, как должно быть, когда проект является EXE-файлом, если вы компилируете DLL (как я), похоже, что эта строка подключения (в том виде, в каком она написана на этапе разработки P C) как-то жестко запрограммирована в 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

Summary

Это очень странная ситуация, которая возникает только при компиляции проекта C#, содержащего DataSet (XSD), в DLL.

Решением было переопределить вызов для получения строки подключения в Settings.designer.cs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...