0

我有一个用户可以有很多电子邮件。这是通过列表集合映射的(由用户上的 IEnumerable 电子邮件公开)。对于每个用户,其中一封电子邮件将是主要电子邮件(电子邮件上的“布尔 IsPrimary”属性)。

如何在没有 NHibernate 为用户加载每封电子邮件的情况下从用户那里获取主要电子邮件?

我有以下两个实体,每个实体都有一个对应的表

public class User
{
   private readonly IList<Email> _emails;

   public virtual int Id { get; private set; }
   public virtual IEnumerable<Email> Emails { get { return _emails; } }
   // public virtual Email PrimaryEmail { get; set; } - Possible somehow ?
}
public class Email
{
   public virtual int Id { get; private set; }
   public virtual String Address { get; set; }
   public virtual Boolean IsPrimary { get; set; }
   public virtual User User { get; set; }
}

我可以将用户上的“电子邮件 PrimaryEmail”属性等映射到以某种方式设置了“IsPrimary = 1”的电子邮件吗?也许使用 Sql 公式?一个看法 ?一对一的关系?或其他方式?

应该可以将主电子邮件更改为其他电子邮件之一,因此我想将它们全部保存在 1 个表中,只需更改 IsPrimary 属性。

使用 Sql 公式,如果我将当前主电子邮件上的 IsPrimary 属性设置为 false,然后将 PrimaryEmail 属性设置为电子邮件,是否可以使用户上的“PrimaryEmail”属性保持最新应该是新的主电子邮件并将 IsPrimary 设置为 true ?NHibernate 会跟踪 Sql 公式加载的“旧/当前”主电子邮件的更改吗?使用 SqlFormula 时,一级缓存和二级缓存呢?

我不知道它是否可以通过使用 View 工作?然后我猜电子邮件可以像组件一样映射?从 View 加载时更新电子邮件数据时它会起作用吗?

有没有更好的办法 ?

因为我在用户和电子邮件之间有双向关系,所以在许多情况下,我当然可以查询主电子邮件,然后使用电子邮件上的“用户”属性来获取用户(而不是反过来——从用户到主要电子邮件)

希望有人能帮忙?

4

2 回答 2

1

乍一看,我想我想确保 PrimaryEMail 始终是对集合中的一个 EMail 对象的引用(这样做的一种方法是让 get/set 完全在运行中)。对于像您这样的全公开设计,您必须将更改与电子邮件和/或集合上的事件处理程序挂钩。新的主要电子邮件对象(您要提升到主要的集合中的东西)将知道其父集合或用户,因此应该能够找到当前的主要对象以使其成为次要对象。

替代方法包括使 IsPrimary 不是公共集,甚至根本不公开它(email.IsPrimary 将替换为 email == user.PrimaryEMail)。PrimaryEMail 设置方法可能只接受集合中已有的 EMail 对象。

我只在手动 ORM 类中完成了这项工作,并且找不到在 NHibernate 中执行这种相当常见的场景的规范方法。那里一定有一个。

于 2010-04-09T03:05:21.470 回答
1

首先。你为什么在那里使用 IEnumerable ?您想在每次访问该属性时启动查询吗?为什么它有一个公共二传手?

在我看来,您希望它是 IList 或 ICollection。有一个列表会更有意义,因为我会添加两种方法:

User.SetPrimary(int index)
User.GetPrimary()
User.ICollection Emails { get; protected set; }

Email.IsPrimary { get; protected set; }

第一个遍历电子邮件以确保只有一个项目设置为主要项目,第二个遍历电子邮件直到找到一个标记为主要项目。

于 2010-04-09T07:31:38.770 回答