如何构建和映射从具有非虚拟属性和方法的系统类派生的实体类?

时间:2011-07-27 09:57:39

标签: c# asp.net nhibernate nhibernate-mapping

我有以下型号。

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 :(得分:0)

可以禁用支票:

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>())

我不确定城堡是否可以处理非虚拟方法

答案 1 :(得分:0)

随时涉及代理,您必须将所有公共属性和方法标记为虚拟。这是因为为了返回映射类的代理,nhibernate从对象继承代理对象,并向其添加延迟加载魔法。因此,要延迟加载的映射类上的每个公共属性都必须是虚拟的。由于您无法控制直接从Collection继承的属性(我不确定您执行此操作的周围代码原因),因此您需要考虑重新安排代码以省略该要求,或者可能尝试继承ICollection直接实现方法而不是直接从Collection继承(可能是最好的方法)。