Смешивание в данных с боковым столом с nhibernate Interceptors и DynamicProxy

StackOverflow https://stackoverflow.com/questions/6343102

Вопрос

Я работаю над проблемой, в которой у меня есть ряд сущностей, каждая из которых имеет соответствующую таблицу переводов с одним ко многим, в которой указываются локализованные версии полей сущности. (Все это - устаревшая схема, которую я добавляю карту на вершину). Например:

  • Мероприятие
    • Я БЫ
  • EventTranslation
    • Eventid
    • Язык
    • Заголовок
    • Другие поля

Итак, если бы я собирался представить свою информацию на греческом языке, я бы присоединился к двум таблицам и указал Language = «греческий» и имел все правильные вещи.

То, что я пытаюсь сделать, это создать микшины на лету, которые напрямую включают правильные данные в один объект и возвращают это в результате запросов, так что:

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

Чтобы сделать это, я пытаюсь настроить nhibernate receptor для создания динамических микшинов. За исключением того, что это не работает, и я не знаю почему. Вот настройка, как я могу ее упростить.

Вот событие:

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

IEvenEntity Также имеет Getter и Setter для списка. Есть также EventTranslation класс, который очень прост и реализует IEventTranslation наиболее очевидным способом.

Карта бегства для события:

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

Работает прекрасно само по себе-я могу запрашивать события и перейти к их переводам. Я почти уверен, что картирование хорошее.

Я основывал форму моего перехватчика на очень крутой руководство Крзиштоф Кецмик за то, что он сделал что -то немного связанное. Во -первых, я создал суперинтерфейс, который собираюсь реализовать с помощью динамического прокси:

public interface IEvent : IEventEntity, IEventTranslation{}

Вот мой NH -перехватчик. Очевидно, я взламываюсь как сумасшедший:

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;
    }
}

Где Dyninterceptor - это перехватчик, который фактически выполняет работу по вопросам вступления в сумку в отношениях, получения правильного перевода и возврата правильной ценности. Детали не слишком актуальны, потому что их никогда не вызывается.

После завязывания в NH Interceptor я вижу, что он работает, и на самом деле NH получает актерский состав IEvent Правильно (т.е. прокси, по крайней мере, создается). Но по какой -то причине это полностью испортит увлажнение сущности:

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

Мне кажется, что это не работает, потому что NH использует отражение, чтобы установить свойство, но, конечно, целевой тип неверен, потому что я поменял IEVENT на мероприятие. Есть ли способ обойти это?

Кроме того, что касается основного подхода, есть ли лучший способ сделать это в NH?

Это было полезно?

Решение

Хорошо, так что для того, насколько сложно я задал этот вопрос, он оказывается довольно простым, и если бы я знал достаточно, я мог бы задать вопрос «как я динамически заставить объект реализовать другой интерфейс, не теряя его типа? ". Ответ заключается в том, чтобы предоставить цель, как в

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

Другие советы

Я не уверен, но я думаю, что вы должны использовать фильтр в сочетании с EventListener, чтобы получить желаемый результат. Если вы установите фильтр в своей языковой таблице и используете eventlistener, чтобы включить фильтр до событий, которые вы хотите включить фильтрацию, вы можете получить желаемое поведение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top