支持.NET产品的多个数据库的最佳方法是什么?

Kal*_*pak 11 c# architecture design-patterns multiple-databases

我们正在设计一种可以支持多个数据库的产品.我们目前正在做这样的事情,以便我们的代码支持MS SQL以及MySQL:

namespace Handlers
{
    public class BaseHandler
    {
        protected string connectionString;
        protected string providerName;

        protected BaseHandler()
        {
            connectionString = ApplicationConstants.DatabaseVariables.GetConnectionString();
            providerName = ApplicationConstants.DatabaseVariables.GetProviderName();
        }
    }
}

namespace Constants
{
    internal class ApplicationConstants
    {
        public class DatabaseVariables
        {
            public static readonly string SqlServerProvider = "System.Data.SqlClient";
            public static readonly string MySqlProvider = "MySql.Data.MySqlClient";

            public static string GetConnectionString()
            {
                return ConfigurationManager.ConnectionStrings["CONNECTION_STRING"].ConnectionString; 
            }

            public static string GetProviderName()
            {
                return ConfigurationManager.ConnectionStrings["CONNECTION_STRING"].ProviderName;
            }
        }
    }
}

namespace Handlers
{
    internal class InfoHandler : BaseHandler
    {
        public InfoHandler() : base()
        {
        }

        public void Insert(InfoModel infoModel)
        {
            CommonUtilities commonUtilities = new CommonUtilities();
            string cmdInsert = InfoQueryHelper.InsertQuery(providerName);
            DbCommand cmd = null;
            try
            {
                DbProviderFactory provider = DbProviderFactories.GetFactory(providerName);
                DbConnection con = LicDbConnectionScope.Current.GetOpenConnection(provider, connectionString);
                cmd = commonUtilities.GetCommand(provider, con, cmdInsert);
                commonUtilities.PrepareCommand(cmd, infoModel.AccessKey, "paramAccessKey", DbType.String, false, provider, providerName);
                commonUtilities.PrepareCommand(cmd, infoModel.AccessValue, "paramAccessValue", DbType.String, false, provider, providerName);
                cmd.ExecuteNonQuery();
            }
            catch (SqlException dbException)
            {
                //-2146232060 for MS SQL Server
                //-2147467259 for MY SQL Server
                /*Check if Sql server instance is running or not*/
                if (dbException.ErrorCode == -2146232060 || dbException.ErrorCode == -2147467259)
                {
                    throw new BusinessException("ER0008");
                }
                else
                {
                    throw new BusinessException("GENERIC_EXCEPTION_ERROR");
                }
            }
            catch (Exception generalException)
            {
                throw generalException;
            }
            finally
            {
                cmd.Dispose();
            }
        }
    }
}

namespace QueryHelpers
{
    internal class InfoQueryHelper
    {
        public static string InsertQuery(string providerName)
        {
            if (providerName == ApplicationConstants.DatabaseVariables.SqlServerProvider)
            {
                return @"INSERT INTO table1
           (ACCESS_KEY
           ,ACCESS_VALUE)
     VALUES
           (@paramAccessKey
           ,@paramAccessValue) ";
            }
            else if (providerName == ApplicationConstants.DatabaseVariables.MySqlProvider)
            {
                return @"INSERT INTO table1
           (ACCESS_KEY
           ,ACCESS_VALUE)
     VALUES
           (?paramAccessKey
           ,?paramAccessValue) ";
            }
            else
            {
                return string.Empty;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你能否建议是否有更好的方法吗?这种方法的优点和缺点是什么?

Jul*_*iet 10

无论你做什么,都不要编写自己的映射代码.它之前已经完成了,它可能比你用手写的任何东西都要好一百万倍.

毫无疑问,你应该使用NHibernate.它是一个对象关系映射器,它使数据库访问透明:您定义了一组代表数据库中每个表的DAL类,并使用NHibernate提供程序对您的数据库执行查询.NHibernate将动态生成查询数据库和填充DAL对象所需的SQL.

NHibernate的优点在于它根据您在配置文件中指定的内容生成SQL.开箱即用,它支持SQL Server,Oracle,MySQL,Firebird,PostGres和其他一些数据库.


Sor*_*tis 5

我使用NHibernate.

这是一个很好的初学者教程


Hap*_*ido 3

对于您当前的需求,我同意 NHibernate...

只是想指出您的类层次结构中的一些内容......

你会更好地使用接口

就像(只需检查文档或互联网以获取确切的语法)

Interface IDBParser  
    Function1  
    Function2  

class MSSQLParser : IDBParser  
    Function1  
    Function2  

class MySQLParser : IDBParser  
    Function1  
    Function2 
Run Code Online (Sandbox Code Playgroud)

然后在您的代码中您可以使用该接口

Main()  
    IDBParser dbParser;  
    if(...)  
       dbParser = new MSSQLParser();  
    else  
       dbParser = new MySQLParser();  

    SomeFunction( dbParser );  

// the parser can be sent by parameter, global setting, central module, ...  
    SomeFunction( IDBParser dbParser)  
      dbParser.Function1();  
Run Code Online (Sandbox Code Playgroud)

这样,管理起来会更容易,并且您的代码不会充满相同的 if/else 条件。添加其他数据库也会容易得多。另一个优点是它可以通过发送模拟对象来帮助您进行单元测试。