如何扩展NHibernate以支持更多数据库?

Mik*_*ash 3 .net c# nhibernate

如果我需要让NHibernate支持更多的数据库(不包括在支持列表中:https://www.hibernate.org/361.html),假设可以使用它的内置查询语言访问数据库,但不是SQL(例如:http://kx.com/Products/kdb+.php)...

  • 我怎样才能让NHibernate与这些数据库一起工作?

Dav*_*d M 9

NHibernate旨在使用SQL的方言而不是即席查询语言.这将是非常棘手的.但要回答你的问题,你需要:

  1. 数据库的ADO.NET提供程序(这将是一个单独的问题).
  2. Driver类(源自NHibernate的DriverBase).这是我过去写过的(有点匿名):

    public sealed class XxxClientDriver : DriverBase
    {
        public override IDbConnection CreateConnection()
        {
            return XxxClientFactory.Instance.CreateConnection();
        }
        public override IDbCommand CreateCommand()
        {
            return XxxClientFactory.Instance.CreateCommand();
        }
        public override bool UseNamedPrefixInSql
        {
            get { return true; }
        }
        public override bool UseNamedPrefixInParameter
        {
            get { return true; }
        }
        public override string NamedPrefix
        {
            get { return "@"; }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 可能(肯定是在你的情况下)一个方言,源自NHibernate的Dialect类,它定义了用你的语言呈现每个特定语法元素的类(但请注意,这仍然是面向SQL的,我怀疑你要去哪里落在这里).在我的案例中的一个例子:

    public sealed class XxxDialect : Dialect
    {
        public override JoinFragment CreateOuterJoinFragment()
        {
            return new XxxJoinFragment();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 与您的语言一样多的非标准语法元素(与普通SQL相比).再一次,我的案例中的一个例子:

    public sealed class XxxJoinFragment : JoinFragment
    {
        private readonly SqlStringBuilder _afterFrom;
        public XxxJoinFragment()
        {
            _afterFrom = new SqlStringBuilder();
        }
        private SqlStringBuilder AfterFrom
        {
            get { return _afterFrom; }
        }
        public override SqlString ToFromFragmentString
        {
            get { return _afterFrom.ToSqlString(); }
        }
        public override SqlString ToWhereFragmentString
        {
            get { return SqlString.Empty; }
        }
        public override void AddJoin(string tableName, string alias,
            string[] fkColumns, string[] pkColumns,
            JoinType joinType)
        {
            AddCrossJoin(tableName, alias);
        }
        public override void AddJoin(string tableName, string alias,
            string[] fkColumns, string[] pkColumns,
            JoinType joinType, string on)
        {
            AddJoin(tableName, alias, fkColumns, pkColumns, joinType);
        }
        public override void AddCrossJoin(string tableName, string alias)
        {
            AfterFrom.Add(", ").Add(tableName).Add(" ").Add(alias);
        }
        public override void AddJoins(SqlString fromFragment, SqlString whereFragment)
        {
            AddFromFragmentString(fromFragment);
        }
        public override bool AddCondition(string condition)
        {
            return true;
        }
        public override bool AddCondition(SqlString condition)
        {
            return true;
        }
        public override void AddFromFragmentString(SqlString fromFragmentString)
        {
            AfterFrom.Add(fromFragmentString);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在我的情况下(具有隐式连接条件的基于SQL的查询语言),这并不太难.但在你的情况下,我怀疑你会反对它.祝好运!