是一对一的关系糟糕的策略

用户总是有一个钱包。 一个钱包总是属于一个用户。

由于我想分离与钱包相关的属性,我创建了Wallet对象并能够跟踪货币交易,…我创建了

public Wallet : Entity { public double Amont {get; set;} public IList Transactions {get; set;} } 

因为这显然是一对一的关系,所以可以使用一对一关系进行映射吗?

一对一的坏策略是什么?

我不得不以相反的观点附加答案。 不要使用one-to-one映射。 至少NHibernate。

我不是在谈论概念域驱动设计。 几乎是我在数据库设计和NHibernate使用方面的经验。

1) one-to-one – 刚性DB设计

首先,使用共享主键(inheritance除外)的设计可能会在以后更改业务需求时导致许多问题。

典型场景,非常类似于示例23.2。 作者/工作 ,其中作者 one-to-one映射到 。 因此,作者的id(主键)来自Person(id)。 迟早,商业会来,问我们是否可以将人映射到作者(参见Lars Kepler示例)

我在这里要说的是: 第24章最佳实践 (让我引用一点)

声明持久化类的标识符属性。

NHibernate使标识符属性可选。 你应该使用它们有各种各样的原因。 我们建议标识符是“合成的”(生成,没有商业含义)和非基本类型。 为了获得最大的灵活性,请使用Int64或String。

正如这里所提到的(根据我的经验) ,让所有实体拥有自己的代理主键是非常有益的。 稍后关系的变化 – 将仅影响引用(在代理键之上),而不影响表/实体本身。

2)NHibernate one-to-one 不能偷懒

事实上,这个原因就是那个,为什么(尽管我尝试了几次)目前根本不使用one-to-one一对一不支持延迟加载。 搜索更多信息,但很好的解释可以在这里找到:

  • Ayende NHibernate一对一 (引用)

    换句话说,一对一不能延迟加载,这是为什么建议使用两个多对一的原因之一。

  • 关于延迟加载的一些解释(一对一)

正如下面评论中的一个链接所提到的那样(引用)

  1. 您可以将所有这些属性作为列包含到实体表中 – 但在这种情况下,对于大量条目,许多列将为空。

  2. 或者:您可以将这些“可选”属性放入单独的表中,与基本实体表建立1:1(或更确切地说:0:1)的关系,

好吧,NHiberante你不会得到这么大的改进。 这个建议是错误的。 不支持延迟加载一对一…

摘要:

这就是为什么我强烈建议:在可能的情况下使用many-to-oneone-to-many 。 你会获得更多……

不,还好。 这不仅仅是关系,而是面向对象。 基本上钱包不是一个人无法分辨的部分。

除此之外,虽然钱包现在可能属于特定的“约翰”,但“詹姆斯”可能会被赠送给礼物。 从数据的角度来看,更改John和James的WalletId字段要好得多,如果他们没有钱包,那么可能是空的(尽管不是在你的情况下)。