从.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';");

在你开始之前,是的,我为自己草率草率的代码感到非常羞愧,但如果你能帮助我改进,我将不胜感激!

感谢

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

首先,我会在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等操作数据库

根据您对并发的需求,处理会话类型、锁定、事务等

这是一个教程