2009-03-23 4 views
4

Ich habe ein Legacy-System, das dynamisch eine Tabelle mit zusätzlichen Spalten bei Bedarf erweitert. Jetzt möchte ich diese Tabelle über C#/NHibernate zugreifen.
Es gibt keine Möglichkeit, das Verhalten des Altsystems zu ändern, und ich muss dynamisch mit den Daten in den zusätzlichen Spalten arbeiten. Daher ist das Dynamic-Component-Mapping keine Option, da ich die genauen Namen der zusätzlichen Spalten nicht kenne.Karte unbekannte Anzahl von Spalten zu Wörterbuch

Gibt es eine Möglichkeit, alle nicht zugeordneten Spalten in ein Wörterbuch zu stellen (Spaltenname als Schlüssel)? Oder wenn das keine Option ist, fügen Sie alle Spalten in ein Wörterbuch ein?

Noch einmal, ich kenne die Namen der Spalten zur Kompilierzeit nicht, also muss dies vollständig dynamisch sein.

Beispiel:

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

Also, wenn die Tabelle Geschichte der Spalten Id enthält, SaveDateTime, Beschreibung, A, B, C und D würde ich gerne "A", "B", "C" und "D" im IDictionary haben. Oder wenn das zu schwer ist, werfen Sie einfach alle Spalten hinein.

Für den Anfang wäre ich auch in Ordnung mit nur String-Spalten, wenn das hilft.

Antwort

1

Sie benötigen wahrscheinlich eine ADO.NET-Abfrage, um diese Daten zu erhalten. Wenn Sie NH verwenden, erhalten Sie selbst bei einer SQL-Abfrage mit SELECT * keine Spaltennamen.

Sie können versuchen, SMO (SqlServer Management-Objekte, ein .NET-Port zum SqlServer) oder eine andere Möglichkeit, um die Tabellendefinitionen zu finden. Dann erstellen Sie das Mapping mit Fluent NHibernate mit einer dynamischen Komponente. Ich bin nicht sicher, ob Sie die Zuordnungen ändern können, nachdem Sie bereits die Sitzungsfactory verwendet haben. Es ist einen Versuch wert. Viel Glück :-)

0

Ich denke, das Beste, was Sie tun können, ist die Spalten zur Laufzeit zu finden, erstellen Sie eine Zuordnung für diese zusätzlichen Spalten und schreiben Sie dann die Ausgabe auf eine xmlfile. Sobald dies geschehen ist Sie die Zuordnung zur Laufzeit hinzufügen können ...

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

Wie Sie diese Zuordnung verwenden würde, ist eine gute Frage, wie Sie Ihre Klasse erstellen müssten, um dynamisch und dann sind Sie SOL

Viel Glück.

0

Was in sql nicht möglich ist, ist in NHibernate nicht möglich.

Es ist nicht möglich, eine insert-Abfrage zu schreiben, um sie in unbekannte Spalten einzufügen.

+0

Es ist jedoch möglich, dynamisch zu erfassen und Metadaten der Tabelle verarbeiten. Und ändern Sie die Anweisungen entsprechend. Es ist möglich, diese Informationen zu verwenden, um Insert-Anweisungen mit "classic" ado.net zu ändern und/oder dynamisch zu assemblieren. Die Frage ist: Ist dies mit NHibernate möglich? Oder stellt NHibernate eine Art von Automatisierung zur Verfügung? –

+0

Ich glaube nicht, aber ich bin mir nicht sicher. Sie können versuchen, in der Benutzergruppe "nhibernate" http://groups.google.com/group/nhusers nachzufragen – Paco

0

Ich nehme an, dass Ihr Programm beim Start ein einzelnes Configuration-Objekt erstellt, indem es XML-Dateien liest, und dann die Configuration Objekt Build Objekte verwendet.

Statt die XML-Dateien zu lesen, den Bau des Configuration Objekt, und es einen Tag nennen, jedoch kann das Programm eine Anfrage an die Datenbank senden zu dieser Tabelle keine zusätzlichen Spalten, um herauszufinden, und dann die Configuration ändern, Hinzufügen Spalten auf die DynamicMapping programmgesteuert, vor dem Kompilieren der Configuration Objekt in eine .

0

NHibernate kann das Datenbankschema abrufen, sofern es vom Datenbanktyp/Dialekt unterstützt wird. Es wird hauptsächlich von den Funktionen SchemaExport und SchemaUpdate verwendet.

Wenn Sie keine Angst haben, Ihre Hände ein bisschen schmutzig zu machen;

Sie zunächst an der GenerateSchemaUpdateScript Funktion in der Konfiguration der Klasse zu suchen: https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs

Insbesondere würden Sie in dieser Klasse interessiert sein, die in diesem Verfahren verwiesen wird: https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Tool/hbm2ddl/DatabaseMetadata.cs

Das DatabaseMetaData Objekt ermöglicht es Ihnen, die Metadaten für alle Tabellen und Felder in der Datenbank zu durchlaufen, so dass Sie herausfinden können, welche Felder nicht zugeordnet sind. Wenn Sie sich die Configuration-Klasse erneut ansehen, enthält sie eine Liste ihrer Zuordnung in der TableMappings-Auflistung. Mithilfe von Hinten aus der GenerateSchemaUpdateScript-Funktion können Sie ein Table-Objekt aus TableMappings mit dem beliebigen Objekt vergleichen, das ITableMetadata implementiert, das von der DatabaseMetadata.GetTableMetadata-Funktion zurückgegeben wird, um herauszufinden, welche Spalten nicht zugeordnet sind.

Verwenden Sie diese Informationen, um die von der Klasse "dynamic" zur Laufzeit verwendete Zuordnungsdatei dann neu zu erstellen, indem Sie alle dynamischen/Laufzeitfelder in den Abschnitt "AdditionalProperties" der dynamischen Komponente der Zuordnungsdatei einfügen. Die Zuordnungsdatei muss als externe Datei und nicht als eingebettete Ressource enthalten sein, dies ist jedoch mit der Configuration AddFile-Funktion möglich. Laden Sie die Konfiguration nach dem Neuaufbau neu, und erstellen Sie schließlich die Sitzungsfactory neu.

Momentan sieht es so aus, als hätten Firebird, MsSQL Compact, MsSQL, MySQL, Oracle, SQLite und SybaseAnywhere Implementierungen für ITableMetadata, so dass es nur mit einem von diesen möglich ist (es sei denn, Sie machen Ihre eigene Implementierung).

1

Ich denke, mit dem folgenden Code Sie Ihre Ergebnisse in einer Hashtable bekommen:

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

Offensichtlich alle Ihre Daten werden aus der Sitzung entfernt werden ...