I have been working on a project in which I am trying to mold entity framework to an existing FoxPro 2.x database in order to use the data while leaving the tables readable to a legacy application (more details on my previous question).
I've had pretty good luck configuring the DBContext to the physical data tables and I have most of my mapping set up. The legacy data structure has a Bills table with a unique primary Id key, but all the LineItems that can be posted to a bill are stored in a single Charges table without a simple primary key.
My question pertains to discriminator mapping in code-first EF. I am recreating the table as TPH in my data objects, so I have
public abstract class Posting
{
public System.DateTime? Post_Date { get; set; }
public string Bill_Num { get; set; }
public string Type { get; set; }
public string Pcode { get; set; }
public string Pdesc { get; set; }
public decimal? Custid { get; set; }
public string Createby { get; set; }
public System.DateTime? Createdt { get; set; }
public string Createtm { get; set; }
public string Modifyby { get; set; }
public System.DateTime? Modifydt { get; set; }
public string Modifytm { get; set; }
public string Linenote { get; set; }
public decimal? Version { get; set; }
public string Id { get; set; }
public string Batch { get; set; }
public virtual Billing Bill { get; set; }
}
public abstract class Charge : Posting
{
}
public class ServiceLine : Charge
{
public string Chargeid { get; set; }
public virtual ICollection<Payment> Payments { get; set; }
}
public class ChargeVoid : Charge
{
}
public abstract class Payment : Posting
{
}
public class PaymentLine : Payment
{
public string Postid { get; set; }
public string Svc_Code { get; set; }
public string Name { get; set; }
public string Checkno { get; set; }
public System.DateTime? Checkdate { get; set; }
}
public class PaymentVoid : Payment
{
}
where my mapping strategy so far is along these lines:
public class PostingMap : EntityTypeConfiguration<Posting>
{
public PostingMap()
{
// Primary Key
this.HasKey(t => new {t.Bill_Num, t.Post_Date, t.Pcode});
this.Map<Charge>(m => m.Requires("Type").HasValue("C"))
.ToTable("Charges");
this.Map<Payment>(m => m.Requires("Type").HasValue("P"))
.ToTable("Charges");
}
}
I have omitted some fields and mapping classes, but this is the core of it.
Every record has the C/P classification, so this makes everything in the table either a Charge or a Payment.
Every Posting is associated with a Bill via Bill_Num foreign key.
The ServiceLine object is only distinct from ChargeVoid objects (which are adjustment entries and no-value information entries associated with a bill) by having values for Pcode and Chargeid (which is just Bill_Num tagged with 01++). I have no idea how to model this.
It is very similar for the Payment hierarchy as well.
So with my current setup, I have Postings which doesn't have a unique key, Charges which has a subset of ServiceLines with values for Chargeid and Pcode and a subset with nulls, and Payments similar to Charges. PaymentLines are also many-to-one with ServiceLines by way of Pcode while PaymentVoids have Pcode = null.
Is there a way I can assign this complex mapping since I can't simply discriminate on !null? On top of that, will EF handle the key assignments once I get the inheritance set up, or am I going to have issues there as well?
Also, if there is a better way to break this object inheritance down, I am all ears.