[英]What is the correct way to deal with a MySql database from a .Net application
In the applications I currently write, I deal a lot with a couple of MySql databases. 在我目前编写的应用程序中,我处理了很多MySql数据库。 I know I am doing this the wrong way, so you don't need to tell me that, but how do I do this the correct way?
我知道我这样做是错误的,所以你不需要告诉我,但我该如何正确地做到这一点? As in, what is the correct practice for dealing with a MySql database from a .Net application.
同样,从.Net应用程序处理MySql数据库的正确做法是什么。
At the minute I use a class, which is below: 在那一刻我使用了一个类,如下所示:
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();
}
}
}
I instanciate this class and then use the Select method to select data like so: 我实例化这个类,然后使用Select方法选择数据,如下所示:
MySql mySql = new MySql();
string whateverIWant = mySql.Select("Select `MyValue` From `FooBarr` Where `Foo` = 'Barr'");
I run update queries like so: 我运行更新查询,如下所示:
mySql.Update("UPDATE `tblFooBarr` SET `acme`='Foo' WHERE `tnt`='barr';");
Before you start, yes I am thoroughly ashamed of myself for my sloppy sloppy code, but if you could help me improve I would be most appreciative! 在你开始之前,是的,我为自己的草率代码彻底感到羞耻,但如果你能帮助我改进,我将非常感激!
Thanks 谢谢
First off, I'd make an interface to put between your MySql database and your code. 首先,我将在MySql数据库和代码之间建立一个接口。 This decouples your application from the MySql database classes;
这将您的应用程序与MySql数据库类分离; something like this:
这样的事情:
public interface IDbProvider : IDisposable
{
void Open();
void BeginTransaction();
IDataReader ExecuteReader(string query);
int ExecuteNonReader(string query);
int GetLastInsertId();
void Commit();
void Rollback();
void Close();
}
Within your MySql-specific IDbProvider
implementation you should get the connection string from the ConfigurationManager.ConnectionStrings
collection rather than hard-coding it. 在特定
IDbProvider
MySql的IDbProvider
实现中,您应该从ConfigurationManager.ConnectionStrings
集合中获取连接字符串,而不是对其进行硬编码。
Next, you could put your queries in a custom config section which gets hard-coded, MySql-syntax-specific queries out of your code, like this: 接下来,您可以将查询放在自定义配置部分中,该部分从代码中获取硬编码,特定于MySql语法的查询,如下所示:
<queries>
<SelectFoo>
<![CDATA
Select `MyValue` From `FooBarr` Where `Foo` = '{value}'
]>
</SelectFoo>
</queries>
...then use a custom configuration provider to expose those queries to your application via an enumeration and a library class, which decouples your application from the knowledge it's using SQL: ...然后使用自定义配置提供程序通过枚举和库类将这些查询公开给您的应用程序,这将您的应用程序与使用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
}
}
Finally, you can have a repository class which uses the QueryLibrary
to get the queries to send to the IDbProvider
so it can return objects or execute updates, which decouples your application from databases altogether: 最后,您可以拥有一个使用
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);
}
}
}
Obviously there's a bunch of error handling, dependency injection setup and other stuff to go in there, but hopefully this should give you a structure to start from :) 显然有一堆错误处理,依赖注入设置和其他内容,但希望这应该给你一个结构从...开始
Nothing specific to MySQL in here. 这里没有MySQL的特定内容。 If you are dealing with multiple DBMS's then one way to go is to use the .net db interfaces IDbCommand, IDbConnection etc..
如果您正在处理多个DBMS,那么一种方法是使用.net db接口IDbCommand,IDbConnection等。
Put the connection string in app.config or some such. 将连接字符串放在app.config或其他类似的地方。
Raw SQL in your code, bad? 你的代码中的原始SQL,不好吗? You could look at entity frameworks, LinQToSQL, a stored procedure based design, but that is have a go, learn and see what fits.
你可以看看实体框架,LinQToSQL,一个基于存储过程的设计,但是有一个去,学习,看看有什么适合。 The real problem with a lot of raw SQL, is your code is inextricably tied to your backend.
很多原始SQL的真正问题是你的代码与你的后端有着千丝万缕的联系。 The trick to managing that is to 'put it all in one place'.
管理它的诀窍是“把它放在一个地方”。 One 'model'.dll, one interface in each class.
一个'model'.dll,每个类中有一个接口。 Once class to deal with each table etc. Don't litter your code base with it.
一旦上课处理每个表等。不要乱丢你的代码库。 Trawling through your entire code base because you renamed the orders table, that's the no no.
由于您重命名了订单表,因此拖拽整个代码库,这是不行的。
Why are you using a reader in that Update() method??? 为什么在Update()方法中使用阅读器? Command has a method for that.
Command有一个方法。
And as @Hans said look at using, you have potential resource leaks all over the place. 正如@Hans所说的那样,你可能会在整个地方发现潜在的资源泄漏。
Expanding TrueWill's comment: 扩展TrueWill的评论:
YourObjectMap : ClassMap<YourObject>
listing database keys, relations etc. in the constructor or use Auto mapping - best if you don't have an existing/too complex database YourObjectMap : ClassMap<YourObject>
在构造函数中列出数据库键,关系等或使用自动映射 - 如果您没有现有/太复杂的数据库,则最好 Take care of session type, locking, transactions etc. depending on your needs for concurrency 根据您的并发需求,处理会话类型,锁定,事务等
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.