2009-03-23 5 views
4

私は、必要に応じて列を追加してテーブルを動的に増やすレガシーシステムを持っています。今私はC#/ NHibernate経由で上記のテーブルにアクセスしたいと思います。
レガシーシステムの動作を変更する方法はなく、追加の列のデータを動的に処理する必要があります。したがって、追加の列の正確な名前がわからないので、動的コンポーネントマッピングはオプションではありません。未知数の列を辞書にマップする

マッピングされていないすべての列を辞書に入れる方法はありますか?それともオプションではない場合は、すべての列を辞書に入れますか?

この場合も、コンパイル時に列名がわからないため、これは完全に動的でなければなりません。

例:

だから
public class History 
{ 
    public Guid Id { get; set; } 
    public DateTime SaveDateTime { get; set; } 
    public string Description { get; set; } 
    public IDictionary<string, object> AdditionalProperties { get; set; } 
} 

テーブル履歴列イドSaveDateTime説明BCD Iが含まれている場合であろうIDictionaryに "A"、 "B"、 "C"、 "D"を持つようにします。それが難しいのであれば、そこにすべての列を投げるだけです。

初心者にとっては、文字列を使用しても問題ありません。

答えて

1

このデータを取得するには、おそらくADO.NETクエリが必要です。 NHを使用する場合、SELECT *を使用するSQL問合せでも、列名は取得されません。

SMO(SqlServer管理オブジェクト、SqlServerへの.NETポート)、または他の方法でテーブル定義を検索できます。次に、Fluent NHibernateを動的コンポーネントに使用してマッピングを構築します。すでにセッションファクトリを使用した後にマッピングを変更できるかどうかはわかりません。それは試みに値します。幸運:-)

0

あなたができることは、実行時に列を見つけて、これらの余分な列のマッピングを作成し、出力をxmlfileに書き込むことです。それが完了したら、あなたは、実行時にマッピングを追加することができます...あなたはこのマッピングを使用する方法

ISessionFactory sessionFactory = new Configuration() 
        .AddFile("myDynamicMapping.hbm.xml") 

良い質問ですあなたが同様に動的にクラスを作成しなければならないとして、あなたはSOL

ですがんばろう。

0

SQLでは不可能なことはNHibernateでは不可能です。

未知の列に挿入するために挿入クエリを記述することはできません。

+0

しかし、動的に検出してすることが可能ですプロセステーブルメタデータ。それに応じてinsert文を変更します。この情報を使用して、 "classic" ado.netを使用してinsert文を変更および/または動的にアセンブルすることは可能です。問題は、これはNHibernateを使って行うことができるのですか?あるいは、NHibernateはこれを行うための何らかの自動化を提供します。 –

+0

私はそうは思わないが、わからない。あなたはnhibernateユーザグループhttp://groups.google.com/group/nhusersで質問することができます – Paco

0

私はあなたのプログラムが起動時にXMLファイルを読むことによって単一のConfigurationオブジェクトを構築し、次にConfigurationオブジェクトビルドISessionFactoryオブジェクトを使用すると仮定します。

Configurationオブジェクトを作成し、それを1日呼び出す代わりに、プログラムはデータベースにクエリを送信して、このテーブルの余分な列を見つけてConfigurationを変更しますISessionFactoryConfigurationオブジェクトをコンパイルする前に、プログラムDynamicMappingに列。

0

NHibernateのは、データベーススキーマを取得する方法を持っているが、それはデータベースタイプ/方言でサポートされていました。主にSchemaExportおよびSchemaUpdate関数によって使用されます。

あなたは少し手を汚すのを怖がっていない場合。

設定開始クラスのGenerateSchemaUpdateScript機能を見て、: https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Tool/hbm2ddl/DatabaseMetadata.cs

DatabaseMetaDataオブジェクト:特に https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs

、あなたはその方法で参照され、このクラス、に興味があると思いますデータベース内のすべてのテーブルとフィールドのメタデータをトラバースすることができ、どのフィールドがマップされていないか把握できます。 Configurationクラスを再度見ると、TableMappingsコレクションにそのマッピングのリストが保持されます。 GenerateSchemaUpdateScript機能からヒントを取ると、あなたは、マッピングされていないする列を把握するDatabaseMetadata.GetTableMetadata関数によって返さITableMetadataを実装する任意のオブジェクトに対してTableMappingsからTableオブジェクトを比較することができます。次に、マッピング・ファイルの「additionalpropertiesを」動的成分セクション内のすべての動的/ランタイムフィールドを配置する実行時に、「動的」クラスによって使用されるマッピングファイルを再構築する

使用この情報。マッピングファイルは、外部ファイルではなく、これを行うには、埋め込みリソースとして含まれる必要がありますが、これは設定ADDFILE機能で可能です。再構築後、構成をリロードし、最後にセッションファクトリを再構築します。

現時点では、Firebird、MsSQL Compact、MsSQL、MySQL、Oracle、SQLite、SybaseAnywhereのようにITableMetadataの実装が用意されているようです。

1

私は次のコードでおHashtableにあなたの結果を得ることができますね。

var hashTable = (Hashtable)Session.CreateSQLQuery("SELECT * FROM MyTable") 
    .SetResultTransformer(Transformers.AliasToEntityMap) 
    .UniqueResult(); 

は明らかに、すべてのデータがセッションから切り離されます...

関連する問題