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 可能是一个不错的决定,可以在您的代码中注入不同的实现。
我在这里缺乏知识,所以我需要帮助,因为我迷失在我不理解的概念中。
先给大家介绍一下题目的背景。
一般上下文
我们有来自其他应用程序的设备。
所以,我们设计了数据库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 可能是一个不错的决定,可以在您的代码中注入不同的实现。