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 null
s, 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.