如何实现类的不同类型:继承、接口或类属性?
我需要实现以下内容,但我不确定最好的方法是什么:
我正在为 MVC 应用程序创建消息功能。
有两种类型的消息:
- 公共消息
- 私人消息
唯一的区别是公共消息具有 ValidFrom 和 ValidTo 日期字段。我尝试过以下方法:
方法1,界面 消息接口。实现该接口的两个类 PrivateMessage 和 PublicMessage。 PublicMessage 有两个额外的属性。使用实体框架将其映射到两个不同的表。
方法2、继承 创建一个包含所有字段的消息基类。创建两个继承基类的类。可以将消息类映射到数据库,因此我只有一张表来保存记录。我似乎无法使用 EF Code First 映射接口。
方法 3,设置消息类型的枚举属性
public enum MessageType
{
Public = 1,
Private = 2,
}
我只有一个消息类,但添加一个字段来显示它是什么类型的消息。轻松映射到一张表,并轻松搜索“公共”类型的消息。我必须在枚举周围制作一个迷你包装器,因为 EF 不会在数据库中为它创建一个字段。
这两个属性字段真的足以证明两个不同的类是合理的吗?在两个数据库表中搜索未读消息有点无效?
有正确的方法吗?
我使用实体框架 Code First 4.3。
I need to implement the following but I'm not shure what the best way is:
I'm creating a message functionality for an MVC app.
There are two types of messages:
- Public messages
- Private messages
The only difference is that public messages have a ValidFrom and ValidTo date field. I have tried the following:
Method 1, interface
IMessage interface. Two classes PrivateMessage and PublicMessage that implements the interface. PublicMessage has the two extra properties. Mapped it to two different tables with entity framework.
Method 2, inheritance
Create a message base class that has all the fields. Create two classes that inherit the base class. Can map the message class to the db so I only have one table to keep the records. I cannot map an interface with EF Code First it seems.
Method 3, Enum property to set what type of message
public enum MessageType
{
Public = 1,
Private = 2,
}
I just have one Message Class, but add a field to show what type of message it is. Maps easily to one table, and easy to search for messages of type "Public". I have to make a mini wrapper around the enum becouse EF wont create a field in the db for it though.
Is really the two property fields enough to justify two different classes? Searching two database tables for unread messages is a bit ineffective?
Is there a right way to do this?
I use Entity Framework Code First 4.3.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ORM框架通常通过三种方式解决继承问题:
1.所有对象一张表:在这种方法中,有一张表,每个具体类将使用同一个表。鉴别器将用于找出哪个记录与哪个类相关。
2.每个具体对象一个表:对于每个具体对象,数据库中都会有一个对应的表,并且每个对象都有自己的映射。框架不知道这些对象是继承层次结构的一部分。(没有鉴别器需要)
3.每个对象(具体或抽象)一个表:在这种方法中,共享数据存储在映射到基本抽象类的表中,每个具体对象将有一个单独的表来存储自己的数据,并且存在一对一的关系该表与其父表之间。父表中再次需要一个鉴别器来向框架显示哪些记录属于哪个对象。
在第一种方法中,表的数量最少(只有一个表),但它具有所有对象的所有字段。因此,所有不常见的字段都应该可以为空并且可以接受空值。
第二,共享数据分布在许多表中,但每个表都控制自己的字段,因此不需要有一些不必要的空值。
第三种方法将最多数量的表共享数据存储在一个位置,并且各处都没有不必要的空值。
根据您的场景,第一种方法似乎是最好的,因为两个对象之间的差异非常小(只有两个字段),并且表中包含一些空值是可以容忍的,并且它比数据库中包含两个或三个表更好,
ORM frameworks usually solve the inheritance problem in three ways :
1.One table for all objects: in this approach there's one table and each concrete class will use the same table . A discriminator will be used to find out which record is related to which class.
2.One table for each concrete object: for each concrete object there will be a corresponding table in the database and each object has its own map .The framework doesn't know that these objects are part of a inheritance hierarchy.(no discriminator is needed)
3.One table for each object (concrete or abstract):in this approach shared data is stored in a table that's map to the base abstract class and each concrete object will have a separated table storing its own data and there's a one to one relationship between this table and its parent table.Again a discriminator is needed in parent table to show the framework which records belong to which object.
in first approach number of tables is minimum (just one table) but it has all the fields of all objects . thus all uncommon fields should be nullable and can accpet null.
in second shared data is distributed among many tables but each table is in control of its own fields thus there's no need to have some unnecessary null values.
The third approach has the most number of tables the shared data is stored in one place and again there's no unnecessary null values all over the place.
It seems that according to your scenario the first approach is the best because the difference between two objects is very small (only two fields) and having some null values in your table is tolerable and it's better than having two or three tables in your database,
您可以通过多种方式来实现这一目标,就像您正在尝试的那样。所以...
1) 您可以拥有 1 个包含所有字段的实体
Message
和一个额外的列IsPublic
2) 您可以将 2 个实体
PublicMessage
和PrivateMessage
保存在 2 个表中3) 您可以拥有 TPT 或 TPH 继承模型,其中将
Message
作为PublicMessage
和PrivateMessage
的基类,使用哪个的问题是更多关于您正在尝试解决的业务问题。您提到搜索两个表效率低下。因此,我假设您希望构建一个人可以同时看到私人和公共消息的视图。如果可以的话,最好在出现性能问题(以及支持它的数据)后进行优化。
有趣的是,公共消息有一个截止日期。这表明两个实体的生命周期不同。这可能表明它们需要单独管理。
考虑到所有这些假设,我会选择简单的并将它们分成单独的实体。对未读消息进行两次查询并不是世界末日。
You can accomplish this is many ways, as it seems that you are experimenting with. So...
1) You can have 1 entity
Message
that contains all fields and an extra columnIsPublic
2) You can have 2 entities
PublicMessage
andPrivateMessage
persisted in 2 tables3) You can have TPT or TPH inheritance model where you have
Message
as a base class ofPublicMessage
andPrivateMessage
The question of which to use is more about what business problem you are trying to solve. You mention that searching two tables is inefficient. So, I assume that you have a view to build where a single person can see both private and public messages. If you can, it is better to optimize after you have a performance issue (and data to support it).
It is interesting that the public messages have a to and from date. This suggests that the life cycle of the two entities differ. This could indicate that they need to be managed separately.
With all those assumptions, I would opt for the simple and make them to separate entities. Making two queries for unread messages is not the end of the world.