NHibernate hinzufügen unmapped Spalte in Interceptor
-
05-07-2019 - |
Frage
Ich versuche, ein zugeordnetes Einheit mit NHibernate zu speichern, aber mein Einsatz in der Datenbank schlägt fehl, da die zugrunde liegende Tabelle eine Spalte, die NULL-Werte nicht zulässt, und ist in meinen Domain-Objekt nicht zugeordnet. Der Grund ist es nicht abgebildet ist, weil die betreffende Spalte eine Anwendung Erbe unterstützt und hat keine Relevanz für meine Anwendung -. So würde Ich mag nicht meine Einheit mit dem Erbe Eigenschaft verschmutze
Ich weiß, dass ich ein eigenes Feld in meiner Klasse verwenden könnte - aber das fühlt sich immer noch böse auf mich. Ich habe lesen , dass ich ein NHibernate Interceptor verwenden kann und die OnSave () -Methode außer Kraft setzen hinzufügen in der neuen Spalte direkt vor meiner Einheit wird gespeichert. Dies erweist sich als schwierig, da ich nicht aus arbeiten kann, wie eine Instanz von Nhibernate.type.IType auf den Typen Parameter meiner Abfangjäger OnSave hinzuzufügen.
Meine Entity sieht in etwa wie folgt aus:
public class Client
{
public virtual int Id { get; set; }
public virtual int ParentId { get; set; }
public virtual string Name { get; set; }
public virtual string Phone { get; set; }
public virtual string Email { get; set; }
public virtual string Url { get; set; }
}
Und mein Interceptor
public class ClientInterceptor : EmptyInterceptor
{
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
{
if (entity is Client)
{
/*
manually add the COM_HOLD column to the Client entity
*/
List<string> pn_list = propertyNames.ToList();
pn_list.Add("COM_HOLD");
propertyNames = pn_list.ToArray();
List<Object> _state = state.ToList();
_state.Add(false);
state = _state.ToArray();
//somehow add an IType to types param ??
}
return base.OnSave(entity, id, state, propertyNames, types);
}
}
Hat jemand irgendwelche Ideen, wie man dies richtig zu tun?
Lösung
Ich kann nicht sicher sagen, da ich eigentlich noch nie getan (wie Stefan, ziehe ich es auch nur eine private Eigenschaft hinzufügen), aber können Sie nur eine NHibernate.Type.BooleanType
zum types
Array hinzufügen?
List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();
Bearbeiten
Ja, es sieht aus wie Sie richtig sind; die Typen haben einen internal
Konstruktor. Ich habe einige graben und fand TypeFactory
:
Anwendungen sollten statisch verwenden Methoden und Konstanten auf NHibernate.NHibernateUtil, wenn die Standard IType ist gut genug. Zum Beispiel kann nur die Type sollte verwendet werden, wenn der String eine Länge von 300 statt 255. An diesem Punkt haben muss NHibernate.String nicht bekommen Sie IType thecorrect. Verwenden Sie stattdessen TypeFactory.GetString (300) und halten ein lokale Variable, die einen Verweis auf die IType hält.
So wie es aussieht, was Sie wollen NHibernateUtil
ist:
Ermöglicht den Zugriff auf das gesamte Spektrum der NHibernate eingebauten Typen. Ich tippe Instanzen können verwendet werden, um Werte zu binden abfragen Parameter. Auch eine Fabrik für neuen Blobs und Clobs.
typeList.Add(NHibernateUtil.Boolean);
Andere Tipps
Ich persönlich würde es nicht tun, so kompliziert. Ich würde das Privateigentum hinzufügen und einen Standardwert zuweisen - fertig. Sie könnten auch einen Standardwert in der Datenbank berücksichtigen, dann brauchen Sie nichts anderes zu tun.
private virtual bool COM_HOLD
{
get { return false; }
set { /* make NH happy */ }
}
Bevor Sie einen Abfangjäger für das Schreiben würde ich erwägen, einen Datenbank-Trigger zu schreiben. Denn mit dem Interceptor Sie „verschmutzen“ Ihre Datenzugriffsschicht. Es könnte machen es instabil und Sie könnte haben seltsame Probleme.