I have a database relationship as shown below. The domain objects are created based on LINQ to SQL ORM.
A payment comprises of Cash Payment and Gift Coupon Payments. Suppose the total amount of purchase is 550. It can be paid as following components
1 Gift Coupon Valued 300
1 Gift Coupon Valued 200
I Cash Currency Valued 50

I am inserting new payment records using the “InsertOnSubmit” function of ORM. The following code is working fine. However, if I the company is introducing a new payment component using credit card, I need to make changes to my “Payment” domain class. How do I make the payment class Open for Extension and Closed for Changes still using ORM?
Note: The Payment class has behaviors (E.g. GetTotalAmountCollected). I am trying to make the "Payment" class to satisfy OCP.
Note: There is a specific behavior for Coupon type. Is the Coupon issued date is less than 1/1/2000, it should not be used in calculation for Total Amount (i.e, CouponValue should be zero). Refer Refactoring code using Strategy Pattern also.
Note: I am using .Net 4.0
Reference:
- Getting an error when using ObjectContext.AddObject with Entity Framework
- Refactoring code using Strategy Pattern
- Prefer composition over inheritance?
- Code-first vs Model/Database-first
- Strategy Pattern and Dependency Injection using Unity
- C# Strategy Design Pattern by Delegate vs OOP
- How to use the Strategy Pattern with C#?
- Inheritance with EF Code First: Part 2 – Table per Type (TPT) http://weblogs.asp.net/manavi/archive/2010/12/28/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt.aspx
C# Code:
public class PaymentAppService
{
    public RepositoryLayer.ILijosPaymentRepository Repository { get; set; }
    public void MakePayment()
    {
        DBML_Project.Payment paymentEntity = new DBML_Project.Payment();
        paymentEntity.PaymentID = 1;
        paymentEntity.PaymentType = "PurchaseP";
        DBML_Project.CashPayment cashObj = new DBML_Project.CashPayment();
        cashObj.CashPaymentID = 1;
        cashObj.CurrencyNumber = 123;
        cashObj.CurrencyValue = 100;
        DBML_Project.GiftCouponPayment giftCouponObj = new DBML_Project.GiftCouponPayment();
        giftCouponObj.GiftCouponPaymentID = 1;
        giftCouponObj.CouponValue = 200;
        giftCouponObj.CouponNumber = 124;
        paymentEntity.CashPayments = new System.Data.Linq.EntitySet<DBML_Project.CashPayment>();
        paymentEntity.CashPayments.Add(cashObj);
        paymentEntity.GiftCouponPayments = new System.Data.Linq.EntitySet<DBML_Project.GiftCouponPayment>();
        paymentEntity.GiftCouponPayments.Add(giftCouponObj);
        Repository.InsertEntity(paymentEntity);
        Repository.SubmitChanges();
    }
}
Repository:
public class LijosPaymentRepository : ILijosPaymentRepository
{
    public System.Data.Linq.DataContext MyDataContext { get; set; }
    public void InsertEntity(DBML_Project.Payment payment)
    {
        //Insert the entity
        MyDataContext.GetTable<DBML_Project.Payment>().InsertOnSubmit(payment);
    }
    public void SubmitChanges()
    {
        MyDataContext.SubmitChanges();
    }
}
 
     
     
     
     
    