У меня есть класс UserControl, класс Main Form и класс DbConn.
Я хочу получить доступ к классу DbConn «как посредник» из обоих других классов. Таким образом, UserControl должен установить строку класса DbConn, а класс основной формы должен снова прочитать строку из него.
(Или он должен сделать это на данный момент. Позже этот класс DbConn должен отслеживать учетные данные соединения и обрабатывать все соединения с моей базой данных, чтобы получить некоторую ясность между отдельными частями. На данный момент все находится в классе основной формы, но с запланированными дополнениями этот код будет сложно поддерживать, если я не разделю класс на разные классы, которые должны обрабатывать только одно, например DatabaseConnection, разные Frontendparts и т. д.)
Это UserControl Класс:
namespace mySQL_Project
{
public partial class SettingsControl : UserControl
{
DbConn dbConn = new DbConn();
public SettingsControl()
{
InitializeComponent();
}
private void Button_SetDB_Click(object sender, EventArgs e)
{
String connectString = tb_stringtext;
dbConn.connParamNewSQLite(connectString);
}
}
}
Это Main Класс:
namespace mySQL_Project
{
public partial class Main : Form
{
DbConn dbConn = new DbConn();
public Main()
{
InitializeComponent();
}
private void textBox_getDBConn_Click(object sender, EventArgs e)
{
label_dbinfo.Text = dbConn.connParamGetSQLite(); //should get Text set in userControl
}
}
}
а это DbConn Класс:
namespace mySQL_Project
{
internal class DbConn
{
private string conn;
public void connParamNewSQLite(string connectionString)
{
conn = connectionString;
}
public string connParamGetSQLite()
{
return conn;
}
public int DbGetSumApples(){
cmd = new SQLiteCommand();
cmd.CommandText = @"SELECT sum FROM inv WHERE ID=@AI";
cmd.Parameters.AddWithValue("@AI", "3"); //Apple-ID
cmd.Connection = conn;
return cmd.ExecuteScalar().ToString();
}
}
}
Но это не дает мне строку, которую я установил в классе UserControl.
Идея состоит в том, чтобы иметь что-то вроде глобальной переменной.
Например. Класс передал некоторые переменные подключения из одного класса с помощью функции connParamNewSQLite(), а другой класс будет использовать, например, функцию DbGetSumApples() в том же классе DbConn для установления соединения с базой данных. Тогда функции DbGetSumApples() потребуются параметры соединения, переданные ранее функцией connParamNewSQLite().
(Функция DbGetSumApples() не будет работать как есть, но я надеюсь прояснить, что в конечном итоге должен делать класс DbConn. Кроме того, экземпляр класса DbConn создается дважды, потому что в противном случае я не смог бы использовать функции во втором классе)
Что мне следует изменить в коде, чтобы оба класса знали класс DbConn? Или есть ли лучший подход к решению этой проблемы в виде «хорошей практики кодирования»?
(например, принимая во внимание несколько потоков, даже если это пока не запланировано.)
@user246821 user246821 Хм, я не знаю, не сделает ли это код еще более запутанным, если я буду обрабатывать все данные из MainForm. Я хочу разделить свою основную форму на разные подформы (UserControls). Несколько из этих подформ необходимо подключиться к базе данных, что я хочу сделать с помощью класса DbConn, поэтому только этот класс должен обрабатывать, например. учетные данные для подключения к базе данных. Могу ли я, например. передать в UserControls только класс DbConn, чтобы экземпляр класса DbConn создавался только один раз?
В указанном сообщении передача данных между формами обсуждается в общем смысле. Однако в большинстве случаев SQL-соединение должно использовать оператор using. Сами данные могут передаваться, но соединения, скорее всего, не должно быть.
Следующее может быть интересно: stackoverflow.com/a/74885060/10024425.





Если вы создаете только один класс DbConn, вы можете реализовать его как синглтон.
public sealed class DbConn
{
private static DbConninstance = null;
private static readonly object padlock = new object();
private string conn;
public static DbConn Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new DbConn();
}
return instance;
}
}
}
public void connParamNewSQLite(string connectionString)
{
conn = connectionString;
}
public string connParamGetSQLite()
{
return conn;
}
public int DbGetSumApples(){
cmd = new SQLiteCommand();
cmd.CommandText = @"SELECT sum FROM inv WHERE ID=@AI";
cmd.Parameters.AddWithValue("@AI", "3"); //Apple-ID
cmd.Connection = conn;
return cmd.ExecuteScalar().ToString();
}
}
Таким образом, вам не понадобится глобальная переменная. Вместо этого вы можете вызвать его сейчас из другого класса, просто назвав его так:
DbConn.Instance.DbGetSumApples()
Например:
public partial class SettingsControl : UserControl
{
public SettingsControl()
{
InitializeComponent();
}
private void Button_SetDB_Click(object sender, EventArgs e)
{
String connectString = tb_stringtext;
DbConn.Instance.connParamNewSQLite(connectString);
}
}
Вот еще материал о шаблоне Singleton. Реализация шаблона Singleton на C#
Следующее может представлять интерес: stackoverflow.com/a/69743297/10024425 (это VB.NET, но эти концепции применимы и к C#).