4 Stimmen

Wie lassen sich mehrsprachige Domänenobjekte am besten mit NHibernate implementieren?

Wie lassen sich die Domänenobjekte, die mehrsprachige Felder enthalten können, am besten gestalten? Ein Beispiel kann eine Produktklasse sein, deren Beschreibung mehrsprachig ist.

Ich habe einige Links gefunden, konnte mich aber nicht entscheiden, welcher der beste Weg ist.

  1. http://fabiomaulo.blogspot.com/2009/06/localized-property-with-nhibernate.html
    (Hier werden alle lokalisierten Sprachdaten in einem Feld gespeichert. Kann ein Problem sein, wenn wir von Sql abfragen)

  2. http://ayende.com/Blog/archive/2006/12/26/LocalizingNHibernateContextualParameters.aspx
    (Dieses hat eine Warnung am Anfang, dass es ein Hack ist und nicht mehr unterstützt wird)

  3. http://www.webdevbros.net/2009/06/24/create-a-multi-languaged-domain-model-with-nhibernate-and-c/
    (Hier wird nicht beschrieben, wie die mehrsprachigen Daten in der Datenbank strukturiert werden).

Hat jemand Erfahrung mit der Verwendung von NHibernate mit mehrsprachigen Daten? Gibt es einen besseren Weg?

2voto

mdma Punkte 55529

Die dritte Option sieht großartig aus. Die Hibernate-Zuordnung ist gegeben, aber nicht das Datenbankschema - wenn es das ist, was Ihnen fehlt, dann skizziere ich es hier:

dictionary
----------
ID: int - identity
name: nvarchar(255)

phrase
------
dictionary_id:int  (fkey dictionary.ID)
culture_id:int     (LCID)
phrase:nvarchar(255)  - this is the default size - seems too small

によると dieser Blogeintrag 255 ist die Standard-Stringlänge für String-Werte. Um die kurze Zeichenfolgenlänge für den Phrasentext zu überwinden, können Sie die <element> Tag an

<element column="phrase" type="String" length="4001"></element>

Um dies in Ihrem Domänenmodell zu verwenden, fügen Sie eine PhraseDictionary Eigenschaft zu Ihrer Entität, wo Sie übersetzbaren Text wünschen. Z.B. die Eigenschaft title oder decription.

Ich denke, der Artikel beschreibt einen großartigen Ansatz und ist derjenige, den ich wählen würde. wählen würde.

EDIT: Als Antwort auf die Kommentare sollten Sie die Länge auf weniger als 4001 festlegen, wenn Sie wissen, dass die absolute Maximalgröße geringer ist, da dies in der Regel schneller ist. Außerdem holt NHibernate die Auflistung nach und nach, aber möglicherweise werden alle Elemente auf einmal geholt. Sie können ein Profil erstellen, um festzustellen, ob dies Auswirkungen auf die Leistung hat. (Wenn Sie nur eine Handvoll Sprachen haben, werden Sie kaum einen Unterschied feststellen). Wenn Sie viele Sprachen haben (z. B. 50+), kann es sich lohnen, benutzerdefinierte Eigenschaften zu erstellen, um den lokalisierten Text abzurufen. Diese geben Abfragen aus, um genau den benötigten Text abzurufen. Noch wichtiger ist, dass Sie den gesamten Text für eine bestimmte Entität in einer einzigen Abfrage abrufen können, anstatt jede lokalisierte Texteigenschaft in einer separaten Abfrage.

Beachten Sie, dass dieser zusätzliche Aufwand nur erforderlich ist, wenn die Profilerstellung Anlass zur Sorge über die Leistung gibt. Die Chancen stehen gut, dass die Implementierung in diesem Artikel in der vorliegenden Form mehr als ausreichend funktioniert.

1voto

meriton Punkte 65030

Ich habe nur Erfahrung mit Hibernate, aber da nHibernate so ähnlich ist:

Eine Möglichkeit besteht darin, einen Komponententyp MultilingualString mit Membern für jede Sprache zu definieren (dies setzt voraus, dass die Menge der Sprachen zum Zeitpunkt der Codierung bekannt ist). Dieser Typ ist auch ein geeigneter Ort, um einen Getter für die Zeichenkette nach Sprach-ID zu platzieren.

class MultiLingualString {
    String english;
    String chinese;
    String klingon;

    String forLanguage(Language lang) {
        switch (lang) {
            // you can guess what goes here
        }
    }
}

Dies führt dazu, dass die Zeichenketten für alle Sprachen in separaten Spalten in der Datenbank gespeichert werden, während die Darstellung in der Objektwelt eine feine Granularität beibehält.

Der Vorteil ist, dass keine Verknüpfung erforderlich ist, um die Zeichenfolgen abzurufen. Andererseits besteht die einzige Möglichkeit, eine Zeichenfolge bei diesem Ansatz nicht abzurufen, darin, eine Projektion zu verwenden, was eine große Einschränkung darstellt, wenn die Zeichenfolgen groß und zahlreich sind und selten benötigt werden.

Wenn Sie dies häufig tun, könnte es sich lohnen, einen UserType zu schreiben.

1voto

lambacck Punkte 9504

Von einem rein datenbankorientierten Standpunkt aus betrachtet, sollten Sie mit SQL Server eine Tabelle mit allen Basisdaten (Datensatzschlüssel, Daten, Zahlen usw.) und eine Tabelle mit allen übersetzbaren Zeichenkettendaten haben. Nennen wir die beiden Tabellen Base und Base_Description.

Base stellt sicher, dass es einen einzigen Schlüssel für jeden Datensatz gibt. Der Schlüssel kann eine Zeichenkette oder eine automatisch generierte ID sein, je nach Ihrem speziellen Anwendungsfall.

Die Tabelle Base_Description ist mit der Tabelle Base verknüpft, enthält aber auch einen Wert zur Auswahl der Sprache, in der die Daten vorliegen. In meinen Projekten verwenden wir die Spalte langid aus sys.Sprachen denn wir können die Sprache der Verbindung mit und dann mit @@LANGID für die meisten Operationen verwenden.

In unseren Tests haben wir festgestellt, dass dies wesentlich schneller ist als mehrere Felder für jede Sprache, und dass Sie so auch leichter weitere Sprachen hinzufügen können. Wir verwenden auch die Volltextindizierung von SQL Server, die mit dieser Methode vollständig funktioniert. Sie sollten in der neutralen Sprache indizieren und können dann die Sprache auswählen, nach der zur Laufzeit gesucht werden soll (auch durch Filterung nach der Spalte LangID in Base_Description).

1voto

Cade Roux Punkte 85601

Beinhalten Ihre Anforderungen, dass die Domänenobjekte tatsächlich mehrsprachige Eigenschaften in ein und demselben Objekt haben? Und wenn ja, handelt es sich dabei um unbegrenzte Übersetzungen, die im Objekt gespeichert sind (z. B. in einer Sammlung - in diesem Fall würde ich sagen, dass sie genau wie jede Master/Detail- oder Parent/Child-Sammlung sein muss), oder um feste Übersetzungen, wobei die Sprachen (und damit die Zuordnung zu den Ergebnissen eines gespeicherten Prozesses oder was auch immer) ohnehin statisch bestimmt werden müssen?

In vielen internationalisierten Anwendungen, an denen ich gearbeitet habe, waren die Daten nur in einer Sprache vorhanden - Kundennamen, Produktnamen (es hatte keinen Sinn, sogar identische Produkte, die in einem Land verwendet wurden, auf Produkte in einem anderen Land abzubilden, da sie alle unterschiedliche Händler und unterschiedliche SKUs hatten, und natürlich lokalisierte Preise). Auch die Schnittstelle war (zunächst) nur in einer Sprache verfügbar. Für alle Domänenobjekte war also jeweils nur eine Sprache erforderlich. Die Sprache der Übersetzung würde also bei der Instanziierung des Objekts festgelegt.

Wir hatten Übersetzungsoberflächen, die es den Benutzern ermöglichten, die übersetzten Texte zu aktualisieren, aber diese benötigten jeweils nur zwei Sprachen (die lokale und die Standardsprache). Ich kann mir vorstellen, dass dies dem am nächsten kommt, worüber Sie sprechen. Ich vermute, dass Sie für jede übersetzbare Eigenschaft untergeordnete Sammlungen mit allen möglichen Übersetzungen in der Sammlung haben würden. Dies käme wahrscheinlich der zweiten Lösung aus dem dritten Artikel, den Sie verlinkt haben, am nächsten. Natürlich, an dieser Stelle müssten Sie auch sehen, wenn Sie eager/lazy Laden usw. wollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X