【问题标题】:is one to one relationship bad strategy是一对一关系不好的策略
【发布时间】:2014-05-02 10:09:32
【问题描述】:

用户始终拥有一个钱包。一个钱包始终属于一个用户。

因为我想分离货币钱包相关的属性,所以我创建了 Wallet 对象并能够跟踪货币交易,...我创建了

public Wallet : Entity<int>
{
    public double Amont {get; set;}
    public IList<MoneyTrans> Transactions {get; set;}
}

由于这显然是一对一的关系,是否可以使用一对一的关系进行映射?

一对一的策略不好吗?

【问题讨论】:

  • 如果这是逻辑设计,为什么它会是一个糟糕的策略?你的意思是如果你以后需要改变它?
  • 不,但我阅读了大量的页面,其中一对一是批评。谢谢
  • 您能否提供一些链接,以便我们阅读并让您知道它的确切含义?
  • 也请查看此链接。可能的重复。 stackoverflow.com/questions/3939589/…

标签: c# .net nhibernate domain-driven-design


【解决方案1】:

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

我不是在谈论概念领域驱动设计。关于我在 DB 设计和 NHibernate 使用方面的经验。

1) one-to-one - 刚性数据库设计

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

典型场景,与示例 23.2. Author/Work 非常相似,其中 Author 映射为 one-to-onePerson。因此,Author 的 id(主键)来自于 Person(id)。迟早,Business 会来询问我们是否必须将人映射到 Author (参见 Lars Kepler 示例)

我在这里想说的是:Chapter 24. Best Practices(让我引用一点)

在持久类上声明标识符属性。

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

正如这里提到的(根据我的经验),让所有实体都有自己的代理主键是非常有益的。稍后发生的关系更改 - 只会影响引用(在代理键之上),而不是表/实体本身。

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

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

正如问题(cite)

下方的 cmets 中的链接之一所述
  1. 您可以将所有这些属性作为列包含到实体表中 - 但在这种情况下,对于大量条目而言,许多列最终会为空。

  2. 或者:你可以把那些“可选”属性放到一个单独的表中,与基础实体表建立1:1(或者更确切地说:0:1)关系,

嗯,使用 NHiberante,您不会得到这么多的改进。这个建议是错误的。 Lazy loading of one-to-one isn't supported...

总结:

这就是我强烈建议的原因:尽可能使用many-to-oneone-to-many。你会得到更多...

【讨论】:

  • 非常好的答案,基于我的具体示例(用户 - 钱包)你有什么建议?
  • 哇...抱歉,我错过了这个答案 ;) 好吧,在这种情况下,我想直接访问从 UserWallet,所以:User (table) 将包含WalletId 列。然后User 将有many-to-one 引用public virtual Wallet Wallet { get; set; } 如果需要,相反的方向可能是:1)钱包可能有Users&lt;bag&gt; - 但受保护,2)和一些虚拟/人工使用Users.SingleOrDefault() 的属性。因为用户钱包的方向是必不可少的,所以many-to-one 在这种情况下将完成 80% 的日常工作......我会说
  • 再次感谢,这是否意味着如果我想要双向关系 UserTable 与 WalletId,反之亦然 Wallet 表与 UserId,我应该在双方都使用 ManyToOne 吗?
  • 很可能,是的。最好的答案是……尝试尝试,玩弄。最后,你的结论可以很好地工作。这里最重要的是使用自己的代理键来保存表(NHibernate 会为我们提供最好的)此外,业务层和 UI 层可能会向我们发布一些不同的视图用户 - 与数据层相比 (即最终用户可能看起来像 one-to-one
【解决方案2】:

不,没关系。这不仅仅是关系,而是面向对象。从根本上说,钱包不是个人不可分割的一部分。

除此之外,虽然钱包现在可能属于特定的“约翰”,但“詹姆斯”可能会作为礼物赠送。从数据的角度来看,如果他们没有钱包,最好只更改 John 和 James 的 WalletId 字段,其中一个可能为空(尽管在您的情况下不是)。

【讨论】:

    猜你喜欢
    • 2018-06-27
    • 2011-07-26
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多