【问题标题】:Entity Framework 4, inheriting vs extending?实体框架 4,继承与扩展?
【发布时间】:2011-05-06 20:01:58
【问题描述】:

每种方法的优点/缺点是什么?

我知道我在一本书或这个网站上的某处读过为什么使用表继承对于 Entity Framework 4 来说很糟糕。

例如,为什么不创建一个具有 entityId、datecreated、datemodified 的表,然后让所有其他类在实体框架中继承它呢?然后我的所有其他实体的表不需要有这些列。然后我可以让一个人类继承那个基类,然后一个特定的人继承人。

除了编写一个较小的 SQL 脚本来生成数据库之外,我不确定这样做的好处...

我看到的缺点是,它让直接在 SQL 中查询/查看数据变得非常痛苦(所有相关信息都被打破了这么多表),我还问了我的朋友,他说:

“对我来说最重要的事情是我不希望我的数据库依赖于我的应用程序的当前继承结构。如果,出于某种原因,我想改变我的应用程序的设计就继承而言,没关系,因为我的数据不依赖于我当前的系统设计。我认为数据存储只是存储。数据库根据适当的数据库设计进行规范化,但继承是一种程序化的选择应用程序开发,而不是数据存储。仅此一项就会阻止我使用它。在设计应用程序时,继承是一件非常困难的事情。更改应用程序代码比更改和迁移数据库要容易得多数据 当大多数经验不足的开发人员遇到问题时,他们会通过继承来解决问题。我刚开始开发时也是这样做的。这在逻辑上是有道理的。但是,一旦开发了很长时间,您就会了解到委托确实是最好的方法(在 soa 的情况下服务调用服务),并且单一用途的服务提供比继承更多的重用。”

这对我来说也很有意义。

所以

1) 一般来说,继承与扩展的优缺点是什么
2)在我上面的具体例子中,什么更合适?
3)如果我的例子对其中一个或两个都不好,那么使用继承和使用扩展的好例子是什么?

我以前都用过,但由于我经验不足,我仍然不确定如何处理所有情况。

10 票,8 人收藏,过百次浏览,无人能展开? =(。

【问题讨论】:

    标签: .net entity-framework inheritance entity-framework-4 extending


    【解决方案1】:

    我尝试过与您描述的类似的事情,我看到的主要问题是您无法为派生类型创建ObjectSet<T>。所以你不会有ObjectSet<Person> 存储库。 如果您从例如 BusinessObject 实体派生所有实体,您将只能使用ObjectSet<BusinessObject>。如果您只想查询 Person 存储库,您可以编写像 Context.BusinessObjectSet.OfType<Person>().ToList() 这样的查询,但我认为它不会在后台生成正确的 SQL,并且会首先获取完整的 BusinessObject 行,然后过滤掉内存中的 Person 实体。所以我猜它会对性能产生巨大的影响。

    【讨论】:

    • 感谢 BP 的回复,您是否有机会进一步扩展?还是没有其他优点和缺点?那么使用继承的好例子是什么?
    • 其实 .OfType 是在 SQL 端过滤的,IIRC
    【解决方案2】:

    在模型中使用继承的一个缺点是您将无法通过 WCF 数据服务 (OData) 显示模型,因为它目前不支持派生实体。

    【讨论】:

      【解决方案3】:

      我参加聚会有点晚了,但是关于 EF 中的继承,我一直有与您相同的问题,并找到了一个很好的摘要供您阅读。这是excerpt from Julie Lerman's book Programming Entity Framework

      阅读后,这是我对该主题的结论:

      1) 一般来说,继承与扩展的优点/缺点是什么 - 优点实际上取决于您选择的表策略。见How to choose an Inheritance Strategy - MSDN Blog。但是,它们只是假设您已经决定使用继承的“专业人士”。这不是一个掉以轻心的决定。

      缺点很多,但最大的缺点是无法将现有实体作为派生实体添加到数据库中。例如:我有一个继承自 Person 的 Student。有 John Smith 的 Person 记录。一段时间后,我需要约翰史密斯成为一名学生。好吧太糟糕了。那是不可能的。 (至少在不使用存储过程规避 EF 的情况下并非如此)。

      2) 在我上面的具体示例中,什么更合适? - 在您的示例中,您应该将这些列(entityId、datecreated、datemodified)添加到需要它们的表中。您可以对 datecreated 和 datemodified 使用复杂类型,但除非您是一个非常严格的 DRY 人,否则这不是必需的。即使那样,它也可能是矫枉过正。原因是一旦有了实体,就永远无法将该实体添加到另一个派生表中。以后不能将 Person(它是 BaseEntity)添加为 Student。此外,编写 LINQ 查询会比需要的复杂得多。亚历克斯已经证明了这一点。

      3) 如果我的示例对于其中一个或两个都不好,那么使用继承和使用扩展的好示例是什么? - 通常,如果您可以将基本类型抽象化,继承 可能对你有用。但您仍应首先考虑其他选择。如果您的基本类型将在某处直接实例化,则只需使用组合。在实际查询和插入记录时,继承变得非常麻烦。

      总而言之,仅仅因为您可以在 EF 中进行继承并不意味着您应该这样做。如果您可以摆脱无继承设计,那么一定要这样做。

      【讨论】:

        猜你喜欢
        • 2011-05-08
        • 2013-04-21
        • 2011-09-14
        • 2011-05-19
        • 2010-10-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多