关闭实体类以进行更改 [英] Making Entity Class Closed for Changes

查看:21
本文介绍了关闭实体类以进行更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a database relationship as shown below. The domain objects are created based on LINQ to SQL ORM.

付款包括现金付款和礼券付款.假设购买总金额为550,可按以下方式支付

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

我正在使用 ORM 的InsertOnSubmit"功能插入新的付款记录.以下代码工作正常.但是,如果公司使用信用卡引入新的支付组件,我需要更改我的支付"域类.如何使付款类对延期开放,对变更封闭仍然使用 ORM?

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?

注意:Payment 类具有行为(例如 GetTotalAmountCollected).我正在尝试制作付款"课程以满足 OCP.

Note: The Payment class has behaviors (E.g. GetTotalAmountCollected). I am trying to make the "Payment" class to satisfy OCP.

注意:优惠券类型有特定的行为.如果 Coupon 发行日期小于 1/1/2000,则不应用于计算 Total Amount(即 CouponValue 应为零).另请参阅使用策略模式重构代码.

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.

注意:我使用的是 .Net 4.0

参考:

  1. 使用 ObjectContext.AddObject 时出错实体框架
  2. 使用策略模式重构代码
  3. 更喜欢组合而不是继承?
  4. 代码优先与模型/数据库优先
  5. 使用 Unity 的策略模式和依赖注入
  6. Delegate 与 OOP 的 C# 策略设计模式
  7. 如何在 C# 中使用策略模式?
  8. EF Code First 的继承:第 2 部分 – 每个类型的表 (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# 代码:

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();
    }
}

存储库:

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();
    }
}

推荐答案

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

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

I think you can make a partial class on the CashPayment type that implements your own IPayment interface, which can be used through the whole application. This interface can then also be on 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 ...
}

在您的 EF 上下文中获取所有付款的内容

Something on your EF context to get all payments




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);
    }
}

这篇关于关闭实体类以进行更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆