【问题标题】:C# - change "hard"-coded style to be reusable code [closed]C# - 将“硬”编码样式更改为可重用代码 [关闭]
【发布时间】:2016-07-28 23:13:18
【问题描述】:

我的 C# 项目中有这个功能

public DataTable access2dt()
    {

        string myConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=test.accdb";
        using (var con = new OleDbConnection(myConnectionString))
        {
            con.Open();

            using (var cmd = new OleDbCommand("EXEC OUTBOUND_FILTER",con))
            {
                cmd.Parameters.AddWithValue("prmORIGINCODE", "BDO");
                cmd.Parameters.AddWithValue("prmORIGIN", "\"*\"");
                cmd.Parameters.AddWithValue("prmSERVICECODE", "REG15");
                cmd.Parameters.AddWithValue("prmDESTCODE", "AMI");
                cmd.Parameters.AddWithValue("prmDESTINATION", "\"*\"");
                using (OleDbDataReader rdr = cmd.ExecuteReader())

                {
                    DataTable myTable = new DataTable();
                    myTable.Load(rdr);
                    return myTable;
                }


            }

        }
    }

上面的函数是用于在 Ms Access 中使用一些参数执行查询对象,该代码只适用于我的项目,但我对“代码样式”有问题。

我想更改代码,因此当我有另一个带有另一个不同参数的查询时,我不需要重写该代码(请参阅参数、查询名称和 db 文件名是“硬编码”以发挥作用)。

任何建议和 C# 代码都会有所帮助。

【问题讨论】:

  • 所以你希望这段代码能够执行任何查询,带有任意数量的参数?然后添加string query, Dictionary<string, string> queryParameters 之类的参数,或者更好的是List<SqlParameter>,或者为什么不让调用者自己发出OleDbCommand
  • @Matias 仅仅因为问题提到“代码风格”并不意味着它属于代码审查。
  • 我认为这个问题不适合 Code Review,因为 OP 专门提出了一个问题:“我希望能够在我的代码中动态更改 X,我该怎么做那?”。他/她不是在问“这是我的代码,你有什么我可以改进的地方吗?”
  • 是的,我可以使用变量并将其传递给函数,但是查询参数呢?参数不止一个,然后参数名称和参数值是我认为的两个不同的值/变量。
  • 是的,因此您希望此方法的调用者使用任意数量的参数执行任意查询。然后让调用者自己实例化并执行OleDbCommand,并将连接字符串粘贴到配置中。

标签: c#


【解决方案1】:

你是对的,你会想要重构它以使其更通用。不经常更改的一件事是该连接字符串。也许您可以将其抽象为 DataStore 类。然后你可以有一个ExecuteCommand 方法来接受命令名和参数:

public class DataStore
{
    private string _connectionStr;

    public DataStore(string connectionStr)
    {
        this._connectionStr = connectionStr;
    }

    public DataTable ExecuteCommand(string commandText, IDictionary<string,string> parameters)
    {
        using (var connection = new OleDbConnection(this._connectionStr))
        {
            connection.Open();
            using (var cmd = new OleDbCommand(commandText, con))
            {
                foreach (var pair in parameters)
                {
                    cmd.Parameters.AddWithValue(pair.Key, pair.Value);
                }

                using (var reader = cmd.ExecuteReader())
                {
                    var table = new DataTable();
                    table.Load(reader);
                    return table;
                }
            }
        }
    }
}

...但这仍然有一些限制,例如每个参数值都必须是一个字符串。您可以将 parameters 更改为 IDictionary&lt;string, object&gt;,但您会失去良好的类型安全性。

退后一步,您可能会想象 很多 开发人员在将数据库访问封装在抽象层中时遇到了完全相同的困难,并且可能已经解决了这个问题。事实上,像 Dapper 和 Entity Framework 这样的东西可以为你做这种事情

请参阅How to use Entity framework for MS Access database,了解有关如何将 Entity Framework 与 MS Access 结合使用的一些提示。或者您可以寻找任何其他类型的 ORM(对象/关系映射器)

【讨论】:

    【解决方案2】:
    public DataTable access2dt(string filename, string namaQuery, IDictionary<string,string> keyValue)
    {
        string myConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=test.accdb";
        using (var con = new OleDbConnection(myConnectionString))
        {
            con.Open();
    
            using (var cmd = new OleDbCommand("EXEC OUTBOUND_FILTER",con))
            {
                foreach (var d in keyValue)
                {
                    cmd.Parameters.AddWithValue(d.Key, d.Value);
                }
    
                using (OleDbDataReader rdr = cmd.ExecuteReader())
                {
                    DataTable myTable = new DataTable();
                    myTable.Load(rdr);
                    return myTable;
                }
            }
        }
    }
    

    【讨论】:

    • 不要回答不清楚的问题,尤其是不要转储“固定”代码,解释您所做的更改以及您认为这有助于 OP 解决原始问题的原因。
    • 我正在搜索 IDictionary 示例代码,这给了我一个想法,但我仍然对将代码放在哪里感到困惑,但感谢您的回答,我想下次我会发布我的(代码)代码审查部分的结果。
    • 谢谢,如果您仍有问题,请联系我@suulisindiyaka@stoicteam.com,以便我们讨论
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    相关资源
    最近更新 更多