Fluent NHibernate and computed properties

南楼画角 提交于 2019-12-19 09:06:21

问题


I'm using Fluent NHibernate, and auto-mapping the classes.

I have a computed property in a class along the lines of

public virtual DateTime? LastActionTimeStamp
{
    get {
        return Actions.Count == 0 ? null : Actions.OrderByDescending(
            a => a.TimeStamp).ElementAt(0).TimeStamp;
    }
}

This wasn't mapped with the rest of the properties, so I couldn't use it in an ICriteria restriction. I added an empty setter (as I read somewhere that doing so would include it in the mapping, which it does), but now I'm getting an NHibernate error:

could not execute query ... Invalid column name 'LastActionTimeStamp'.

So my question is: how do I tell Fluent NHibernate to tell NHibernate to ignore the database for this property, but still return the calculated value from the property get?


回答1:


You could associate a formula with the property and use that instead of the c# code. e.g.

Property:

private int _postCount = 0;
public virtual int PostCount
{
    get
    {
        return _postCount;
    }
}

Formula:

(SELECT count(p.ID) FROM BlogPost p WHERE p.BlogID = ID and p.IsDeleted = 0)

And then you can use PostCount in your expression as usual. Remember to set the access modifier on the property in your FluentMapping. Not sure what Fluent supports but the options I have found for normal mapping are:

* property
* field
* field.camelcase
* field.camelcase-underscore
* field.pascalcase-m-underscore
* field.lowercase-underscore
* nosetter.camelcase
* nosetter.camelcase-underscore
* nosetter.pascalcase-m-underscore
* nosetter.lowercase-underscore

Probably best check out NHibernate documentation for the official list Access Strategies so you combine the access strategy with the naming strategy e.g. "field.lowercase-underscore"




回答2:


I'm not certain you can do that with NHibernate, but I could be wrong. NHibernate translates your criteria into SQL, and thus that property wouldn't be available to query with (it ain't in the db!).

However, if I'm wrong (and that's frequent), you should be able to map it with an override.

In your automapping setup, create an override and map that property explicitly using the Access property to tell NHibernate how to treat it.

Something like this:

AutoMap.AssemblyOf<YourEntity>()
  // automapping stuff
  .Override<ThatClass>(m =>
  {
    m.Map(x => x.LastActionTimeStamp)
      .Access.None();
  });



回答3:


You can also override the mapping and ignore the propery:

public class ThatClassMappingOverride : IAutoMappingOverride<ThatClass>
{
  public void Override(AutoMapping<ThatClass> mapping)
        {
            mapping.IgnoreProperty(x=> x.PropertyToIgnore);
        }
}


来源:https://stackoverflow.com/questions/2386981/fluent-nhibernate-and-computed-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!