Component Properties

Eine der vielen Möglichkeiten von NHibernate sind Component Properties.

Das sind Klassen die mehrere Properties zusammenfassen, die dann wiederrum als Property in anderen Klassen verwendet werden können. Das ist vor allem dann sinnvoll, wenn es mehrere Entities/Tabellen gibt, die die gleichen Properties/Spalten beeinhalten.
Ich benutze das sehr gerne für Spalten die Änderungs- oder Löschinformationen o.ä. abzulegen.

Wir starten mit einer einfachen Klasse: Primary Key, zwei Strings, und besagte Component Property. Natürlich nur mit der minimalen Attributierung. Hervorgehoben ist die ComponentProperty, die gleich noch definiert wird.

[NHibernate.Mapping.Attributes.Class]
 public class Employee
 {
  public Employee()
  {
    DeletedInformation = new DeletedComponent();
  }

 [NHibernate.Mapping.Attributes.Id(TypeType = typeof(Int64), Name = "Id")]
 [NHibernate.Mapping.Attributes.Generator(Class = "native")]
 public virtual long Id { get; set; }

 [NHibernate.Mapping.Attributes.Property]
 public virtual string Firstname { get; set; }

 [NHibernate.Mapping.Attributes.Property]
 public virtual string Lastname { get; set; }

 [NHibernate.Mapping.Attributes.ComponentProperty]
 public virtual DeletedComponent DeletedInformation { get; set; }
 }

Und hier die Definition der Komponente, bestehend aus zwei Nullable Properties. Diese Komponente lässt sich nun in jeder Klasse als Property hinzufügen, und erweitert deren Datenbanktabelle um zwei Spalten (siehe Create Statement). Am einfachsten funktioniert es, wenn eine gemeinsame Oberklasse besteht, in der die Property definiert wird.


[NHibernate.Mapping.Attributes.Component]
public class DeletedComponent
{
[NHibernate.Mapping.Attributes.Property]
public DateTime? DeletedOn{ get; set; }

[NHibernate.Mapping.Attributes.Property]
public string UserName { get; set; }
}

Aus diesen beiden Klassen lässt sich nun folgendes Create Statement generieren . Hervorgehoben ist wieder die Component-Property.

create table Employee (
Id INT IDENTITY NOT NULL,
Firstname NVARCHAR(255) null,
Lastname NVARCHAR(255) null,
DeletedOn DATETIME null,
UserName NVARCHAR(255) null,
primary key (Id));

Fertig!

Auf eins möchte ich hinweisen.
Im folgenden Programm wird ein Employee erzeugt, abgespeichert und sofort wieder geladen.


Employee emp = new Employee();
 emp.Firstname = "Heinz";
 emp.Lastname = "Huber";
 emp.Save();

 emp = Employee.GetByPK(emp.Id);
 if (emp.DeletedInformation == null)
 throw new NullReferenceException();

Da die beiden Properties der Komponente nicht gefüllt waren, ist jetzt die ganze DeletedInformation-Property im Employee null. Und das obwohl der Konstruktor in der Employee Klasse eben genau das verhindern sollte.
Wer das nicht haben möchte (z.B. ich) ändert einfach die Spaltendefinition so, dass Default-Werte abgespeichert werden :

[NHibernate.Mapping.Attributes.Component]
    public class DeletedComponent
    {
        public DeletedComponent()
        {
            DeletedOn = DateTime.MaxValue;
        }

        [NHibernate.Mapping.Attributes.Property]
        public DateTime DeletedOn { get; set; }

        [NHibernate.Mapping.Attributes.Property]
        public string UserName { get; set; }
    }
Veröffentlicht unter Allgemein | Kommentare deaktiviert für Component Properties

SQLite und NHibernate

Nicht immer hat man in den Projekten die Möglichkeit einen großen SQL Server oder Oracle zu benutzen.
Für diese Fälle gibt es das ganze eine Nummer kleiner: SQLite.

Das funktioniert ganz ohne Serverdienste, die Datenbank besteht aus einer Datei. Natürlich hat diese Einfachheit auch seine Einschränkungen, die auf der Hersteller Seite dokumentiert sind (Limitations).

Nun gilt es SQLite mit NHibernate zusammen zum Laufen zu bringen.
Der erste Treffer bei Google fördert diesen Link aus dem Jboss Wiki zutage, der auch schon die wichtigsten Konfigurationsdetails liefert :

...
<property name="connection.provider"> NHibernate.Connection.DriverConnectionProvider </property>
<property name="connection.driver_class"> NHibernate.Driver.SQLiteDriver </property>
<property name="connection.connection_string"> Data Source=sqlite.db3;Version=3 </property>
<property name="dialect"> NHibernate.Dialect.SQLiteDialect </property>
<property name="query.substitutions"> true=1;false=0 </property>
...

Leider ist der Link zu den Treibern auf Sourceforge wohl schon veraltet, bzw das Projekt wird nicht mehr gepflegt.

Dieser Link ist der richtige, und führt auch zu einem gepflegten Projekt. Also einfach die Dateien herunterladen, und die System.Data.SQLite.DLL ins Projekt einbinden.

Die Konfiguration wird noch geringfügig modifiziert:

...
<property name="connection.provider"> NHibernate.Connection.DriverConnectionProvider </property>
<property name="connection.driver_class"> NHibernate.Driver.SQLite20Driver </property>
<property name="connection.connection_string"> Data Source=sqlite.db3;Version=3 </property>
<property name="dialect"> NHibernate.Dialect.SQLiteDialect </property>
...

Als Datenbankdatei reicht es eine leere Datei mit dem entsprechenden Namen zu erzeugen – und es kann losgehen.

Veröffentlicht unter Allgemein | Kommentare deaktiviert für SQLite und NHibernate

Hallo und Willkommen!

Willkommen hier bei meinem ersten Blogpost.

Ich bin freiberuflicher Softwareentwickler im Bereich .Net und möchte hier über verschiedene Themen der Softwareentwicklung schreiben. Vor allem beschächtige ich mich mit .Net, ORM und Business Intelligence.

Ein bischen kämpfe ich noch etwas mit WordPress – aber das wird sicher noch 🙂

Ich freue mich auf eure Kommentare!

Veröffentlicht unter Allgemein | Kommentare deaktiviert für Hallo und Willkommen!