使用Fluent NHibernate覆盖C#属性访问器方法的基本行为

时间:2015-01-13 21:29:20

标签: c# .net nhibernate fluent-nhibernate fluent

我有一堆C#类,它们从一个抽象基类继承了许多属性。所有类型都使用Fluent NHibernate映射到数据库模型,并且所有属性定义都使用自动getter和setter(标准的“get; set;”语法)。我最近发现需要为我的一个派生类型的基本类型属性提供一个访问器方法的特定实现。所以我为基类属性创建了一个显式的支持字段:

public abstract class BaseEntity : IBaseEntity
{
    protected bool active_field;

    ...

    public virtual bool active { get { return active_field; } set { active_field = value; } }

    ...

}

然后在派生类型定义中为“active”属性定义特定的getter逻辑:

public override bool active
    {
        get { return active_field && (this.Expiration == null || this.Expiration < DateTime.Now); }
        set { active_field = value; }
    }

但是,当我启动项目时,NHibernate会抛出异常:

  

FluentNHibernate.dll中出现'System.InvalidOperationException'类型的异常,但未在用户代码中处理。   附加信息:尝试在已添加时添加属性“有效”。

我猜这与NHibernate有关,需要为属性定义提供它自己的覆盖(因此为什么它要求属性首先被声明为虚拟),但我不是那个NHibernate精明的人。既然如此,我很乐意提供任何其他细节,但不知道还有什么相关的。是否有一个明显的原因导致无法正常工作?如果是这样,有一个简单的解决方法吗?

1 个答案:

答案 0 :(得分:0)

我不确定问题的根源,但是,试着回答你的问题:

  1. NHibernate需要所有属性都是虚拟的,然后允许延迟加载,因为它创建了实体类型的代理类型(这是类的扩展)。它需要它们是虚拟的,因此它可以覆盖它们并在其中注入新的行为(用数据库值填充它们);
  2. 您可以映射非公共属性和字段,但您必须明确地执行此操作,请参阅有关如何使用FluentNHibernate执行此操作的示例。
  3. 映射私有财产或字段:

    public class EntityMap : ClassMap<Entity>
    {
        Id(e => e.Id).GeneratedBy.Identity();
        Map(Reveal.Member<Entity>("PrivatePropertyName"));
    }
    

    现在建议尝试解决您的问题:您可以使用 new 关键字隐藏扩展类的属性(该属性仍需虚拟)。

    public virtual new bool active
    {
        get { return active_field && (this.Expiration == null || this.Expiration < DateTime.Now); }
        set { active_field = value; }
    }