简体   繁体   English

如何使用EF Core中的select方法获取所有以前的数据

[英]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类时遇到问题

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. 因此,如您在此处看到的,我要添加position属性,但也要从人员表中获取先前的数据。 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 所以在javascript中有类似

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

Is it possible to do something like this in c#? 是否可以在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. 那么您将像这样的employees[0].Person.Name等进行操作。

If I understand you, you essentially want to "upgrade" an existing Person entity to an Employee entity. 如果您了解我的意思,那么您实质上是想将现有的Person实体“升级”到Employee实体。 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. EF Core通过带有歧视项列的单个表对继承进行建模。 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. 由于已将其保存为Person ,因此它将以“ Person”作为值,并且当您从数据库中检索它时,EF Core将实例化Person实例。

You can then potentially downcast it to Employee , but EF Core isn't going to know what to do with this. 然后,您可以将其转换为Employee ,但EF Core将不知道如何处理。 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 . 如果尝试跟踪它,则保存时会出错,因为EF Core会尝试添加与现有Person PK相同的新Employee Boom. 繁荣。

Your best bet is to map over the data from the Person instance to a new Employee instance, including all associated relationships. 最好的选择是将Person实例中的数据映射到新的 Employee实例,包括所有关联的关系。 Then, create the Employee , causing the relationships to be moved at the database-level, before finally removing the old Person . 然后,创建Employee ,使关系在数据库级别移动,最后移除旧的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. 当然,这将导致分配新的PK(这就是为什么迁移相关实体很重要的原因),并且如果您有引用该PK的URL或只是在处理自动增加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). 这必须通过直接的SQL来完成,因为discriminator列是EF Core不公开的shadow属性(即无法通过C#代码对其进行修改)。 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. 但是,如果从字面上将值更改为类似于“ Employee”的值,则在获取它时,EF将创建一个Employee实例,所有Employee特定的属性都将为null或默认值。 However, at that point, you can make the necessary updates and save it back. 但是,此时,您可以进行必要的更新并将其保存回去。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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