How to insert Derived Class with Entity Framework (TPH approach)

c# entity-framework entity-framework-6

Question

Here are my classes:

public class User : Person
{
    [Required]
    public Person Person { get; set; }
    [Required]
    public string Username { get; set; }
}

[Table("Person")]
public class Person : Entity
{
    [Required]
    public List<User> Users { get; set; }
    public string Name { get; set; }
}

public class Entity
{
    [Key]
    public Guid Id { get; set; } = Guid.NewGuid();
}

Here is what I am trying now but I am not certain that it is the best way to do this.

var person1 = new Person { Name = "person1" };
var person2 = new Person { Name = "person2" };
var person3 = new Person { Name = "person3" };

var user1 = new User { Username = "sportsguy23", Person = person1};
var user2 = new User { Username = "sportsguy24", Person = person1};
var user3 = new User { Username = "sportsguy25", Person = person2};
var user4 = new User { Username = "sportsguy26", Person = person3};

context.Person.AddOrUpdate(user1);
context.Person.AddOrUpdate(user2);
context.Person.AddOrUpdate(user3);
context.Person.AddOrUpdate(user4);

After inserting the records my Person table looks like this (NULL foreign keys :/).

Person table

I realize this works but it just doesn't seem optimal. Is it possible to only have one record per User (pretty much combine the Person and User record)? If anyone has a better method for base/derived classes please let me know. Thanks in advance!

1
1
12/6/2016 5:17:28 PM

Accepted Answer

There are three methods you can implement inheritance in database.

Table per Hierarchy (TPH): This approach suggests one table for the entire class inheritance hierarchy. Table includes discriminator column which distinguishes between inheritance classes. This is a default inheritance mapping strategy in Entity Framework.

Table per Type (TPT): This approach suggests a separate table for each domain class.

Table per Concrete class (TPC): This approach suggests one table for one concrete class, but not for the abstract class. So, if you inherit the abstract class in multiple concrete classes, then the properties of the abstract class will be part of each table of the concrete class.

you can read more in here

I think what you are looking for is Table per Concrete class (TPC) which is like this :

enter image description here enter image description here

Update :

I find out your problem. you don't need to add the property Person to your User class , because it's already inherite from that class. remove it and it should work.

public class User : Person
{
    //[Required]
    //public Person Person { get; set; } Remove this line
    [Required]
    public string Username { get; set; }
}

[Table("Person")]
public class Person : Entity
{
    [Required]
    public List<User> Users { get; set; }
    public string Name { get; set; }
}
2
6/26/2016 9:10:55 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow