我有一个数据库的关系如下图所示。基于LINQ to SQL的ORM创建的域对象。
一个支付包括现金支付和礼券付款。假设购买的总量为550可以支付如下组分
1礼券值300
1礼券值200
我的现金货币值50
我插入使用ORM的InsertOnSubmit功能的新的缴费记录。下面code是工作的罚款。不过,如果我的公司正在使用的信用卡引入一个新的支付部分,我需要改变我的支付领域类。我如何支付类打开的扩展和关闭更改还在使用的 ORM
注:支付类有行为(例如GetTotalAmountCollected)。我试图使支付类,以满足OCP。
注:有一个特定的的行为作为优惠券类型。是发出日期的优惠券是小于1/1/2000,它不应该在为总量(即,CouponValue应为零)计算中使用。请参阅Refactoring使用策略模式code 也。
注:我使用的的.Net 4.0
参考:
Getting在使用ObjectContext.AddObject与实体框架 错误 Refactoring使用策略模式code preFER组成了继承? EF 4.1 code-第一与模型/数据库一 Strategy模式和使用Unity 依赖注入 C# Strategy设计模式所代表VS OOP 如何使用策略模式用C#? 在继承与EF code第一:第2部分 - 每个类型表(TPT) http://weblogs.asp.net/manavi/archive/2010/12/28/inheritance-mapping-strategies-with-entity-framework-$c$c-first-ctp5-part-2-table-per-type-tpt.aspxC#code:
公共类PaymentAppService
{
公共RepositoryLayer.ILijosPaymentRepository库{获得;组; }
公共无效MakePayment()
{
DBML_Project.Payment paymentEntity =新DBML_Project.Payment();
paymentEntity.PaymentID = 1;
paymentEntity.PaymentType =PurchaseP;
DBML_Project.CashPayment cashObj =新DBML_Project.CashPayment();
cashObj.CashPaymentID = 1;
cashObj.CurrencyNumber = 123;
cashObj.CurrencyValue = 100;
DBML_Project.GiftCouponPayment giftCouponObj =新DBML_Project.GiftCouponPayment();
giftCouponObj.GiftCouponPaymentID = 1;
giftCouponObj.CouponValue = 200;
giftCouponObj.CouponNumber = 124;
paymentEntity.CashPayments =新System.Data.Linq.EntitySet< DBML_Project.CashPayment>();
paymentEntity.CashPayments.Add(cashObj);
paymentEntity.GiftCouponPayments =新System.Data.Linq.EntitySet< DBML_Project.GiftCouponPayment>();
paymentEntity.GiftCouponPayments.Add(giftCouponObj);
Repository.InsertEntity(paymentEntity);
Repository.SubmitChanges();
}
}
存储库:
公共类LijosPaymentRepository:ILijosPaymentRepository
{
公共System.Data.Linq.DataContext MyDataContext {获得;组; }
公共无效InsertEntity(DBML_Project.Payment付款)
{
//将实体
MyDataContext.GetTable< DBML_Project.Payment>()InsertOnSubmit(付款)。
}
公共无效的SubmitChanges()
{
MyDataContext.SubmitChanges();
}
}
解决方案
对于@Lijo试图解决抽象的方法会更好的问题的
我想你可以实现你自己的IPayment接口,可通过整个应用程序中使用的CashPayment类型进行部分类。然后该接口也可对类:CreditCardPayment:
例如:
公共接口IPayment
{
INT标识{获取;组; }
INT PaymentId {获得;组; }
//其他支付特定属性或方法
}
公共部分类CashPayment:IPayment
{
公众诠释标识
{
{返回CashPaymentId; }
集合{CashPaymentId =价值; }
}
//其它性能
}
公共部分类类:CreditCardPayment:IPayment
{
//更多code ...
}
东西在你的EF方面得到的所有款项
公共部分类PaymentEntities //你的EF实体的名称
{
公开IQueryable的AllPayments
{
返回this.CashPayment.Union(this.CreditCardPayment); //这是不好的,但只是一个例子。抽象类的办法是更好地在这里。
}
公共无效InsertPayment(IPayment付款)
{
this.AddObject(payment.GetType()名称,付款。);
}
}
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? EF 4.1 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.aspxC# 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);
}
}
相关推荐
最新文章