0

如果我让每个类都从提供他的密钥/ID的基类继承,会不会有问题(或者可能是个坏主意)?这在实体框架中的代码优先设计中

class MyObject
{
[Key]
public int Id { get; set; }
}

class Person : MyObject {...}
class Message : MyObject {...}
class Whatever : MyObject {...}

我想这样做是因为发生了很多事情,我希望两个/三个类(例如)从某个基类继承,而我不负责提供 id 的那个基类。

具体例子,比较一下:(实际场景)

class Recipient
{
[Key]
public int RecipientId { get; set; } // I want to avoid this
public string DisplayName { get; set; }
}

class Person : Recipient {...}
class Group : Recipient {...}

为此:(我想要实现的目标)

class MyObject
{
[Key]
public int Id { get; set; }
}

class Recipient : MyObject
{
public string DisplayName { get; set; }
}

class Person : Recipient {...}
class Group : Recipient {...}
4

4 回答 4

4

我知道自从提出这个问题以来已经有一段时间了,无论如何我都会发布答案。

到目前为止,我已经完成了比我数不清的更多代码优先项目,而且我总是以我的实体的抽象基类结束。原因很简单,总有一些你认为应该存在于所有实体中的字段,当然Id是最明显的。

此外,当您添加一个基类(或就此而言的接口)时,您突然允许您的 DbContext 对该抽象进行操作。我几乎总是将事件添加到我保留为虚拟的这个基类(如 OnLoad、OnSave、OnDelete),然后为我的 DbContext 覆盖SaveChanges方法并为受影响的实体调用适当的事件。

所以我的回答是否定的,向你的 EF 类添加基类没有害处。但是就像上面的一些答案所说的那样,如果它对于 Id 列来说是微不足道的,那么也许你不妨在你的所有课程中重复这一行(4 条带有基本评论;))。

于 2014-02-22T18:41:14.330 回答
1

我的问题是why你想这样做...

I don't see any real reasons to want to 'decouple' base class for the sake of 'ID-ing' alone. 您所节省的只是一行代码。否则,您将不会在查询中使用该类(因为它实际上不代表任何内容),但您仍然必须小心“继承” - 因为您的代码,使用 TPC 场景会导致额外的表(对于所有“非-abstract'类) - 所以我可能abstract只是为了确定。也不要将它定义为DbSet(这应该让它几乎不被关注,就像界面一样)。

如果你已经有另一个基类——这似乎是“ID”的理想场所——但这一切都是非常个人化的。

...简而言之I haven't seen any major issues with it (just make it abstract and off DbSet)--虽然equally I don't see any gains from it。IMO Entities / POCO 是 C# 对象——但毕竟提供了一些有意义的底层数据——我喜欢这样看待它们(也适用于任何其他类,而不仅仅是实体 / POCO)。

于 2013-03-31T17:26:53.140 回答
1

我对此有复杂的感觉。

  • 它包含 DRY 原则(不要重复自己)。

缺点

  • 它违反了继承的目的,即表达“是”关系(客户“是”人)。说 Person “是”基础对象在业务领域中毫无意义。它不表达任何业务逻辑。最终,具有基类型可能会阻止其他继承策略,因为 C# 不支持多重继承。
  • 它混合了业务逻辑和 DAL 实现。基类中的字段与业务领域无关。拥有一个Id纯粹是 DAL 事务。(对于InsertDateTime经常使用基本类型的值也是如此)。

我倾向于这样做。如果您希望您的实体有共同点,我会使用界面。这是相当多的工作,我知道。而且它看起来并不 DRY,但我认为 DRY 原则应该定义为“不要不必要地重复自己”。

尽管如此,如果您决定使用基类,我发现确保它不会成为实体模型(实体框架已知的模型)的一部分是有益的。如果是这样,您必须确保 EF 使用 TPC,并且无法使用其他继承模型。因此,只映射派生类型,EF 永远不会知道基类型,也永远不会尝试实现和继承策略。

于 2013-04-02T10:15:51.717 回答
0

在我看来,这一切都会造成并发症。例如,您想引用 userId,但由于超类,您的表都有 id。那么现在你必须在你的课堂上添加这样的东西

@AttributeOverrides(value = { @AttributeOverride(name = "id", column = @Column(name = "passwordTokenId", nullable = false)), @AttributeOverride(name = "name", column = @Column(name = "token ", nullable = false)) })

它并没有在这里结束。尝试在休眠中映射关系怎么样......你开始想知道这个 id 是类 Book 还是类 Person

但是当你的类定义如下时很好

公共类 Client 扩展 Person 公共类 Broker 扩展 Person

并且类 Person 定义有 String firstName 和 String lastName .. 再次 DRY 原则

我都试过了,我喜欢保持简单(KISS)。就像上面那位先生说的那样,它包含 DRY,但它也违反了 (KISS).. 我同意最后一位先生的观点,我喜欢你喜欢的 :) 所以跟随你的直觉

于 2020-05-01T18:30:31.627 回答