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; }
}

したがって、テーブル History に列IdSaveDateTimeDescriptionABC、およびDが含まれている場合、 IDictionary に「A」、「B」、「C」、および「D」が必要です。または、それが難しすぎる場合は、すべての列をそこに投げ込むだけです。

手始めに、それが役立つ場合は、文字列列のみを使用しても問題ありません。

4

6 に答える 6

1

次のコードを使用すると、ハッシュテーブルで結果を取得できると思います。

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

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

于 2009-10-20T09:15:42.300 に答える
1

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

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

于 2009-04-15T06:57:19.773 に答える
0

NHibernate には、データベースの種類/方言でサポートされている場合、データベース スキーマを取得する方法があります。主に SchemaExport および SchemaUpdate 関数で使用されます。

手を少し汚すのが怖くないなら。

まず、Configuration クラスの GenerateSchemaUpdateScript 関数を確認します: https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs

特に、そのメソッドで参照されているこのクラスに興味があるでしょう: https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Tool/hbm2ddl/DatabaseMetadata.cs

DatabaseMetadata オブジェクトを使用すると、データベース内のすべてのテーブルとフィールドのメタデータをトラバースできるため、マップされていないフィールドを特定できます。Configuration クラスをもう一度見ると、そのマッピングのリストが TableMappings コレクションに保持されています。GenerateSchemaUpdateScript 関数からヒントを得て、TableMappings の Table オブジェクトを、DatabaseMetadata.GetTableMetadata 関数によって返された ITableMetadata を実装する任意のオブジェクトと比較して、マップされていない列を特定できます。

この情報を使用して、実行時に「動的」クラスによって使用されるマッピング ファイルを再構築し、マッピング ファイルの「AdditionalProperties」動的コンポーネント セクションにすべての動的/ランタイム フィールドを配置します。これを行うには、マッピング ファイルを埋め込みリソースとしてではなく、外部ファイルとして含める必要がありますが、これは Configuration AddFile 関数で可能です。再構築後、構成を再読み込みし、最後にセッション ファクトリを再構築します。

現時点では、Firebird、MsSQL Compact、MsSQL、MySQL、Oracle、SQLite、および SybaseAnywhere に ITableMetadata の実装があるようです。そのため、これらのいずれかでのみ可能です (独自の実装を作成しない限り)。

于 2009-06-17T07:07:01.473 に答える
0

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

ただし、 XML ファイルを読み取ってConfigurationオブジェクトを作成し、1 日で呼び出す代わりに、プログラムでデータベースにクエリを送信して、このテーブルの余分な列を見つけてから、 を変更し、プログラムで にConfiguration列を追加することができます。オブジェクトを にDynamicMappingコンパイルします。ConfigurationISessionFactory

于 2009-06-15T03:29:19.643 に答える
0

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

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

このマッピングをどのように使用するかは、クラスを動的に作成する必要があるため、良い質問です。SOL

幸運を。

于 2009-06-13T04:17:34.787 に答える