在我目前编写的应用程序中,我处理了很多MySql数据库.我知道我这样做是错误的,所以你不需要告诉我,但我该如何正确地做到这一点?同样,从.Net应用程序处理MySql数据库的正确做法是什么.
在那一刻我使用了一个类,如下所示:
using System;
using MySql.Data.MySqlClient;
namespace WhateverProjectImWorkingOn
{
class MySql
{
public string myConnectionString = String.Format("SERVER={0}; DATABASE={1}; UID={2}; PASSWORD={3}", "8.8.8.8", "foobar", "foo", "barr");
public string Select(string mySqlQuery)
{
MySqlConnection connection = new MySqlConnection(myConnectionString);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader Reader;
command.CommandText = mySqlQuery;
connection.Open();
Reader = command.ExecuteReader();
string thisrow = "";
while (Reader.Read())
{
for (int i = 0; i < Reader.FieldCount; i++)
{
thisrow += Reader.GetValue(i).ToString();
}
}
Reader.Close();
connection.Close();
return thisrow;
}
public void Update(string mySqlQuery)
{
MySqlConnection mangoConnection = new MySqlConnection(myConnectionString);
MySqlCommand command = mangoConnection.CreateCommand();
command.CommandText = mySqlQuery;
mangoConnection.Open();
MySqlDataReader reader = command.ExecuteReader();
mangoConnection.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我实例化这个类,然后使用Select方法选择数据,如下所示:
MySql mySql = new MySql();
string whateverIWant = mySql.Select("Select `MyValue` From `FooBarr` Where `Foo` = 'Barr'");
Run Code Online (Sandbox Code Playgroud)
我运行更新查询,如下所示:
mySql.Update("UPDATE `tblFooBarr` SET `acme`='Foo' WHERE `tnt`='barr';");
Run Code Online (Sandbox Code Playgroud)
在你开始之前,是的,我为自己的草率代码彻底感到羞耻,但如果你能帮助我改进,我将非常感激!
谢谢
首先,我将在MySql数据库和代码之间建立一个接口.这将您的应用程序与MySql数据库类分离; 这样的事情:
public interface IDbProvider : IDisposable
{
void Open();
void BeginTransaction();
IDataReader ExecuteReader(string query);
int ExecuteNonReader(string query);
int GetLastInsertId();
void Commit();
void Rollback();
void Close();
}
Run Code Online (Sandbox Code Playgroud)
在特定于MySql的IDbProvider实现中,您应该从ConfigurationManager.ConnectionStrings集合中获取连接字符串,而不是对其进行硬编码.
接下来,您可以将查询放在自定义配置部分中,该部分从代码中获取硬编码,特定于MySql语法的查询,如下所示:
<queries>
<SelectFoo>
<![CDATA
Select `MyValue` From `FooBarr` Where `Foo` = '{value}'
]>
</SelectFoo>
</queries>
Run Code Online (Sandbox Code Playgroud)
...然后使用自定义配置提供程序通过枚举和库类将这些查询公开给您的应用程序,这将您的应用程序与使用SQL的知识分离:
public enum AvailableQuery
{
SelectFoo
}
public class QueryLibrary
{
private readonly AvailableQueryConfigSection _availableQueries;
public QueryLibrary()
{
this._availableQueries =
(AvailableQueryConfigSection)
ConfigurationManager.GetSection("queries");
}
public string GetQuery(AvailableQuery query)
{
// return query from availableQueries
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您可以拥有一个存储库类,该类使用它QueryLibrary来获取要发送的查询,IDbProvider以便它可以返回对象或执行更新,从而将应用程序与数据库完全分离:
public class FooRepository
{
public Foo GetFooByValue(string value)
{
string query = this._queryLibrary
.GetAvailableQuery(AvailableQuery.SelectFoo)
.Replace("{value}", value); // <- or better still, use parameters
using (IDataReader reader = this._dbProvider.ExecuteReader(query))
{
// Or get the values out of the reader here and pass them into
// a constructor instead of passing in the reader itself:
return new Foo(reader);
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然有一堆错误处理,依赖注入设置和其他内容,但希望这应该给你一个结构从...开始