Solution 1:

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

Solution 2:

Maybe one alternative would be to take advantage of Inheritance, in the ORM as well. So that instead of having N collections, one for each type in the Payment Entity. You would have all of the subtypes in the same collection. And all those, added up would represent the entire Payment.

Maybe it would be easier to name things a bit differently. For example, let's consider the concept of a Purchase. Purchase should have a collection of Payments. And Payment could be an abstract class, from which Cash, Coupon, CreditCard, all inherit.

Having the model set up that way opens a great deal of possibilities regarding how you can solve certain problems. You can treat all payments the same and forget about distinct collections, plus have a great deal of control through polymorphism and double dispatch.

That way, if a new payment type arises, your model will remain the same, you will just have a new subtype.

Most ORMs nowadays support different persistence schemes for inheritance, that will help keep your data structure clean as well.

Solution 3:

What is the added value of creating a new type for each type of payment ? I can see the distinction between a 'Payment by money', and a 'Payment done via a voucher'. I can agree to have two different types to make that distinction.

However, why make the distinction between a CashPayment, a CreditCardPayment, etc ... ? Do you have to store extra information depending on the type of payment ? Does the behaviour change ?

Why don't you just keep it simple, and add an extra property to the regular 'Payment' type, which acts as a discriminator and gives you the information how the payment was made (via creditcard, cash, .... ) ?

public class Payment {}

public class VoucherPayment : Payment {}

public class MoneyPayment : Payment
{
    public PaymentMode { get; set; }
}

public enum PaymentMode 
{
    Cash,
    CreditCard
}