有没有一种方法可以轻松地将很多依赖SqlConnection的代码切换到MySqlConnection

时间:2019-02-06 10:10:16

标签: c# mysql sql-server

我有一个旧应用程序,其中有200,000多行代码。

它当前使用MS Sql Express作为其数据存储。有存储过程被调用,而CURD功能主要通过表适配器来实现。

由于SqlExpress具有10 GB的限制,所以我试图将应用程序更改为使用MySql数据库。

我使用了MySQL工作台附带的迁移向导来导入所有数据。

现在我要面对的问题。

在当前代码中,有一个Singleton Connection Manager可以像这样访问

var connection = ConnectionManager.GetInstance().GetNewSQLConnection();
            if (connection.State == ConnectionState.Closed) connection.Open();
            int? iErrorNumber = 0;
            DataTable dt;
            string sErrorMessage = "";
            try
            {
                SqlParameter[] paramsToStore = new SqlParameter[3];
                paramsToStore[0] = new SqlParameter("@iErrorNumber", SqlDbType.Int);
                paramsToStore[0].Value = iErrorNumber;
                paramsToStore[1] = new SqlParameter("@sErrorMessage", SqlDbType.NVarChar);
                paramsToStore[1].Size = 8000;
                paramsToStore[1].Value = sErrorMessage;
                paramsToStore[2] = new SqlParameter("@iAssayPK", iAssayPK);
                dt = SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, "USP_ASY_AssayUseCount", paramsToStore).Tables[0];
            }

这是ConnectionManager的提取接口

public interface IConnectionManager
    {
        string GenerateDBUsername(string _sDatabase, string _sUsername);
        Connection GetConnection();
        Connection GetCurrentConnection();
        SqlConnection GetNewSQLConnection();
        string GetOrmConnectionString();
        void SetCurrentConnection(Connection _oConCurrentConnection);
        void UpdateConnection(Connection _oTheConnection, bool _bSavePassword, string _sNameBeforeUpdate, string ServerAddress);
    }

如您所见,GetNewSQLConnection()返回SqlConnection对象。 在数百个使用此连接的地方。 而且大多数情况下都是这样传递给tableAdapter的

using (CustomNamesTableAdapter tadaCustomNames = new CustomNamesTableAdapter())
            {
                try
                {
                    tadaCustomNames.Connection = ConnectionManager.GetInstance().GetNewSQLConnection();
                    tadaCustomNames.Fill(_dtblToFill, ref iErrorNumber, ref sErrorMessage);
                    if (iErrorNumber != 0)
                    {
                        ErrorLogManager.GetInstance().WriteDBError(DateTime.Now, (int)iErrorNumber, sErrorMessage, "USP_CSN_GetCustomNames", this.GetType().ToString(), "void GetCustomerNames(CommonDataSet.CustomNamesDataTable _dtblToFill)", "Error while executing SP");
                        throw new BDRException(Globals.BDRMessageType.EXCEPTION, DateTime.Now, 46, "Error while executing SP");
                    }
                }

我认为,如果我可以继承SqlConnection类,那么我可以做一个类,也许我可以尝试将SqlConnection和MySqlConneciton合并为一个对象,并根据所选择的当前数据库使用基础对象,从而做到这一点。

但是我正在查看的表适配器也正在使用System.Data.SqlClient中的其他类型(例如参数),并且尝试更新所有代码将意味着更改代码很多地方....

我知道这是非常不同的,因为应用程序是使用ORM构建的,但是由于不是..我正在寻找有关如何解决此问题的建议。

如果我可以以某种方式使用接口并使用不同的实现(具有不同的数据库),那应该是可行的方法,但是由于所有代码已经取决于typed(SqlConnection,Sql.Data.SqlClient.SqlCommand等)参数,没有找到避免这种情况的方法。

其他选择是购买Sql Standard,它比正式版贵得多。或尝试归档未积极使用的旧数据并使数据库大小保持在限制以下,或者创建多个“数据”数据库(应用程序在其上运行的数据)并将其中一个用于应用程序数据(用户/角色/等等

这里只是一个想法,如果这个应用程序是用python编写的……那么更改这种类型会更容易吗?

1 个答案:

答案 0 :(得分:0)

前段时间我遇到了非常相似的情况,但是在那种情况下,我不得不将MySQL代码迁移到SQL Server代码。

最重要的是,您必须重构代码。不仅在.NET级别,还必须更新您的存储过程,并且SQL Server存储过程与MySQL存储过程并非100%兼容。有句法上的差异。

好消息是,就SQL Server与MySQL而言,ADO.NET代码非常相似。毕竟,SqlConnection和MySqlConnection继承自同一类DbConnection。同样,SqlDataAdapter和MySqlDataAdapter从相同的类DbDataAdapter继承。所有其他ADO.NET类都是如此。

您显然可以继续并重构现有的ADO.NET和存储过程代码。但是,就我而言,我没有选择那种方法。取而代之的是,我更多地考虑了实现额外的数据提供程序。这样,我现有的数据访问代码保持不变。这可能是更多的工作,但它确保了无论出于何种原因,我都可以随时返回到以前的实现。

您还有其他选择应该考虑。如何使用基于云的数据库说Azure SQL数据库?这样,您只需为您选择的大小和性能层付费。