使用 Fluent NHibernate 映射没有 setter 的只读属性

发布于 2024-10-01 01:20:34 字数 1128 浏览 3 评论 0原文

我有一个看起来像这样的域类。我希望 NHibernate 在插入/更新时保存 LastUpdate 的当前值,以便我可以在查询中使用它,但在检索 Foo 时忽略它code> 从数据库中获取,并让对象本身在我实际访问它时重新计算值。

public class Foo {
    public DateTime LastUpdate {
        get {
            /* Complex logic to determine last update by inspecting History */
            return value;
        }
    }
    public IEnumerable<History> History { get; set; }
    /* etc. */
}

我的 Foo 映射如下所示:

public class FooMap : ClassMap<Foo> {
    Map(x => x.LastUpdate)
        .ReadOnly();
    HasMany(x => x.History);
    // etc...
}

我认为 ReadOnly() 是我想要实现的目标,但是当我尝试创建 SessionFactory 时,出现以下异常:

错误:FluentNHibernate.Cfg.FluentConfigurationException:创建 SessionFactory 时使用了无效或不完整的配置。检查 PotentialReasons 集合和 InnerException 了解更多详细信息。
---> NHibernate.PropertyNotFoundException:无法在类“Foo”中找到属性“LastUpdate”的设置器。

该属性没有设置器,因为不应设置它,而只能读取ReadOnly() 在这里做的事情正确吗?如果没有,那又怎样?

(NHibernate v3.0b1、Fluent NHibernate v1.1)

I have a domain class that looks like this. I want NHibernate to save the current value of LastUpdate when inserting/updating so that I can use it in queries, but to ignore it when retrieving a Foo from the database and let the object itself recalculate the value when I actually access it.

public class Foo {
    public DateTime LastUpdate {
        get {
            /* Complex logic to determine last update by inspecting History */
            return value;
        }
    }
    public IEnumerable<History> History { get; set; }
    /* etc. */
}

My mapping for Foo looks like this:

public class FooMap : ClassMap<Foo> {
    Map(x => x.LastUpdate)
        .ReadOnly();
    HasMany(x => x.History);
    // etc...
}

I thought that ReadOnly() was what I wanted to accomplish this, but when I try to create a SessionFactory I get the following exception:

Error: FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
---> NHibernate.PropertyNotFoundException: Could not find a setter for property 'LastUpdate' in class 'Foo'.

The property doesn't have a setter because it shouldn't be set, only read from. Is ReadOnly() the correct thing to do here? If not, what?

(NHibernate v3.0b1, Fluent NHibernate v1.1)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-柠檬树下少年和吉他 2024-10-08 01:20:34

ReadOnly 指示 Fluent NHibernate 不查找此属性的更改,这并不等同于编译器世界中的只读属性。在 NHibernate 看来,您的属性不是只读的,因为您希望从数据库中填充它。您需要做的是告诉 NHibernate 它应该通过与属性同名(小写)的私有字段来访问该属性的值。

Map(x => x.LastUpdate)
  .Access.Field();

使用 Field 有多种替代方法,您使用哪一种取决于您如何命名私有字段。

ReadOnly instructs Fluent NHibernate to not look for changes on this property, this does not equate to a read-only property in compiler-world. Your property isn't read-only in NHibernate's eyes because you're expecting it to be populated from your database. What you need to do is tell NHibernate that it should access the value of that property through a private field with the same name (lowercased) as the property.

Map(x => x.LastUpdate)
  .Access.Field();

There are several alternatives to using Field, which one you use will depend on how you name your private fields.

苦笑流年记忆 2024-10-08 01:20:34

就NHibernate而言,你可以映射到一个字段,即成员变量,这样NHibernate就可以直接访问成员变量。所以你可以创建一个类似_lastUpdate这样的可以直接映射的成员变量。 Nhibernate 现在将有一个可供使用的变量,您可以在 getter 中单独控制该值,因为 NHibernate 将不再使用属性 getter。它会保存该值,并检索它,但检索到的值应该不重要,因为一旦您通过 getter 访问,您就可以重新计算它。对于没有 getter 或 setter 的私有变量也是如此。

在常规 hbm 中,您只需映射 access=field。每个人都这样做。显然Fluent并不简单。我不使用 Fluent ...

编辑...

找到您的版本中似乎总是移动的用于映射私有支持字段的目标并使用它...

As far as NHibernate goes, you can map to a field, i.e member variable so Nhibernate can access the member variable directly. So you can create a member variable like _lastUpdate that can be mapped directly. Nhibernate will now have a variable to use and you can control the value separately in your getter because NHibernate will no longer use the property getter. It will save the value, and retrieve it too, but the retrieved value should not matter because as soon as you access through your getter you can recalculate it. Ditto for private variables with no getters or setters.

In a regular hbm you would just map access=field. Everyone does it. Apparently Fluent is not a simple. I don't use Fluent ...

EDIT ...

find whatever the seemingly always moving target for mapping private backing fields is in your version and use that ...

三岁铭 2024-10-08 01:20:34

只需向您的类添加一个空的私有 setter:

        private set { }

我还添加一个属性和注释来记录我的意图(并使 ReSharper 满意):

        [UsedImplicitly]
        // ReSharper disable once ValueParameterNotUsed
        private set { }

Just add an empty private setter to your class:

        private set { }

I also add an attribute and a comment to document my intent (and make ReSharper happy):

        [UsedImplicitly]
        // ReSharper disable once ValueParameterNotUsed
        private set { }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文