简体   繁体   English

从.Net应用程序处理MySql数据库的正确方法是什么

[英]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的评论:

  • install fluent nhibernate and dependencies with nuget 使用nuget安装流畅的nhibernate和依赖项
  • write database configuration code to register the database connection on application startup, load mappings and create a session 编写数据库配置代码以在应用程序启动时注册数据库连接 ,加载映射并创建会话
  • write class mappings for your objects 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>在构造函数中列出数据库键,关系等使用自动映射 - 如果您没有现有/太复杂的数据库,则最好
  • use the session. 使用会话。 Save (yourObject), .Delete, . 保存 (yourObject),.删除,。 SaveOrUpdate etc. to manipulate the database SaveOrUpdate等来操纵数据库

Take care of session type, locking, transactions etc. depending on your needs for concurrency 根据您的并发需求,处理会话类型,锁定,事务等

Here is a tutorial 这是一个教程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从IDE构建时,部署.NET应用程序的正确方法是什么? - What is the correct way to deploy a .NET application when building from IDE 在.NET中从NetworkStream读取的正确方法是什么 - What is the correct way to read from NetworkStream in .NET 在应用程序启动期间从文件加载值的正确方法是什么? - What is the correct way of loading values from file during application startup? 处理需要“很长时间”才能完成的程序的正确方法是什么? - What is the correct way to deal with procedures that take a “long time” to complete? 在 ASP.NET 应用程序中关闭 MySQL 连接的最佳方法是什么? - What is the best way to close a MySQL connection in an ASP.NET application? 为应用程序保留可写数据库的正确方法 - Correct way to keep writable database for an application MySQL数据库的正确DateTime格式是什么? - What is the correct DateTime format for MySQL Database? 从桌面应用程序操作MySQL数据库的最佳方法是什么? - What is the best method of manipulate a MySQL database from a desktop application? 关闭第二个Application循环的正确方法是什么? - What is the correct way to close a second Application loop? 在mojoportal中传输数据库的正确方法是什么? - What is the correct way to transfer database in mojoportal?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM