This is an extension of this question which from what I can tell now works in EF6. However, it seems as though there's a problem when you've got subclasses which have both shared and unshared properties.
Let's say this is my model setup:
public abstract class Document
{
public int Id { get; set; }
public string NameOnDocument { get; set; }
}
public class BirthCertificate : Document
{
public string RegistrationNumber { get; set; }
}
public class Licence : Document
{
public string LicenceNumber { get; set; }
}
In the database, I want BirthCertificate.RegistrationNumber
and Licence.LicenceNumber
to share the same column, Number
. As such, I'm setting up my model like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Document - base class
modelBuilder.Entity<Document>().HasKey(d => d.Id);
modelBuilder.Entity<Document>()
.Property(d => d.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Document>()
.Property(d => d.NameOnDocument)
.HasColumnName("Name");
// Birth certificate
modelBuilder.Entity<Document>().Map<BirthCertificate>(map =>
map.Property(c => c.RegistrationNumber).HasColumnName("Number"));
// Licence
modelBuilder.Entity<Document>().Map<Licence>(map =>
map.Property(l => l.LicenceNumber).HasColumnName("Number"));
}
When I generate the database, it all looks and works as expected:
Now for the issue at hand. Let's say the Licence
entity also needs to record an expiry date; so I add that in as follows:
public class Licence : Document
{
public string LicenceNumber { get; set; }
public DateTime ExpiryDate { get; set; }
}
Now when I regenerate the database, it looks like this:
What's more, if I try to insert a licence and a birth certificate, I get the following exception:
An unhandled exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll
Additional information: A value shared across entities or associations is generated in more than one location. Check that mapping does not split an EntityKey to multiple store-generated columns.
I can understand why that exception is raised - because the database is useless.
What have I missed?
Ok, so it turns out that the problem is simple to solve, and yet so far as I can tell is not documented anywhere. So hopefully this will help someone with the same problem.
Seemingly, the key is that you have to map every property on the derived entity:
Now my database generates as I would expect and all is right with the world.