流畅的NHibernate和计算属性

时间:2010-03-05 13:22:30

标签: fluent-nhibernate nhibernate-mapping automapping

我正在使用Fluent NHibernate,并自动映射类。

我在

行的类中有一个计算属性
public virtual DateTime? LastActionTimeStamp
{
    get {
        return Actions.Count == 0 ? null : Actions.OrderByDescending(
            a => a.TimeStamp).ElementAt(0).TimeStamp;
    }
}

这未与其他属性进行映射,因此我无法在ICriteria限制中使用它。我添加了一个空的setter(因为我在某处读到这样做会将它包含在映射中,它确实如此),但现在我收到了一个N​​Hibernate错误:

  

无法执行查询...无效的列名称'LastActionTimeStamp'。

所以我的问题是:如何告诉Fluent NHibernate告诉NHibernate忽略该属性的数据库,但仍然从属性get返回计算值?

3 个答案:

答案 0 :(得分:2)

您可以将公式与属性相关联,并使用该公式代替c#代码。 e.g。

属性:

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

公式:

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

然后您可以照常在表达式中使用PostCount。请记住在FluentMapping中的属性上设置访问修饰符。不确定Fluent支持什么,但我找到的用于法线贴图的选项是:

* 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

可能最好查看官方列表Access Strategies的NHibernate文档,以便将访问策略与命名策略结合起来,例如: “field.lowercase下划线”

答案 1 :(得分:1)

我不确定你能用NHibernate做到这一点,但我可能错了。 NHibernate将您的标准转换为SQL,因此该属性不可用于查询(它不在数据库中!)。

但是,如果我错了(这很常见),你应该可以用覆盖来映射它。

在自动化设置中,创建一个override并使用Access属性显式映射该属性,告诉NHibernate如何对待它。

这样的事情:

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

答案 2 :(得分:1)

您也可以覆盖映射并忽略该属性:

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