问题描述
我有一个数据库关系如下所示。域对象是基于LINQ to SQL ORM创建的。付款包括现金付款和礼品券付款。假设购买总额为550.可以支付以下组件
1礼品券价值300
1礼品券价值200
我现金货币价值50
我正在插入新的付款使用ORM的InsertOnSubmit功能记录。以下代码正常工作。但是,如果我公司正在使用信用卡引入新的付款组件,我需要更改我的付款域类。仍然使用 ORM ,
如何使支付类别开启扩展和关闭更改注意:付款类有行为(例如GetTotalAmountCollected)。我正在努力使付款类满足OCP。
注意:优惠券类型有一个特定的行为。优惠券发行日期小于1/1/2000,不应用于总金额的计算(即CouponValue应为零)。请参阅。
注意:我正在使用 .Net 4.0
参考:
- 继承EF代码首先:第2部分 - 每种类型表(TPT)
- 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#代码:
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:
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);
}
}
这篇关于使实体类关闭以进行更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!