Entity Framework TPC Inheritance (Please shoot me now)

I am trying to build an entity model and database based on objects defined at http://www.schema.org using Code First and Migrations. In the bottom line, all entities are inherited from the Thing entity.

Migrations create a database, but any attempt to displace the database failed.

Everything inherits from Thing:

namespace Entities.Models { public class Thing { public Thing() { Id = Guid.NewGuid(); Name = String.Empty; } public Guid Id { get; set; } public virtual string Name { get; set; } } public class Person : Thing { public Person() : base() { Friends = new List<Person>(); } public string GivenName { get; set; } public string FamilyName { get; set; } public string Email { get; set; } public virtual ICollection<Person> Friends { get; set; } } public class Event : Thing { public Event() : base() { Attendees = new List<Person>(); } public virtual ICollection<Person> Attendees { get; set; } public TimeSpan Duration { get; set; } public DateTime? endDate { get; set; } public DateTime? StartDate { get; set; } } public class ThingMap : EntityTypeConfiguration<Thing> { public ThingMap() { // Primary Key this.Property(t => t.Id) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); // Properties this.Property(t => t.Name) .IsOptional() .HasMaxLength(200); // Table & Column Mappings this.ToTable("entity_Thing"); } } public class PersonMap : EntityTypeConfiguration<Person> { public PersonMap() { // Properties this.Map<Person>(t => { t.MapInheritedProperties(); t.ToTable("entity_Person"); }); // Table & Column Mappings } } public class EventMap : EntityTypeConfiguration<Event> { public EventMap() { // Properties this.Map<Event>(t => { t.MapInheritedProperties(); t.ToTable("entity_Event"); }); // Table & Column Mappings } } public class CitriusSpotsContext : DbContext { static CitriusSpotsContext() { Database.SetInitializer<CitriusSpotsContext>(null); } public CitriusSpotsContext() : base("Name=CitriusSpotsContext") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new ThingMap()); modelBuilder.Configurations.Add(new PersonMap()); modelBuilder.Configurations.Add(new EventMap()); } public DbSet<Thing> Things { get; set; } public DbSet<Person> People { get; set; } public DbSet<Event> Events { get; set; } } } 
+4
source share
2 answers

I am currently working with a similar model, I know this answer is delayed, but it may help.

To run, TPH, TPT and TPC are inheritance modeling mechanisms in our databases. If we do not need to model inheritance for polymorphic queries, updates, or persistence, we do not need to follow the TP * conventions.

Let me repeat that. TPH, TPT, and TPC are optional database inheritance modeling strategies. If our application does not require polymorphic queries, updates or insertions, we do not need to follow the TP * conventions.

My basic project setup is very similar to yours. In my project, I have an abstract class from which every class in my project inherits. It is called XModelBase , and I believe that it matches your Thing class.

I use this abstract class to implement some basic methods that link my business validation with the Entity Framework validation engine. This class also ensures that audit values ​​are fixed for each object, and the class contains other generic properties (KeyId), and also provides a prototype / template for generic processes.

The only real difference between our models is that my XModelBase has an int as the data type for the primary key (which all classes subsequently inherit), while you use the Guid data type for your primary key.

If I'm right, you and I will never need to complete a query that looks like this:

Scenario 1:

 var query = from t in context.Things select t; 

This type of request does not make sense in our scenario. Why do we want to select every object in our database? We would not do this, and we will not

We will also never save objects through our abstract class, for example:

Scenario 2:

 var person = new Person() {Email = " something@somewhere.com "}; context.Things.Add(person); 

Instead, we simply do the following:

Scenario 3:

 var person = new Person() {Email = " something@somewhere.com "}; context.People.Add(person); 

Since we don’t need to host either Scenario 1 or Scenario 2 , we don’t need Things be a separate table base (TPT). We also do not need or do not need access or saving our subclassed tables in the TPC invisible polymorphic mode; therefore, when you think about it, we really do not need the following property:

 public DbSet<Thing> Things { get; set; } 

We only need this DbSet property in our object context, when we want / should model polymorphic associations.

Removing this property from our context and getting rid of our model configuration for the base class is the first step to freedom of inheritance.

Then we will remove MapInheritedProperties() from our subclass model configurations because the inherited properties will be displayed automatically. We simply leave our .ToTable designation .ToTable our subclass objects.

Again I have an int for my primary key of XModelBase base classes, so I can just mark it with the [Key] attribute, for example:

 [Key] public int KeyId { get; set; } 

But since I am not creating a table or using DbSet for my XModelBase class, all inheriting subclasses will have independent automatically incrementing primary keys that were configured using this [Key] attribute in my XModelBase class.

If I understand your question correctly, this information should point you in the right direction, but if I didn’t address your question, I would be interested to know how you decided to solve the problems.

Hope this helps!

+3
source

It seems you are working on a code-based approach and trying to generate your schema as C # classes.

To use the code first, your base class must inherit from DbContext, and then you can create proper methods for exchanging data with the database.

In your case, Thing should be inherited from DbContext, as this will be your repository, and then you can start creating your entities.

Objects are simple classes of objects, so you can inherit them from any other class. An exemplary structure may be as follows:

 class Thing : DbContext { public DbSet<Product> Products { get; set; } } class Product { public int Id { get; set; } public int ProductName { get; set; } } 

For more information http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspx and http: // www. codeproject.com/Articles/318010/Entity-Framework-Code-First-Let-s-Try-It

Hope this helps.

-1
source

All Articles