winforms 如何使用MySqlConnection C#编写可用于所有类的get方法

1u4esq0p  于 2022-12-14  发布在  Mysql
关注(0)|答案(2)|浏览(154)

我有一些从数据库中获取数据的方法,如下所示。问题是,如果我有很多类,我需要编写很多get-data方法来检索相应对象的列表,尽管逻辑是相同的,只是类、属性和表名不同。
我想知道是否有可能只写一个方法用于所有类。挑战部分是我不知道如何将读取器数据转换为属性的数据类型。
我将传入对象、列和表名。例如:

// I want to write this method so it can be used for all classes
public List<Object> getData(string className, string[] columns, string tableName) {...} 

public List<Client> GetClients()
    {
        List<Client> list = new List<Client>();
        try
        {
            conn.Open();

            string sql = "SELECT id, clientName, info, hidden from clients";
            MySqlCommand cmd = new MySqlCommand(sql, conn);
            MySqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                Client p = new Client((int)rdr[0], (string)rdr[1], (string)rdr[2], Convert.ToBoolean(rdr["hidden"]));
                list.Add(p);
            }
            rdr.Close();
            return list;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            return null;
        }
        finally
        {
            conn.Close();
        }
    }

public List<RepPrefix> GetRepPrefixes()
    {
        List<RepPrefix> list = new List<RepPrefix>();
        try
        {
            conn.Open();

            string sql = "SELECT id, prefixName, hidden from repPrefix";
            MySqlCommand cmd = new MySqlCommand(sql, conn);
            MySqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                RepPrefix p = new RepPrefix((int)rdr[0], (string)rdr[1], Convert.ToBoolean(rdr["hidden"]));
                list.Add(p);
            }
            rdr.Close();
            return list;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            return null;
        }
        finally
        {
            conn.Close();
        }
    }
d6kp6zgx

d6kp6zgx1#

如果您的ClientRepPrefix具有名称与数据库列匹配的可设置属性,则可以使用Dapper这样的库来避免编写大量样板代码:

var clients = conn.Query<Client>("SELECT id, clientName, info, hidden from clients;").ToList();
var repPrefixes = conn.Query<RepPrefix>("SELECT id, prefixName, hidden from repPrefix;").ToList();

// ...
class Client
{
    public int Id { get; set; }
    public string ClientName { get; set; }
    public string Info { get; set; }
    public bool Hidden { get; set; }
}

它将从DB列名Map到C#属性名,执行适当的类型转换等。
如果您不想使用外部库,而是想自己编写代码,我将修改getData的签名,以接受一个函数,该函数接受DbDataReader并返回T类型的初始化对象:

// method that executes the query and invokes a callback to read the data
public List<T> getData<T>(string[] columns, string tableName, Func<DbDataReader, T> readData)
{
    var list = new List<T>();
    try
    {
        conn.Open();

        string sql = "SELECT " + string.Join(",", columns) + " from " + tableName;
        using var cmd = new MySqlCommand(sql, conn);
        using var rdr = cmd.ExecuteReader();

        while (rdr.Read())
        {
            // read the data from this row and construct a new T
            T t = readData(rdr);
            list.Add(p);
        }
        return list;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        return null;
    }
    finally
    {
        conn.Close();
    }
}

// an example of calling getData with a custom callback that creates Client objects
List<Client> GetClients() =>
    getData(new[] { "id", "clientName", "info", "hidden" }, "clients",
    rdr => new Client(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2), rdr.GetBoolean(3)));
vyu0f0g1

vyu0f0g12#

首先,我强烈推荐Dapper。Dapper将为您将对象Map到SQL语句,并且性能良好。
如果您有与db表一致的类,则可以在每个类上使用反射或某个函数来生成SELECT、INSERT和UPDATE语句,然后将这些相同的对象用作Dapper函数中的参数。

相关问题