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

使用Fluent NHibernate重写C#属性访问器方法的基本行为,c#,.net,nhibernate,fluent-nhibernate,fluent,C#,.net,Nhibernate,Fluent Nhibernate,Fluent,我有一堆C#类,它们从抽象基类继承了许多属性。所有类型都使用Fluent NHibernate映射到数据库模型,所有属性定义都使用自动getter和setter(标准的“get;set;”语法)。我最近发现需要为我的一个派生类型上的基类型属性的一个访问器方法提供一个特定的实现。因此,我为基类属性创建了一个显式支持字段: public abstract class BaseEntity : IBaseEntity { protected bool active_field; ..

我有一堆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; }
    }
public override bool active
{
获取{return active_字段&(this.Expiration==null | | this.Expiration
但是,当我启动项目时,NHibernate抛出一个异常:

FluentNHibernate.dll中发生“System.InvalidOperationException”类型的异常,但未在用户代码中处理。 其他信息:已添加属性时,尝试添加属性“活动”


我猜这与NHibernate需要为属性定义提供自己的覆盖有关(因此它首先要求属性声明为虚拟),但我并不完全了解NHibernate。在这种情况下,我很乐意提供任何其他细节,但不知道还有什么是相关的。有没有一个明显的原因可以解释为什么这不起作用?如果是这样,是否有一个简单的解决方法?

我不确定您的问题的来源,但是,尝试回答您的问题:

  • NHibernate需要所有属性都是虚拟的,以允许延迟加载,因为它创建了实体类型(是类的扩展)的代理类型。它需要它们是虚拟的,这样它就可以覆盖它们并在其中注入新的行为(用数据库值填充它们)
  • 您确实可以映射非公共属性和字段,但您必须显式地这样做,下面是一个关于如何使用FluentNHibernate进行映射的示例
  • 映射私有属性或字段:

    public class EntityMap : ClassMap<Entity>
    {
        Id(e => e.Id).GeneratedBy.Identity();
        Map(Reveal.Member<Entity>("PrivatePropertyName"));
    }
    
    公共类EntityMap:ClassMap
    {
    Id(e=>e.Id).GeneratedBy.Identity();
    地图(显示成员(“PrivatePropertyName”);
    }
    
    现在有一个解决问题的建议:您可以使用new关键字隐藏扩展类上的属性(属性仍然需要virtual

    公共虚拟新bool活动
    {
    获取{return active_字段&(this.Expiration==null | | this.Expiration
    如果将
    激活
    非虚拟包装器设置为另一个非公共虚拟财产,该怎么办?
    NHibernate
    是否会填充非公共属性?因此您可以使用
    ClassMap
    进行显式映射,或者使用自动映射?此外,覆盖也有缺陷,因为在持久化时,即使活动字段值没有更改,活动值也可能更改。更好地区分
    IsActivated
    /
    IsEnabled
    (持久化)和
    IsActivated
    这是在使用自动映射。我不知道你在后面的部分是什么意思。通过将活动位设置为0,可以“软删除”从BaseEntity派生的所有类型。我最近添加了一些有过期日期的BaseEntity类型,我有一个完整的代码库,在检查数据时已经显式地检查活动字段。当然,我的目标是,如果过期已过,则能够将具有过期属性的BaseEntity类型视为非活动,而无需在已检查活动字段的任何位置手动检查它。这是一种糟糕的形式吗?T.S.,据我所知,我不认为NHibernate会占据非公共财产。
    public virtual new bool active
    {
        get { return active_field && (this.Expiration == null || this.Expiration < DateTime.Now); }
        set { active_field = value; }
    }