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

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

问题描述

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



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

  1礼品券价值300 

1礼品券价值200

我现金货币价值50



我正在插入新的付款使用ORM的InsertOnSubmit功能记录。以下代码正常工作。但是,如果我公司正在使用信用卡引入新的付款组件,我需要更改我的付款域类。仍然使用 ORM



如何使支付类别开启扩展和关闭更改注意:付款类有行为(例如GetTotalAmountCollected)。我正在努力使付款类满足OCP。



注意:优惠券类型有一个特定的行为。优惠券发行日期小于1/1/2000,不应用于总金额的计算(即CouponValue应为零)。请参阅使用策略模式重建代码



注意:我正在使用 .Net 4.0



参考:


  1. 获取错误当使用ObjectContext.AddObject与实体框架

  2. 使用策略模式重构代码

  3. 喜欢组合继承?

  4. 代码优先与模型/数据库优先


  5. C#由代表vs OOP的策略设计模式

  6. 如何使用C#中的策略模式

  7. 继承EF代码首先:第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


  8. C#代码:

      public class PaymentAppService 
    {
    public RepositoryLayer.ILijosPaymentReposi tory存储库{get;组; }

    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;组;

    public void InsertEntity(DBML_Project.Payment payment)
    {
    //插入实体
    MyDataContext.GetTable< DBML_Project.Payment>()。InsertOnSubmit );
    }

    public void SubmitChanges()
    {
    MyDataContext.SubmitChanges();
    }
    }


    解决方案

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



    我认为你可以对实现的CashPayment类型进行部分类您自己的IPayment接口,可以通过整个应用程序使用。此接口也可以在CreditCard付款:



    示例:

      

    public interface IPayment
    {
    int Id {get;组; }
    int PaymentId {get;组; }
    //其他付款特定属性或方法
    }

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

    //其他属性

    }

    公共部分类CreditCard付款:IPayment
    {
    //更多代码...
    }

    您的EF上下文获得所有付款

      


    公共部分类PaymentEntities //您的名称EF实体
    {
    public IQueryable AllPayments
    {
    return this.CashPayment.Union(this.CreditCardPayment); //这不好,只是一个例子。抽象类的方法在这里会更好。
    }

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


    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:

    1. Getting an error when using ObjectContext.AddObject with Entity Framework
    2. Refactoring code using Strategy Pattern
    3. Prefer composition over inheritance?
    4. Code-first vs Model/Database-first
    5. Strategy Pattern and Dependency Injection using Unity
    6. C# Strategy Design Pattern by Delegate vs OOP
    7. How to use the Strategy Pattern with C#?
    8. 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();
        }
    }
    

    解决方案

    For the problem that @Lijo tries to solve the abstract approach would be better

    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:

    Example:

    
    
    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 ...
    }
    
    

    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天全站免登陆