【问题标题】:Overriding the base behavior of a C# property accessor method with Fluent NHibernate使用 Fluent NHibernate 覆盖 C# 属性访问器方法的基本行为
【发布时间】:2015-01-13 21:29:19
【问题描述】:

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

【问题讨论】:

  • 如果您将active 非虚拟包装到另一个非公共虚拟财产怎么办? NHibernate会填非公共财产吗?
  • 所以你有ClassMap&lt;T&gt;的显式映射或使用自动映射?覆盖也是有缺陷的,因为在持久化时,即使 active_field 值没有改变,活动值也会改变。更好地区分IsActivated/IsEnabled(持续)和IsActive
  • 这是使用自动映射。我不确定你在后半部分的意思。从 BaseEntity 派生的所有类型都可以通过将活动位设置为 0 来“软删除”。我最近添加了一些具有到期日期的 BaseEntity 类型,并且我有一个已经明确检查活动的完整代码库检查数据时的字段。当然,我的目标是能够在过期已过时将具有 Expiration 属性的 BaseEntity 类型视为不活动,而无需在我已经检查活动字段的地方手动检查它。这是不好的形式吗?
  • TS,据我所知,我认为 NHibernate 不会填充非公共属性。

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


【解决方案1】:

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

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

映射私有属性或字段:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 2019-10-13
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    相关资源
    最近更新 更多