NHibernate - 从 PGSQL 迁移到 MSSQL 时语法不正确

Posted

技术标签:

【中文标题】NHibernate - 从 PGSQL 迁移到 MSSQL 时语法不正确【英文标题】:NHibernate - Incorrect syntax when migrating from PGSQL to MSSQL 【发布时间】:2013-01-04 07:21:21 【问题描述】:

我目前正在尝试将 ASP.NET MVC 4 网站从 postgreSQL 迁移到 MS SQL(然后使用 SQL Azure)。该网站与 pgsql 完美配合。我预计只需更改连接字符串和数据库驱动程序就足够了,但我收到一条错误消息:

NHibernate.HibernateException: Incorrect syntax near the keyword 'Public'. ---> System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'Public'. 

请注意,我们使用 NHibernate Castle 进行数据库交互。这是显示 NHibernate 配置的 web.config 部分:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
  <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
  <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
  <property name="connection.connection_string">Data Source=.\SQLEXPRESS;Initial Catalog=folke;Integrated Security=SSPI;</property>
  <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
  <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
  <mapping assembly="Folke" />
</session-factory>

当我调用这个方法时触发了错误:

public static void Install()
    
        new SchemaExport(CurrentConfiguration).Execute(true, true, false);
    

这是完整的错误信息:

NHibernate.HibernateException:关键字“Public”附近的语法不正确。 ---> System.Data.SqlClient.SqlException:关键字“Public”附近的语法不正确。在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 在 System.Data.SqlClient.SqlClient 的 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection,Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 在 System.Data.SqlClient。 SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at NHibernate.Tool.hbm2ddl.SchemaExport.ExecuteSql(IDbCommand cmd, String sql) at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action1 scriptAction, Boolean export, Boolean throwOnError, TextWriter exportOutput, IDbCommand statement, String sql) at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action1 scriptAction, Boolean export, Boolean justDrop, IDbConnection connection, TextWriter exportOutput) at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action1 scriptAction, Boolean export, Boolean justDrop) --- 内部异常堆栈跟踪结束 --- 在 NHibernate.Tool.hbm2ddl.SchemaExport.Execu te(Action1 scriptAction, Boolean export, Boolean justDrop) at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Boolean script, Boolean export, Boolean justDrop) at FolkeLib.BaseDataAccess.Install() in e:\Documents\GitHub\Folke\FolkeLib\BaseDataAccess.cs:line 36 at Folke.Models.Installer.Install() in e:\Documents\GitHub\Folke\Folke\Models\Installer.cs:line 22 at Folke.Controllers.InstallerController.Index() in e:\Documents\GitHub\Folke\Folke\Controllers\InstallerController.cs:line 20 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 参数) 在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.&lt;&gt;c__DisplayClass15.&lt;InvokeActionMethodWithFilters&gt;b__12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 继续) 在 System.Web.Mvc.ControllerActionInvoker.c_DisplayClass15。 c_DisplayClass17.b__14() 在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary2 参数) 在 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) ;

【问题讨论】:

【参考方案1】:

您的映射中似乎可能有一些Auxiliary Database Objects。您可能需要更改它们的 SQL 语法,或使用 dialect-scope 为多种方言提供它们。

自定义 SQL 也可能来自命名查询,如果您在 ISession 上使用 CreateSqlQuery(),但由于在创建模式期间发生异常,这似乎不太可能。请注意,其他一些映射结构(如公式和过滤器)也可能在映射中使用自定义 SQL。

如果这没有帮助,我认为您必须尝试弄清楚实际尝试的 SQL 命令是什么。如果它在异常中不可用,通过提供 NHibernate.pdb 文件和相应的源代码应该很容易做到。并要求 Visual Studio 中断发生异常的位置。

【讨论】:

【参考方案2】:

实际上,我认为这是因为 MS SQL Server 将 PUBLIC 定义为关键字 (http://msdn.microsoft.com/en-us/library/ms189822%28v=sql.100%29.aspx)。

您可能有一些这样命名的表或属性/列。您应该在映射中重命名它,或将其括在反引号 (`) 中以使 NHibernate 应用方言特定的引号字符。

您还可以在 NHibernate 配置中启用自动引用。

【讨论】:

以上是关于NHibernate - 从 PGSQL 迁移到 MSSQL 时语法不正确的主要内容,如果未能解决你的问题,请参考以下文章

如何从 NHibernate 映射文件生成“迁移”DDL?

使用py-mysql2pgsql 简单实现mysql数据库迁移到pgsql

MySQL迁移PostgreSQL--py-mysql2pgsql迁移

MySQL准实时同步到PostgreSQL, Greenplum的方案之一 - rds_dbsync

从 Postgres 迁移到 MongoDB

NHibernate 中的自动更新包