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; }
    }
Dieser Beitrag wurde unter Allgemein veröffentlicht. Setze ein Lesezeichen auf den Permalink.