Frage

Ich arbeite an einem Problem, in dem ich eine Reihe von Entitäten habe, von denen jede eine entsprechende Ein-zu-Viele-Übersetzungs-Tabelle hat, in der die lokalisierten Versionen der Felder von Entity angegeben sind. (All dies ist ein Legacy -Schema, auf dem ich eine Karte hinzufüge). Zum Beispiel:

  • Vorfall
    • ICH WÜRDE
  • EventTranslation
    • EventId
    • Sprache
    • Titel
    • andere Felder

Wenn ich meine Informationen auf Griechisch rendern würde, würde ich mich den beiden Tabellen anschließen und Sprache = 'Griechisch' angeben und alles richtige Zeug haben.

Ich versuche, Mixins auf dem Fliege zu erstellen, die die richtigen Daten direkt in ein einzelnes Objekt einbeziehen und dies als Ergebnis von Abfragen zurückgeben, also wie folgt:

var someEvent = session.CreateCriteria<Event>().SetMaxResults(1).UniqueResult<IEvent>();
Console.WriteLine(someEvent.Title);

Dazu versuche ich, einen Nhibernate -Interceptor einzurichten, um DynamicProxy -Mixins zu erstellen. Außer dass es nicht funktioniert und ich nicht weiß warum. Hier ist das Setup, so am besten ich es vereinfachen konnte.

Hier ist Ereignis:

class Event : IEventEntity {
   //ID and props here
   public IList Translations {get; set;}
}

IEvenEntity Hat auch einen Getter und Setter für die Liste. Es gibt auch eine EventTranslation Klasse, die super einfach ist und implementiert IEventTranslation auf die offensichtlichste Weise möglich.

Die fließende Karte für das Ereignis:

class EventMap : ClassMap<Event>{
  //obvious ID and properties stuff here...
  HasMany<EventTranslation>(x => x.Translations);
}

Funktioniert von selbst einwandfrei-ich kann nach Ereignissen abfragen und zu ihren Übersetzungen navigieren. Ich bin mir ziemlich sicher, dass die Zuordnung gut ist.

Ich habe die Form meines Interceptor -Sachen auf eine sehr coole gestützt führen von krzysztof koźmic für etwas, das etwas miteinander verwandt ist. Zuerst habe ich ein Superinter -Face erstellt, das ich mit einem dynamischen Proxy implementieren werde:

public interface IEvent : IEventEntity, IEventTranslation{}

Hier ist mein NH -Interceptor. Offensichtlich hacke ich wie verrückt:

public class EventInterceptor : NHibernate.EmptyInterceptor
{
    private readonly static ProxyGenerator gen = new ProxyGenerator();

    public override object Instantiate(string clazz, NHibernate.EntityMode entityMode, object id)
    {
           var mixin = gen.CreateClassProxy(typeof(object), new[] { typeof(IEvent) }, new DynInterceptor());
                    //would also need to set the identifier here
            return mixin;
    }
}

Wo DynInterceptor ein Interceptor ist, der tatsächlich die Arbeit in die Beziehungsbeutel einfließt, die richtige Übersetzung erhalten und den richtigen Wert zurückgibt. Die Details sind nicht zu relevant, weil es nie aufgerufen wird.

Nachdem ich den NH -Interceptor zusammengebunden habe, sehe ich, dass er läuft, und in der Tat bringt NH die Besetzung dazu IEvent Richtig (dh der Stellvertreter wird zumindest erstellt). Aber aus irgendeinem Grund verkleinert es die Feuchtigkeit der Entität vollständig:

Unhandled Exception: NHibernate.PropertyAccessException: could not set a property value by reflection setter of Event.Translations ---> System.Reflection.TargetException: Object does not match target type.
   at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke
Attr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisib
ilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke
Attr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, B
indingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, O
bject[] index)
   at NHibernate.Properties.BasicPropertyAccessor.BasicSetter.Set(Object target,
 Object value) in C:\thirdparty\NHibernate\src\NHibernate\Properties\BasicProper
tyAccessor.cs:line 304

Es sieht für mich aus, dass es nicht funktioniert, weil NH Reflection verwendet, um die Eigenschaft festzulegen, aber der Zieltyp ist natürlich falsch, weil ich einen IEVENT gegen das Ereignis eingetauscht habe. Gibt es eine Möglichkeit, dies umzugehen?

Gibt es für den grundlegenden Ansatz eine bessere Möglichkeit, dies in NH zu tun?

War es hilfreich?

Lösung

OK, wie kompliziert ich diese Frage gestellt habe, stellt sich heraus, dass es ziemlich einfach ist, und wenn ich genug gewusst habe, hätte ich die Frage als "Wie kann ich ein Objekt dynamisch eine andere Schnittstelle implementieren, ohne ihren Typ zu verlieren? ". Die Antwort ist, ein Ziel zu liefern, wie in

Type type = Type.GetType(clazz, false);
var mixin = (Event)gen.CreateClassProxy(type, new[] { typeof(IEvent) }, new DynInterceptor());

Andere Tipps

Ich bin mir nicht sicher, aber ich denke, Sie sollten einen Filter in Kombination mit einem EventListener verwenden, um das gewünschte Ergebnis zu erhalten. Wenn Sie einen Filter in Ihrer Sprachtabelle festlegen und mit einem EventListener den Filter vor den Ereignissen aktivieren, die Sie mit Filtern aktivieren möchten, erhalten Sie möglicherweise das gewünschte Verhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top