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

时间:2021-10-30 11:31:32

I have a bunch of C# classes which are inheriting a number of properties from an abstract base class. All of the types are mapped to a database model using Fluent NHibernate, and all of the property definitions use automatic getters and setters (the standard "get; set;" syntax). I recently found a need to provide a specific implementation for one of the accessor methods for a base type property on one of my derived types. So I created an explicit backing field for the base class property:

我有一堆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; } }

    ...

}

And then defined the specific getter logic for the "active" property in the derived type definition:

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

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

When I fire up the project, though, NHibernate throws an exception:

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

An exception of type 'System.InvalidOperationException' occurred in FluentNHibernate.dll but was not handled in user code. Additional information: Tried to add property 'active' when already added.

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

I'm guessing this has something to do with NHibernate needing to provide it's own override for the property definitions (hence why it requires the properties be declared virtual in the first place), but I'm not all that NHibernate savvy. That being the case, I'm happy to provide any other details, but don't really know what else is relevant. Is there an obvious reason why this can't work? If so, is there a simple workaround?

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

1 个解决方案

#1


0  

I am not exactly sure about the origin of your problem, but, trying to answer your question:

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

  1. NHibernate needs all properties to be virtual to allow then to be lazy-loaded because it creates a proxy type of your entity type (which is an extension of your class). It needs them to be virtual so it can override them and inject a new behavior in it (fill them with the database value);
  2. NHibernate需要所有属性都是虚拟的,以允许延迟加载,因为它创建了实体类型的代理类型(这是类的扩展)。它需要它们是虚拟的,因此它可以覆盖它们并在其中注入新的行为(用数据库值填充它们);

  3. You do can map non-public properties and fields, but you would have to do this explicitly, follows an example on how to do it with FluentNHibernate.
  4. 您可以映射非公共属性和字段,但您必须明确地执行此操作,请按照如何使用FluentNHibernate执行此操作的示例。

Mapping a private property or field:

映射私有财产或字段:

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

Now a suggestion to try to solve your problem: you can hide the property on your extended class using the new keyword (the property still needs to be virtual).

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

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

#1


0  

I am not exactly sure about the origin of your problem, but, trying to answer your question:

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

  1. NHibernate needs all properties to be virtual to allow then to be lazy-loaded because it creates a proxy type of your entity type (which is an extension of your class). It needs them to be virtual so it can override them and inject a new behavior in it (fill them with the database value);
  2. NHibernate需要所有属性都是虚拟的,以允许延迟加载,因为它创建了实体类型的代理类型(这是类的扩展)。它需要它们是虚拟的,因此它可以覆盖它们并在其中注入新的行为(用数据库值填充它们);

  3. You do can map non-public properties and fields, but you would have to do this explicitly, follows an example on how to do it with FluentNHibernate.
  4. 您可以映射非公共属性和字段,但您必须明确地执行此操作,请按照如何使用FluentNHibernate执行此操作的示例。

Mapping a private property or field:

映射私有财产或字段:

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

Now a suggestion to try to solve your problem: you can hide the property on your extended class using the new keyword (the property still needs to be virtual).

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

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