Entity framework + mvc + code first + Inheritance table per Hierarchy,如何使用 heritage/polymorphism 来避免 switch/if

Entity framework + mvc + code first + Inheritance table per Hierarchy, How to use heritage/polymorphism to avoid switch/if

我在这里缺乏知识,所以我需要帮助,因为我迷失在我不理解的概念中。
先给大家介绍一下题目的背景。

一般上下文
我们有来自其他应用程序的设备。
所以,我们设计了数据库class设备。
每个应用程序都有自己的设备 class 继承基础设备 class.
例如,应用程序 "AAA" 将继承 "Equipment" 的 class "AAAEquipment"。 由于申请的人不多,我们选择了型号"Inheritance table per Hierarchy".

有关 TPH 的详细信息,请参阅以下 link:http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph

问题背景
给定一个设备,我们需要检索详细信息。
详细信息存储在国外应用程序中。
无论哪个应用程序,结果细节始终具有相同的结构。
但是,检索详细信息的逻辑不同。
例如,"AAAEquipment" 使用 Web 服务。另一个可以使用别的东西。

在我们的 Web 应用程序控制器中,当我们需要给定设备的详细信息时,我们现在在 TypeOf(Equipment) 上有一个切换案例来调用良好的 Web 服务。

假设(基于我对entity framework、代码优先和设计模式的非常贫乏的了解)
- 数据库 class 必须保留 "POCO",这意味着只包含没有逻辑的属性。
- 数据库项目不应该引用其他项目,如 web 服务和其他东西。其他项目应该参考数据库项目,而不是相反。

问题
我如何使用继承来避免在我的控制器中使用 IF 和 SWITCH 案例来检索细节? 如果我们不能为层次结构的每个 class 拥有自定义逻辑,那么拥有像 TPH 这样的概念有什么意义呢? 不应该是

MyEquipment.GetDetail();

而不是

IF(MyEquipment is AAAEquipment)
{
    Call AAAWebService
}

我认为我可以对所有类型的设备使用 "extension methods",但我不认为这是处理此问题的 "Normal" 方式。我觉得多态性的能力在这里被削弱了。

感谢您的帮助,谢谢!

Database class must remain "POCO", meaning containing only properties with no logic.

这是不正确的。 EF 并没有阻止 POCO 类 包含其他逻辑。虽然在一个对象中混合关注点不是一种好的风格,但没有技术限制。

一个简单的解决方案是向 Equipment 的每个子类添加一个方法来实现检索其自身详细信息的细节

abstract class Equipment
{
    public void GetDetail();
}

public class AAAEquipment
{
    public void GetDetail()
    {
        // Appropriate implementation to get details
    }
}

如果您需要更严格的关注点分离,您可以提供一个单独的工厂来获取仅属性 POCO 的详细信息。为避免 if/switch 语句,您可以为与您的设备 sub类 相匹配的工厂继承层次结构。您也可以使用 Dependency Injection 代替工厂。

如果你想从你的 poco 中抽象出细节,可以使用依赖倒置。 (请注意,虽然我在这里使用的是构造函数注入。如果您觉得使用 EF 有困难,您也可以使用 属性 注入)

public abstract  class Equipment
{
    public abstract Detail GetDetail();
}

public sealed class EquimpmentAA : Equipment
{
    private readonly IGetDetail _getDetail;
    public EquimpmentAA( IGetDetail getDetail)
    {
        _getDetail = getDetail;
    }


    public override Detail GetDetail()
    {
        return _getDetail.Get();
    }
}

public sealed class Detail 
{
   //Details
}

//Different implementations on how each class gets its detail
public interface IGetDetail
{
    Detail Get();
}

你是对的,你可能不想让你的 pocos 依赖于特定的服务等等。这不仅适用于 pocos,而且适用于所有 类 通常,您希望 类 不直接依赖于 wcf 服务。通过使用依赖倒置原则,很容易将您的代码与这些实现细节分离。

使用 Dependency Injection 可能是一个不错的决定,可以在您的代码中注入不同的实现。