简体   繁体   中英

How to get all previous data by using select method in EF Core

I know that my question is a bit confused, But let me explain in detail.
Suppose that I have person class like this.

public class Person {
  public int Id {get; set;}  
  public string Name {get; set;}  
}  

and I want create a new entity, but these two classes are similarly so I would like to just inherit and add some new properties

public class Employee : Person {
  public string Position {get; set;}
}

everything works fine, but I have a problem when I want to select the data from person table and add it to Employee class like this

employee = _context.Person.Select(
              a => new Employee {
              Name = a.Name,
              Position = "Programmer"
            }).ToList();  

So as you can see here, I want to add the position property, but also want the previous data from person table. The problem is, I have to type the previous data from person table manually. If the person table has a lot of properties I need to type all of that to get all data. Is there anyway to get previous data without typing all of them. So in javascript it have something like

new State = {
...State,
Position : "employee"
} 

Is it possible to do something like this in c#?

Having employee as an entity, you can use

var employees = _context.Employee.Include(e=>e.Person).ToList(); 

then you'll do it like this employees[0].Person.Name and so on.

If I understand you, you essentially want to "upgrade" an existing Person entity to an Employee entity. Unfortunately, this is not as simple or straight-forward as you would like. EF Core models inheritance via a single table with a discriminator column. That discriminator column informs what class type should actually be instantiated, when the entity is pulled from the database. Since it was saved as a Person , it will have "Person" as the value there, and EF Core will instantiate a Person instance when you retrieve it from the database.

You can then potentially downcast it to Employee , but EF Core isn't going to know what to do with this. Technically, the downcast instance will be untracked. If you attempt to track it, you'll get an error on saving as EF Core will attempt to add a new Employee with the same PK as an existing Person . Boom.

Your best bet is to map over the data from the Person instance to a new Employee instance, including all associated relationships. Then, create the Employee , causing the relationships to be moved at the database-level, before finally removing the old Person .

This will of course result in a new PK being assigned (which is why it's important to migrated the related entities), and that could potentially be problematic if you've got URLs referencing that PK or if you're simply dealing with an auto-increment PK. You'll end up leaving gaps in the keys, and could potentially even run out of keys, if you do this enough.

The only other potential alternative is to change the value of the discriminator column. This would have to be done via straight SQL, as the discriminator column is a shadow property not exposed by EF Core (ie there's no way to modify it via C# code). However, if you literally change the value to something like "Employee", then when you fetch it, EF will create an Employee instance, just will all the Employee -specific properties null or default. However, at that point, you can make the necessary updates and save it back.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM