Как построить и отобразить класс сущности, производный от системного класса, со свойствами и методами, которые не являются виртуальными? - PullRequest
0 голосов
/ 27 июля 2011

У меня есть следующая модель.

public class DataValue : Collection<DataValue>
{
  private List<DataValue> _values;
  public virtual int Id { get; set; }
  public virtual string Value { get; set; }

  protected override void InsertItem(int index, DataValue item)
  {
    base.InsertItem(index, item);
    this._values.Add(item._value);
  }
}

Модель наследует класс Collection. Это необходимо для моей доменной модели, но это не критично для NHibernate. Таким образом, каждый экземпляр этого класса представляет собой одну строку в базе данных, но он может содержать другие значения DataValues, которые инициализируются другими частями программного обеспечения. Я отображаю это так (свободно)

public DataValueMap()
{
  Id(x => x.Id);
  Map(x => x.Value);
}

Теперь, когда NHibernate пытается создать прокси-класс, он выдает следующую ошибку

NHibernate.InvalidProxyTypeException: NHibernate.InvalidProxyTypeException:
 The following types may not be used as proxies:
 DataValue: method get_Count should be 'public/protected virtual' or 'protected internal virtual'
 DataValue: method get_Item should be 'public/protected virtual' or 'protected internal virtual'
 DataValue: method set_Item should be 'public/protected virtual' or 'protected internal virtual'
 DataValue: method Add should be 'public/protected virtual' or 'protected internal virtual'
 etc... basically all the Collection methods and properties

Это, конечно, связано с тем, что методы и свойства Collection не являются виртуальными. Как мне решить эту проблему?

  • DataValue должен загружаться с отложенной загрузкой, поэтому отключение LazyLoad не вариант.
  • Я мог бы реализовать IList и не наследовать Collection, но это могло бы загромождать класс и наследовать Collection, по моему мнению, чище.

Ответы [ 2 ]

0 голосов
/ 27 июля 2011

Каждый раз, когда задействованы прокси, вы должны иметь все открытые свойства и методы, помеченные как виртуальные.Это связано с тем, что для возврата прокси сопоставленного класса nhibernate наследует объект прокси от вашего объекта и добавляет к нему магию ленивой загрузки.Поэтому каждое общедоступное свойство в отображаемом классе, загружаемое с отложенной загрузкой, должно быть виртуальным.Так как вы не можете управлять свойствами, которые вы непосредственно наследуете от Collection (я не уверен в причинах окружающего кода, почему вы это делаете), вам нужно будет рассмотреть возможность реорганизации кода, чтобы пропустить это требование, или, возможно, попытаться наследовать от ICollection.и реализация методов напрямую, а не наследование напрямую от Collection (вероятно, лучший способ).

0 голосов
/ 27 июля 2011

проверка может быть отключена:

public class CustomProxyFactoryFactory : IProxyFactoryFactory
{
    NHibernate.ByteCode.Castle.ProxyFactoryFactory internalfactory = ...;

    public IProxyFactory BuildProxyFactory()
    {
        return internalfactory.BuildProxyFactory();
    }

    public bool IsInstrumented(Type entityClass)
    {
        return true;
    }

    public bool IsProxy(object entity)
    {
        return (entity is INHibernateProxy);
    }     

    public IProxyValidator ProxyValidator
    {
        get { return new CustomProxyValidator(); }
    }
}

public class CustomProxyValidator : DynProxyTypeValidator
{
    private const bool iDontCare = true;

    protected override bool CheckMethodIsVirtual(Type type)
    {
        return iDontCare;
    }
}

с использованием fluentnhibernate

Fluently.Configure()
    .Database(xxxConfiguration.Standard
        .ProxyFactoryFactory<CustomProxyFactoryFactory>())

Я не уверен, что Castle может обрабатывать не виртуальные методы

...