0

NHibernateから生成されたSQLを表示または実行できる小さなソフトウェアツールを作成しました。hbm2ddl.autoは本番環境には推奨されないため、これを作成しました。

問題が1つあります。それは、SQLを生成するときに、マッピングが必要なため、悪名高いIndex列が常に引用符で囲まれていないことです。.AsList()これにより、SQLを実行できなくなります。

理論的には、NHibernateのXML構成があればhbm2ddl.keywordsタグを使用できますが、残念ながら、私のツールは複数の環境向けのDBAサポートツールとして設計されているため、プログラムによるアプローチを使用する必要があります。

私のアプローチ(冗長)は次のとおりです。

private static Configuration BuildNHConfig(string connectionString, DbType dbType, out Dialect requiredDialect)
    {
        IPersistenceConfigurer persistenceConfigurer;

        switch (dbType)
        {
            case DbType.MySQL:
                {
                    persistenceConfigurer =
                        MySQLConfiguration
                        .Standard
                        .Dialect<MySQL5Dialect>()
                        .Driver<MySqlDataDriver>()
                        .FormatSql()
                        .ShowSql()
                        .ConnectionString(connectionString);

                    requiredDialect = new MySQL5Dialect();
                    break;
                }
            case DbType.MsSqlAzure:
                {
                    persistenceConfigurer = MsSqlConfiguration.MsSql2008
                        .Dialect<MsSqlAzure2008Dialect>()
                        .Driver<SqlClientDriver>()
                        .FormatSql()
                        .ShowSql()
                        .ConnectionString(connectionString);

                    requiredDialect = new MsSqlAzure2008Dialect();
                    break;
                }
            default:
                {
                    throw new NotImplementedException();
                }
        }


        FluentConfiguration fc = Fluently.Configure()
            .Database(persistenceConfigurer)
            .ExposeConfiguration(
                cfg => cfg.SetProperty("hbm2ddl.keywords", "keywords")
                            .SetProperty("hbm2ddl.auto", "none"))
            .Mappings(
            m => m.FluentMappings.AddFromAssemblyOf<NHibernateFactory>());
        Configuration ret = fc.BuildConfiguration();
        SchemaMetadataUpdater.QuoteTableAndColumns(ret);
        return ret;


    }

...

public static void GenerateSql(MainWindowViewModel viewModel)
    {
        Dialect requiredDialect;
        Configuration cfg = BuildNHConfig(viewModel.ConnectionString, viewModel.DbType.Value, out requiredDialect);

        StringBuilder sqlBuilder = new StringBuilder();

        foreach (string sqlLine in cfg.GenerateSchemaCreationScript(requiredDialect))
            sqlBuilder.AppendLine(sqlLine);

        viewModel.Sql = sqlBuilder.ToString();
    }

説明:ViewModelテキストボックスに表示するようにのSQLを設定する場合(はい、これはWPFです)、指定された接続文字列を使用してプログラムで構成を初期化し、ViewModelそれに応じて方言/プロバイダーを選択します。Fluently ConfigureNHibernateを実行するときは、両方を設定し(との両方をhbm2ddl.keywords試しました。これがデフォルトです)、このブログ投稿に続いて、も使用します。auto-quotekeywordsSchemaMetadataUpdater

その結果、私は常に次のようなSQLを表示されます。

create table `OrderHistoryEvent` (Id BIGINT NOT NULL AUTO_INCREMENT, EventType VARCHAR(255) not null, EventTime DATETIME not null, EntityType VARCHAR(255), Comments VARCHAR(255), Order_id VARCHAR(255), Index INTEGER, primary key (Id))

有罪のIndex列が引用されていない場合。

問題は、NHibernateのプログラム的で流暢な構成を前提として、NHibernateにエクスポートされたSQLの予約語を引用するように指示するにはどうすればよいGenerateSchemaCreationScriptですか?

4

1 に答える 1

0

回避策を見つけました: 更新スクリプト (で実行されるhbm2ddl.auto=updateスクリプト) を生成すると、スクリプトは正しく引用されます。

悪名高い Index 列については既に説明しましたが、私の調査結果から、FNH ( ToManyBase.cs, method public T AsList()) にハードコーディングされています。

更新スクリプトは空のデータベースで完全に機能する作成スクリプトであるため、コードを変更して空のデータベースで更新スクリプトを生成することは、作成スクリプトを生成することと同じです。

これは、自分でスクリプトを生成したいという理由だけで発生します。NHibernate にはおそらくバグがあり、呼び出したときにのみアクティブになり、DB を構築GenerateSchemaCreationScriptさせたときにはアクティブになりません。SessionFactory

于 2013-03-18T13:01:59.737 に答える