从.Net应用程序处理MySql数据库的正确方法是什么
本文关键字:方法 是什么 数据库 Net 应用程序 处理 MySql | 更新日期: 2023-09-27 18:20:17
在我目前编写的应用程序中,我处理了很多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();
}
}
}
我初始化这个类,然后使用Select方法选择数据,如下所示:
MySql mySql = new MySql();
string whateverIWant = mySql.Select("Select `MyValue` From `FooBarr` Where `Foo` = 'Barr'");
我运行这样的更新查询:
mySql.Update("UPDATE `tblFooBarr` SET `acme`='Foo' WHERE `tnt`='barr';");
在你开始之前,是的,我为自己草率草率的代码感到非常羞愧,但如果你能帮助我改进,我将不胜感激!
感谢
首先,我会在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();
}
在MySql特定的IDbProvider
实现中,您应该从ConfigurationManager.ConnectionStrings
集合中获取连接字符串,而不是对其进行硬编码
接下来,您可以将查询放在一个自定义配置部分中,该部分从代码中提取硬编码的MySql语法特定查询,如下所示:
<queries>
<SelectFoo>
<![CDATA
Select `MyValue` From `FooBarr` Where `Foo` = '{value}'
]>
</SelectFoo>
</queries>
然后使用自定义配置提供程序,通过枚举和库类向应用程序公开这些查询,这将使应用程序与使用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
}
}
最后,您可以有一个存储库类,它使用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);
}
}
}
显然,这里有很多错误处理、依赖注入设置和其他内容,但希望这能给你一个开始的结构:)
这里没有MySQL特有的内容。如果您正在处理多个DBMS,那么一种方法是使用.netdb接口IDbCommand、IDbConnection等。
将连接字符串放在app.config或类似的文件中。
你的代码中有原始SQL,不好吗?你可以看看实体框架,LinQToSQL,一个基于存储过程的设计,但这是一个尝试,学习并看看什么适合。许多原始SQL的真正问题是,您的代码与后端密不可分。解决这一问题的诀窍是"把一切都放在一个地方"。一个"模型".dll,每个类中有一个接口。一次类来处理每个表等。不要把你的代码库弄得一团糟。因为你重命名了订单表,所以遍历你的整个代码库,这是不可能的。
为什么在Update()方法中使用读取器???命令有一个方法。
正如@Hans所说,看看使用,到处都有潜在的资源泄漏。
扩展TrueWill的注释:
- 使用nuget安装fluent nhibernate和依赖项
- 编写数据库配置代码以在应用程序启动时注册数据库连接,加载映射并创建会话
- 为对象
YourObjectMap : ClassMap<YourObject>
编写类映射,在构造函数中列出数据库键、关系等。或使用自动映射-如果您没有现有/过于复杂的数据库,则最好使用自动映射 - 使用会话。Save(yourObject)、.Delete、.SaveOrUpdate等操作数据库
根据您对并发的需求,处理会话类型、锁定、事务等
这是一个教程