如果我让每个类都从一个提供keyid的基类中继承,会不会有问题(或者说这是个坏主意)? 在Entity Framework中的代码优先设计中。
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 {...}
我知道这个问题已经有一段时间没有人问了,我还是要发个答案。
我已经做了更多的代码优先项目,我现在可以计算,我 始终 最终为我的实体建立了一个抽象的基类。原因很简单,总有一些你认为应该出现在所有实体中的字段。身份证 当然是最明显的。
另外,当你添加了一个基类(或接口),你突然允许你的DbContext在这个抽象上操作。我几乎总是在这个基类中添加事件(比如OnLoad, OnSave, OnDelete),我将这些事件留为虚拟的,然后重写了 保存更改 方法,并为我的DbContext调用相应的受影响实体的事件。
所以我的答案是否定的,在你的EF类中添加一个基类是没有坏处的。但是就像上面的一些答案所说的那样,如果它仅仅是为了Id列,那么也许你还不如在你所有的类中重复那一行(4个基本注释;)。
我对此有不同的感受。
亲
缺点
Id
是纯粹的DAL的事情。(价值观也是如此,比如 InsertDateTime
基类型经常使用的)。)我倾向于 不 这样做。如果你想让你的实体有共同的东西,我会用一个接口。我知道,这是相当多的工作。而且它看起来并不DRY,但我认为DRY原则应该被定义为 "don't 无谓 重复自己"。
如果尽管如此,你还是决定使用一个基类,我发现确保它不会成为实体模型(实体框架已知的模型)的一部分是有益的。如果会的话,你必须确保EF使用TPC,而且不可能使用其他继承模型。所以,只映射派生类型,EF永远不会知道基础类型,也不会尝试实现和继承策略。
我的问题是 why
你会想这样做... ...
I don't see any real reasons to want to 'decouple' base class for the sake of 'ID-ing' alone
. 你所节省的只是一行代码。否则,你不会在查询中使用该类(因为它实际上什么都不代表),但你仍然必须小心 "继承"--因为你的代码,与TPC方案将导致额外的表(为所有 "非抽象 "类)--所以我可能会使它成为 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
. 我认为实体POCO是C#对象--但毕竟呈现了一些有意义的底层数据--我喜欢看到它们这样(也适用于任何其他类,而不仅仅是entitiyPOCO)。
例如,你想引用userId,但是由于超级类的存在,所有的表都有id。
@AttributeOverrides(value = { @AttributeOverride(name = "id", column = @Column(name = "passwordTokenId", nullable = false)), @AttributeOverride(name = "name", column = @Column(name = "token", nullable = false))})
在hibernate中尝试映射关系......你开始怀疑这个id是类Book还是类Person的
但当你的类被定义为如下时,它是很好的。
公共类 Client 扩展到 Person 公共类 Broker 扩展到 Person
和类Person的定义是有String firstName和String lastName.同样是DRY原则。
我尝试了这两种,我喜欢保持它的简单(KISS).就像上面的先生说,它拥抱DRY,但它也违反(KISS).我同意最后一位先生,我喜欢你喜欢的:),所以遵循你的直觉。