使实体类关闭以进行更改

LCJ*_*LCJ 7 .net c# domain-driven-design entity-framework linq-to-sql

我有一个数据库关系,如下所示.域对象是基于LINQ to SQL ORM创建的.

付款包括现金付款和礼品券付款.假设购买总额为550.可以按以下组件支付

1 Gift Coupon Valued 300

1 Gift Coupon Valued 200

I Cash Currency Valued 50
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我正在使用ORM的"InsertOnSubmit"功能插入新的付款记录.以下代码工作正常.但是,如果我公司使用信用卡引入新的支付组件,我需要更改我的"付款"域类.如何使支付类打开以进行扩展并关闭仍在使用ORM的更改

注意:Payment类具有行为(例如GetTotalAmountCollected).我正在努力使"付款"类满足OCP.

注意:优惠券类型有特定的行为.优惠券发行日期是否小于2000年1月1日,它不应用于计算总金额(即,CouponValue应为零).请参阅使用策略模式重构代码.

注意:我使用的是.Net 4.0

参考:

  1. 将ObjectContext.AddObject与Entity Framework一起使用时出错
  2. 使用策略模式重构代码
  3. 喜欢构成而不是继承?
  4. 代码优先与模型/数据库优先
  5. 使用Unity的策略模式和依赖注入
  6. 委托与OOP的C#策略设计模式
  7. 如何在C#中使用策略模式?
  8. 继承与EF代码第一:第2部分-每个类型表(TPT) http://weblogs.asp.net/manavi/archive/2010/12/28/inheritance-mapping-strategies-with-entity-framework-code-first -ctp5部分-2-表每类型tpt.aspx

C#代码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

库:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Pre*_*hts 5

对于@Lijo试图解决抽象方法的问题会更好

我认为您可以对CashPayment类型进行部分类,该类型实现您自己的IPayment接口,可以在整个应用程序中使用.这个界面也可以在CreditCardPayment上:

例:



public interface IPayment
{
     int Id { get; set; }
     int PaymentId { get; set; }
     //Other payment specific properties or methods
}

public partial class CashPayment : IPayment
{
    public int Id 
    {
       get { return CashPaymentId ; }
       set { CashPaymentId = value; }
    }

    //Other properties

}

public partial class CreditCardPayment : IPayment 
{
   //more code ...
}

Run Code Online (Sandbox Code Playgroud)

您的EF背景上的东西可以获得所有付款




public partial class PaymentEntities //The name of your EF entities
{
   public IQueryable AllPayments
   {
      return this.CashPayment.Union(this.CreditCardPayment); //This is not good, but just an example. The abstract class approach would be better here.
   }

    public void InsertPayment(IPayment payment)
    {
         this.AddObject(payment.GetType().Name, payment);
    }
}

Run Code Online (Sandbox Code Playgroud)