是一对一的关系糟糕的策略
用户总是有一个钱包。 一个钱包总是属于一个用户。
由于我想分离与钱包相关的属性,我创建了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:1(或更确切地说:0:1)的关系,
好吧,NHiberante你不会得到这么大的改进。 这个建议是错误的。 不支持延迟加载一对一…
摘要:
这就是为什么我强烈建议:在可能的情况下使用many-to-one
或one-to-many
。 你会获得更多……
不,还好。 这不仅仅是关系,而是面向对象。 基本上钱包不是一个人无法分辨的部分。
除此之外,虽然钱包现在可能属于特定的“约翰”,但“詹姆斯”可能会被赠送给礼物。 从数据的角度来看,更改John和James的WalletId字段要好得多,如果他们没有钱包,那么可能是空的(尽管不是在你的情况下)。