C# 在简单的WinForms应用程序中管理数据访问
我有一个简单的WinForms数据输入应用程序,它使用SQLite。它将始终是一个单用户应用程序,并且始终带有本地数据库。我有多个选项卡,用户控件作为选项卡的内容。每次选择一个选项卡时,都会初始化相应的UserControl,并删除旧的一个(使用TabPage.Controls.Remove) 每个UserControl初始化一个通用DataAccess对象,该对象包装所有数据库内容,并可与任何选项卡内容一起重用。问题是,在选项卡(UserControl)的生命周期内,我有一个打开的SQLiteConnection。我在别处读到过,这不是一个好的做法。我不想过度使用精心设计的数据层和业务对象层,部分原因是我不知道怎么做,部分原因是我认为这个应用程序没有必要这样做 我基本上在内存中保留相同的连接、适配器、DataTable、SqlCommand等对象,并使用不同的sql查询参数重用它们,并使用其他方法(如RowCount)获取缓存数据。我对LoadData方法有一个问题,因为它没有从DataTable中清除以前的查询结果,所以我在开始时手动执行 我试图找到一种方法来使用SQLiteConnection和其他对象的“using”,但是对于RowCount等简单的事情,我必须重做整个DataLoad或类似的东西。所以我只是在寻找关于这种数据访问方法的建议和评论 下面是我的DataAccess类C# 在简单的WinForms应用程序中管理数据访问,c#,winforms,sqlite,datatable,sqlconnection,C#,Winforms,Sqlite,Datatable,Sqlconnection,我有一个简单的WinForms数据输入应用程序,它使用SQLite。它将始终是一个单用户应用程序,并且始终带有本地数据库。我有多个选项卡,用户控件作为选项卡的内容。每次选择一个选项卡时,都会初始化相应的UserControl,并删除旧的一个(使用TabPage.Controls.Remove) 每个UserControl初始化一个通用DataAccess对象,该对象包装所有数据库内容,并可与任何选项卡内容一起重用。问题是,在选项卡(UserControl)的生命周期内,我有一个打开的SQLite
public class DataAccess
{
private SQLiteConnection connection = new SQLiteConnection(Global.DbConnectionString);
private DataTable dataTable = new DataTable();
private SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter();
private SQLiteCommandBuilder commandBuilder = new SQLiteCommandBuilder();
private SQLiteCommand command = new SQLiteCommand();
private BindingSource bindingSource = new BindingSource();
public DataAccess()
{
dataAdapter.SelectCommand = command;
commandBuilder.DataAdapter = dataAdapter;
bindingSource.DataSource = dataTable;
}
~DataAccess()
{
connection.Dispose();
}
public BindingSource BindingSource
{
get { return bindingSource; }
}
///*
public void LoadData(string sql, Dictionary<string, string> parameters)
{
try
{
dataTable.Clear();
command.Connection = connection;
// Ignore sql parameter if we already have CommandText. This assumes sql never changes per instance
if (command.CommandText == null)
command.CommandText = sql;
foreach (KeyValuePair<string, string> parameter in parameters)
{
if (command.Parameters.Contains(parameter.Key))
command.Parameters[parameter.Key].Value = parameter.Value;
else
{
command.Parameters.Add(new SQLiteParameter(parameter.Key));
command.Parameters[parameter.Key].Value = parameter.Value;
}
}
dataAdapter.Fill(dataTable);
}
catch (SqlException)
{
MessageBox.Show("Data Problem, need to display what's wrong later");
}
}//*/
public int RowCount()
{
return dataTable.Rows.Count;
}
public string GetFieldValue(int row_index, string column_name)
{
return dataTable.Rows[row_index][column_name].ToString();
}
public void Save()
{
dataAdapter.Update(dataTable);
}
public void NewRow(Dictionary<string, string> fields)
{
DataRow dataRow = dataTable.NewRow();
foreach (KeyValuePair<string, string> field in fields)
dataRow[field.Key] = field.Value;
dataTable.Rows.Add(dataRow);
}
}
公共类数据访问
{
私有SQLiteConnection=newsqliteconnection(Global.DbConnectionString);
私有数据表=新数据表();
私有SQLiteDataAdapter dataAdapter=新的SQLiteDataAdapter();
私有SQLiteCommandBuilder commandBuilder=新SQLiteCommandBuilder();
private SQLiteCommand=new SQLiteCommand();
私有BindingSource BindingSource=新BindingSource();
公共数据访问()
{
dataAdapter.SelectCommand=命令;
commandBuilder.DataAdapter=数据适配器;
bindingSource.DataSource=dataTable;
}
~DataAccess()
{
connection.Dispose();
}
公共绑定源绑定源
{
获取{return bindingSource;}
}
///*
公共void加载数据(字符串sql、字典参数)
{
尝试
{
dataTable.Clear();
command.Connection=连接;
//如果已经有CommandText,则忽略sql参数。这假定每个实例的sql从不更改
if(command.CommandText==null)
command.CommandText=sql;
foreach(参数中的KeyValuePair参数)
{
if(command.Parameters.Contains(parameter.Key))
command.Parameters[parameter.Key].Value=parameter.Value;
其他的
{
添加(新的SQLiteParameter(parameter.Key));
command.Parameters[parameter.Key].Value=parameter.Value;
}
}
dataAdapter.Fill(dataTable);
}
捕获(SqlException)
{
Show(“数据问题,需要稍后显示错误”);
}
}//*/
公共整数行计数()
{
返回dataTable.Rows.Count;
}
公共字符串GetFieldValue(int行索引、字符串列名称)
{
返回dataTable.Rows[行索引][列名称].ToString();
}
公共作废保存()
{
dataAdapter.Update(dataTable);
}
public void NewRow(字典字段)
{
DataRow DataRow=dataTable.NewRow();
foreach(字段中的KeyValuePair字段)
dataRow[field.Key]=field.Value;
dataTable.Rows.Add(dataRow);
}
}
如果您想做得更好,应该创建一个数据访问层,该层将公开获取数据和修改数据的方法。该层将在必要时打开连接,然后关闭它。您可以在上面添加一个缓存层。您的GUI将只使用较低层的数据对象
这不是一个小的重写,所以如果您当前的解决方案有效,并且您不想在其中投入太多精力,那么就让它保持这样,它并没有那么糟糕。如果它是一个简单的程序,那么这个简单的解决方案就很好。有了这个设计,你能对你的应用程序进行单元测试吗?不,甚至还没有考虑过单元测试。谢谢,你知道我可以看的这类应用程序的任何例子吗?