通过 NHibernate 检索/保存链接到其他实体的日志条目的最佳方法是什么?

发布于 2024-11-02 07:15:02 字数 1361 浏览 3 评论 0原文

免责声明:我概述了简化的图片以强调我的问题的要点。

我正在开发的应用程序维护一组资源。我们在 NHibernate 中有一个相应的表和映射实体。每个资源由整数 id 标识。我们还有用户表和相应的实体来维护用户配置文件。

我们需要记录用户对应用程序的访问并检索访问历史记录。对于存储库类,我们必须引入 2 个方法:

  1. IEnumerable GetUserLog(User user) 用于按日期降序检索用户访问历史记录,以及
  2. void WriteLogEntry(User user, Resource resource) 用于写入新条目

我尝试将 LogEntry 实体简单地定义为以下:

public class LogEntry
{
     public virtual User User {get; set;}
     public virtual Resource Resource {get; set;}
     public virtual DateTime Date {get; set;}
}

并像平常一样使用 Fluent NHibernate 映射它。要检索/更新日志条目,我们可以简单地使用

Session.Query<LogEntry>().Where(entry => entry.User = currentUser).OrderByDesc(entry => entry.Date)
Session.Save(new LogEntry() {
    User = currentUser,
    Resource = resource,
    Date = DateTime.Now
})

这是我们处理此问题的最方便的方法。

问题 问题是 NHibernate 需要 id 映射。我们必须在这里使用复合 id,唯一的选择是映射用户、资源和日期列,因为只有这种组合才能提供唯一性。另外,在复合 id 的情况下,我们必须重写 Equals 和 GetHashCode,对于这样一个简单的任务来说,所有这些似乎都太过分了。另一个问题是id字段不能使用延迟加载,而且也太多了。我们不想提前加载所有相关的资源实体。

另一种可能的解决方案是定义普通类,而不是实体,然后使用 SetResultTransformer(Transformers.AliasToBean()) 检索结果。在这种情况下,我们必须手动构建查询,手动检索相关实体,这样通常并不比处理原始连接更好。

我想询问专家的意见,因为我相信周围的人有类似的经历并且可以提供帮助。提前致谢。

PS 这是使用 NHibernate 3 (+ Fluent) 的 ASP.NET MVC 应用程序。日志信息将用于显示用户最近访问的 5-10 个资源。

Disclaimer: I'm outlining simplified picture to emphasize main point of my question.

The application I'm working on maintains a set of resources. We have a corresponding table and mapped entity in NHibernate. Each resource identified by integer id. Also we have user table and corresponding entity to maintain user profiles.

We need to log user accesses to the application and retrieve access history. For repository class we have to introduce 2 methods:

  1. IEnumerable GetUserLog(User user) to retrieve user access history order by date in descending order and
  2. void WriteLogEntry(User user, Resource resource) to write new entry

I have tried to simply define LogEntry entity as following:

public class LogEntry
{
     public virtual User User {get; set;}
     public virtual Resource Resource {get; set;}
     public virtual DateTime Date {get; set;}
}

and map it using Fluent NHibernate as usually. To retrieve/update log entries we can simply use

Session.Query<LogEntry>().Where(entry => entry.User = currentUser).OrderByDesc(entry => entry.Date)
Session.Save(new LogEntry() {
    User = currentUser,
    Resource = resource,
    Date = DateTime.Now
})

This is the most convenient way to deal with this issue for us.

Problem
The problem is that NHibernate requires id mapping. We have to use composite id here and the only option is to map User, Resource and Date columns because only this combination provides uniqueness. Also in case of composite id we have to override Equals and GetHashCode and all this seems to be overkill for such a simple task. Another problem that lazy loading cannot be used for id fields and it's too much as well. We do not want to load all related Resource entities in advance.

Another possible solution is to define plain class, not entity and then use SetResultTransformer(Transformers.AliasToBean()) to retrieve results. In that case we have to construct queries manually, retrieve related entities manually and this way it's not better in general then dealing with raw connection.

I would like to ask expert opinion because I'm confident people around had similar experience and can help. Thanks in advance.

P.S. This is ASP.NET MVC application using NHibernate 3 (+ Fluent). Log information will be used to display last 5-10 resources user accessed.

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

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

发布评论

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

评论(1

冰魂雪魄 2024-11-09 07:15:02

您是否考虑过为 LogEntry 表引入 Id 字段?
许多 DBA 会推荐它,它似乎是最简单的解决方案。

have you considered introducing an Id field for LogEntry table as well?
many DBAs will recommend it and it seems like the easiest solution.

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