Displaying a read-only property without using setter using Fluent NHibernate

I have a domain class that looks like this. I want NHibernate to keep the current LastUpdate value on insert / update, so that I can use it in queries, but ignore it when retrieving Foo from the database and let the object itself recount 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() is what I wanted to execute, but when I try to create a SessionFactory, I get the following exception:

Error: FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used when creating the SessionFactory. See the PotentialReasons and InnerException collection for more information.
---> NHibernate.PropertyNotFoundException: Could not find setter for property "LastUpdate" in class "Foo".

The property does not have a setter, because it should not be set, only read. Is ReadOnly() right thing here? If not, what?

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

+5
source share
3 answers

ReadOnly instructs Fluent NHibernate not to look for changes in this property; this does not mean a read-only property in the compiler world. Your property is not read-only in the eyes of NHibernate because you expect it to be completed from your database. What you need to do is tell NHibernate that it should access the value of this property through a private field with the same name (lowercase) as the property.

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

There are several alternatives to using the Field that you use will depend on how you name your private fields.

+13
source

As for NHibernate, you can map a field, i.e. a member variable, so that Nhibernate can directly access a member variable. This way you can create a member variable, such as _lastUpdate, that can be mapped directly. Nhibernate will now have a variable that you can use separately, and you can control the value separately in your getter, because NHibernate will no longer use the getter property. It will save the value and extract it, but the resulting value should not matter, because as soon as you get access through your getter, you can recalculate it. The same goes for private variables without getters or setters.

In regular hbm, you just hit the access = field. Everyone does it. Obviously, Fluent is not easy. I do not use Fluent ...

EDIT ...

find any seemingly always moving target for matching closed support fields in your version and use it ...

+2
source

Just add an empty class to your class:

  private set { } 

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

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

Source: https://habr.com/ru/post/890348/


All Articles