2015-01-13 12 views
3

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

public abstract class BaseEntity : IBaseEntity 
{ 
    protected bool active_field; 

    ... 

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

    ... 

} 

然后定义的特定的吸气剂逻辑在派生类型定义中的“活跃”属性:

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的精明。既然如此,我很乐意提供任何其他细节,但不知道还有什么相关的。有没有明显的原因,为什么这不起作用?如果是这样,是否有一个简单的解决方法?

+0

如果您为另一个非公有虚拟属性创建'active'非虚拟包装怎么办? 'NHibernate'会填充非公有财产吗? –

+0

所以你有'ClassMap '显式映射或使用Automapping?此外,覆盖是有缺陷的,因为即使active_field值没有改变,活动值也会改变。更好地区分'IsActivated' /'IsEnabled'(持续)和'IsActive' – Firo

+0

这是使用自动映射。我不确定你在后半部分的含义。所有派生自BaseEntity的类型都可以通过将活动位设置为0来“软删除”。最近我添加了一些BaseEntity类型,它们有过期日期,并且我有一个完整的代码库,它已经明确地检查了活动字段在检查数据时。当然,我的目标是能够查看一个BaseEntity类型,如果过期已过,则将过期属性视为不活动,而无需在已检查活动字段的位置手动检查它。那是不好的形式? –

回答

0

我并不完全确定你的问题的根源,但是,试图回答你的问题:

  1. 的NHibernate需要的所有属性,因为它创建一个代理,是虚拟的,允许再偷懒装你的实体类型(这是你的类的扩展)。它需要它们是虚拟的,因此它可以覆盖它们并在其中注入新的行为(用数据库值填充它们);
  2. 您可以映射非公共属性和字段,但您必须明确地执行此操作,请遵循有关如何使用FluentNHibernate执行此操作的示例。

映射一个私有属性或字段:

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

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

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