Entity Framework TPT - Insert sub-type for existing base-type

c# ef-code-first entity-framework-6 poco sql-server

Question

I am running into a problem where I want to insert a record for a sub-type with an existing record for the base-type.

The base-type may be a Person entity described by:

public class Person {
    [Key, Column("Id"), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public DateTime? BirthDate { get; set; }
}

with the sub-type described by: (updated: didn't really have Id field here too)

public class Employee : Person {
    public DateTime HireDate { get; set; }
}

My create can be illustrated by this:

var employee = new Employee
    {
       Id = 1,
       HireDate = DateTime.Now
    });

context.Employees.Add(employee);
context.SaveChanges();

The SQL Server database, has two tables, Persons and Employees which has a foreign key between the Id fields and the Person.Id is autogenerated.

-----------             -------------
| Persons |             | Employees |
-----------             -------------
| Id      |   1 to 0..1 | Id        |
-----------             -------------

While this is like an EF-Code First, I am implementing it manually by writing the POCO's and then creating the tables in SSMS by hand.

Now, there is a person record with Id = 1. When I try to create a new Employee, and assign the Id as 1, Entity Framework is ignoring my Id assignment and inserting a brand new Person record, using the generated Id from that to assign Id of the Employee table.

How do I create an employee record using an/relating to an existing person record? I'm really trying to explore this idea. But, if it's not possible: What is an alternative to this?

1
1
2/10/2018 11:59:17 PM

Popular Answer

Because you use the function Add, you are informing your DbContext that a new Employee is being inserted into the database and that your DbContext should generate a new value for the primary key of the your new Employee.

If it was allowed to provide an Id when adding a new item, then you could create two different Employees, both referring to the same Person. Changing the Birthday of one Employee would result in changing the Birthday of the other Employee. Surely you wouldn't want this.

Hence: when Adding an item to the DbSet, DbContext will translate this into a SQL Insert statement, which ignores your provided Id.

How do I create an employee record using an existing person record?

You specified that an Employee "is" a Person, not "has" a Person. If you create a new Employee object, you create also new Person-data. This is by object oriented design. It has nothing to do with databases. If you want a new Employee object with the same values for its Person properties, you'll have to copy the Person properties.

If you want the concept to have a new Employee without a new Person, then you should not derive, but aggregate. For Employee-Person this is a fairly strange concept, but for Employee-Address it is quite normal: An Employee lives on an Address. A new Employee might live on the same Address. You can create a new Employee and give it the same Address (not a copy!) of the original Employee. The effect is that you'll have two Employees, both having the same Address. You can even give one of the Employees a different Address, which won't effect the Address of the other Employee.

0
2/19/2018 12:29:22 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