2009-05-05 2 views
1

Я пытаюсь сохранить преобразованный объект с помощью NHibernate, но моя вставка в базу данных завершается с ошибкой, потому что в базовой таблице есть столбец, который не разрешает NULL и НЕ отображается в моем объекте домена. Причина, по которой он не отображается, заключается в том, что рассматриваемый столбец поддерживает устаревшее приложение и не имеет никакого отношения к моему приложению - поэтому я бы не стал загрязнять мою сущность унаследованным свойством.NHibernate добавить неотображенный столбец в перехватчик

Я знаю, что могу использовать частное поле внутри своего класса, но это все еще кажется мне неприятным. У меня есть read, что я могу использовать перехватчик NHibernate и переопределить метод OnSave(), чтобы добавить в новый столбец прямо до того, как мой объект будет сохранен. Это сложно, поскольку я не могу решить, как добавить экземпляр Nhibernate.type.IType к параметрам типов OnSave моего перехватчика.

My Entity примерно выглядит следующим образом:

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

И мой перехватчик

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

Кто-нибудь есть какие-либо идеи о том, как сделать это правильно?

ответ

1

Я не могу сказать точно, так как я никогда не делал этого (например, Stefan, я также предпочитаю просто добавлять частную собственность), но можете ли вы просто добавить NHibernate.Type.BooleanType в массив types?

List<IType> typeList = types.ToList(); 
typeList.Add(new BooleanType()); 
types = typesList.ToArray(); 

EDIT

Да, похоже, вы правы; типы имеют конструктор internal. Я сделал некоторые раскопки и нашли TypeFactory:

Приложения должны использовать статические методы и константы на NHibernate.NHibernateUtil если IType по умолчанию достаточно хорошо. Например, TypeFactory должен использовать только , когда длина строки должна иметь длину 300, а не 255. В этот момент NHibernate.String не дает вам правильный IType. Вместо этого используйте TypeFactory.GetString (300) и сохраните локальную переменную , которая содержит ссылку на IType.

Так это выглядит как то, что вы хотите NHibernateUtil:

Обеспечивает доступ к полному спектру NHibernate встроенных типов. Типы типов IType могут использоваться для привязки значений к параметрам запроса. Также есть фабрика для новых Blobs и Clobs.

typeList.Add(NHibernateUtil.Boolean); 
+0

Я не боюсь - NHibernate.Type.BooleanType и все остальное в этом пространстве имен имеет частный конструктор, что делает его невозможным для обычного обычным способом. Я предполагаю, что вам нужно использовать какой-то другой NHibernate API для создания объектов. –

+0

Попробуйте NHibernateUtil.Boolean. –

+0

Спасибо, Стюарт - это сделал трюк. Я удалил частное поле из моего класса сущности, и я могу без проблем встать в таблицу. –

1

Лично я бы не сделал это так сложно. Я бы добавил частную собственность и присвоил ей значение по умолчанию - закончено. Вы также можете рассмотреть значение по умолчанию в базе данных, тогда вам не нужно ничего делать.

private virtual bool COM_HOLD 
{ 
    get { return false; } 
    set { /* make NH happy */ } 
} 

Прежде чем писать перехватчик для этого, я хотел бы написать триггер базы данных. Потому что с Interceptor вы «загрязняете» свой уровень доступа к данным. Это может сделать его неустойчивым и вы может имеют странные проблемы.

+1

Hi Stefan - спасибо за отзыв. К сожалению, я не могу изменить базу данных, поверьте мне, я бы хотел. Как я изложил в своем вопросе, мне идеально хотелось бы не добавлять свойство к моей сущности, потому что COM_HOLD ничего не значит в логике моего приложения - его просто обязательный столбец в моей таблице db. –

+0

Я понимаю, что вы имеете в виду. Я предлагаю принять самое простое решение. Частная собственность очень проста и не причиняет большого вреда. Беспокойство с перехватчиками не так просто. –

Смежные вопросы