获取对象内的所有关联/复合对象(以抽象方式)

业务

我有一个支付系统,可以通过GiftCoupon,ClubMembershipCard等支付。一个支付本身可以有多个支付组件

分类

我有一个付款类。 它有支付组件,如GiftCouponPayment,ClubMembershipCardPayment,CashPayment等。 每种组件类型都满足通用接口IPaymentComponent。 我使用有关现有类型的知识实现了它。

问题

1)如何以抽象的方式实现这个function – 不知道存在哪些类型? 这意味着它需要适用于实现IPaymentComponent接口的所有类型。

2)如果无法在LINQ to SQL中实现它,是否可以在Entity Framework中实现?

3)当LINQ to SQL在Payment对象中生成GiftCouponPayment实体时,它是关联/聚合还是组合?

注意:我使用LINQ to SQL作为ORM。 GiftCouponPayment和Payment是自动生成的类,这些对象由ORM创建。 我通过使用部分类为这些类添加了更多function。

注意:在数据库中,每个PaymentComponent(例如GiftCouponPayment)都有自己的属性(例如CouponValue,CardValue等)。 因此,每层次表不会很好 。 我们需要单独的表格。 那条线路有解决方案吗?

注意:此付款之前,数据库中已存在GiftCouponPayment。 我们需要使用客户提供的GiftCouponPaymentID来识别GiftCouponPayment对象。 我们只需要更新此表中的PaymentID列。

泄漏抽象是指任何已实现的抽象,旨在减少(或隐藏)复杂性,其中底层细节未被完全隐藏

LINQ to SQL Diagram

在此处输入图像描述

参考

  1. entity framework4,inheritancevs扩展?
  2. 如何选择inheritance策略http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx
  3. 流畅的API示例 – http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-fluent-api-samples.aspx

C#代码

public interface IPaymentComponent { int MyID { get; set; } int MyValue { get; set; } int GetEffectiveValue(); } public partial class GiftCouponPayment : IPaymentComponent { public int MyID { get { return this.GiftCouponPaymentID; } set { this.GiftCouponPaymentID = value; } } public int MyValue { get { return this.CouponValue; } set { this.CouponValue = value; } } public int GetEffectiveValue() { if (this.CouponNumber < 2000) { return 0; } return this.CouponValue; } } public partial class Payment { public List AllPaymentComponents() { List allPayComps = new List(); List giftCouponPaymentList = new List(); List cashPaymentList = new List(); foreach (GiftCouponPayment g in this.GiftCouponPayments) { giftCouponPaymentList.Add(g); allPayComps.Add(g); } foreach (CashPayment c in this.CashPayments) { cashPaymentList.Add(c); allPayComps.Add(c); } return allPayComps; } } 

我想你可能想暂时离开设计。 我听到的是:

付款由一个或多个组件组成,每个组件可以是各种类型之一

你需要的是一个Payment表,然后是一个PaymentComponent表,外键关系回到Payment表。 然后,您可以在PaymentComponent表上实现各种付款方式的inheritance。

您可以尝试使用抽象层或数据访问层,这将是类型T的通用层。或者至少使方法通用。

你基本上有一些问题:

  1. 如何建模付款类型

    让我们假设我们想要以经典的OOP方式:

    你需要一个基类,支付(或PaymentBase)是抽象的和从它inheritance的各种类,例如PaymentInCash,PaymentWithCreditCard等。

    另一种方法是将PaymentDetails添加到Payment并创建PaymentDetails的层次结构,如果您选择这样做,则在以下所有点中将Payment替换为PaymentDetails。

    对于使用多种方法的付款 ,您可以:

    一个。 在付款下有一系列PaymentDetails
    要么
    湾 创建一个名为AggregatePayment的类型,其中包含付款列表。

  2. 如何将付款类型映射到表

    TPT和TPH都在这里有效……

    对于TPT,使用一个表格进行付款,使用一个表格进行各种付款。
    所有inheritance类型的表PK应该是基类型表的FK。
    如果您有多个层次结构,则可以在第二个(或任何其他)级别使用TPT或TPH(如果使用EF)。

    对于TPH,使用一个带有鉴别器列的表(例如PaymentType),并将层次结构中所有实体之间未共享的每个列标记为可空。 不要对不同实体中的不同属性使用相同的列。 在EF中,将每个实体映射到同一个表,条件为PaymentType =(数字在此处)和(不应为空的列名称)不为空。

    我的建议是,如果你有很多窄类型(每个属性很少)和TPH一起使用,如果你有几种类型,请选择TPT。

  3. 哪种设计模式/代码技术用于支付算法

    你有更多的选择:

    一个。 使用部分类并在基类上放置一个抽象的ProcessPayment()方法,并在inheritance类中重写。

    湾 每个支付类型使用基本PaymentProcessor类和特定的PaymentProcessor,例如PaymentInCashProcessor。 在这种方法中,您可以使用reflection来加载正确的PaymentProcessor类型,方法是存储字典或更好,使用generics:

 abstract class PaymentProcessor { } abstract class PaymentProcessor : PaymentProcessor where TPayment : class, Payment { } class PaymentInCashProcessor : PaymentProcessor { } // Use reflection to find types that inherits from PaymentProcessor // create an instance of the type you found // then cast the instance to PaymentProcessor to use 

如果设计EF模型,则可以在名为payment的基类上使用abstract属性。 并inheritance您所有类别的付款方式:

实体框架模型

付款将具有所有常见属性,并且每种特定类型都可以拥有自己的属性。

如果您有这种模型,您只需查询付款。

这将返回inheritance付款类型的所有对象:

 var allPayments = objectContext.Payments;