流畅的 NHibernate 和计算属性

发布于 2024-08-23 18:06:38 字数 552 浏览 9 评论 0原文

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

我在一个类中有一个计算属性,类似于

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

This 没有与其余属性映射,因此我无法在 ICriteria 限制中使用它。我添加了一个空的设置器(正如我在某处读到的那样,这样做会将其包含在映射中,它确实这样做了),但现在我收到了 NHibernate 错误:

无法执行查询...列名“LastActionTimeStamp”无效。

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

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?

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

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

发布评论

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

评论(3

花开雨落又逢春i 2024-08-30 18:06:38

您可以将公式与属性关联起来,并使用它来代替 C# 代码。例如

属性:

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

最好查看 NHibernate 文档以获取官方列表 访问策略,以便将访问策略与命名策略结合起来,例如“field.lowercase-underscore”

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"

仅此而已 2024-08-30 18:06:38

我不确定 NHibernate 是否可以做到这一点,但我可能是错的。 NHibernate 将您的条件转换为 SQL,因此该属性将无法用于查询(它不在数据库中!)。

但是,如果我错了(而且这种情况很常见),您应该能够使用覆盖来映射它。

在您的自动映射设置中,创建一个 覆盖 并使用 Access< 显式映射该属性/code> 属性告诉 NHibernate 如何处理它。

像这样的东西:

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

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();
  });
暖阳 2024-08-30 18:06:38

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

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

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);
        }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文