简体   繁体   English

如何在 EntityFramework 中重新加载实体?

[英]How to reload entity in EntityFramework?

I hava a classes:我有一个课程:

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

public class Student:Person{
    public string Specialisation {set;get;}
}

public class Instructor:Person{
   public decimal Salary {set;get;}
}

In database i have tables: Persons, Students, Instructors for this classes.在数据库中,我有表格:本课程的人员、学生、教师。

Now in my application i want to change one of students to instrector.现在在我的应用程序中,我想将其中一名学生更改为讲师。 I mean that i need to change entity type BUT i need to save same Id .我的意思是我需要更改实体类型但我需要保存相同的Id I did not found how to do this with EF so i just use SQL script:我没有找到如何使用 EF 执行此操作,所以我只使用 SQL 脚本:

using (var command = db.Database.Connection.CreateCommand())
            {
                if (command.Connection.State == ConnectionState.Closed) command.Connection.Open();

                if (db.Database.CurrentTransaction != null)
                    command.Transaction = db.Database.CurrentTransaction.UnderlyingTransaction;

                command.CommandText = $@"delete from [dbo].[Students] where Id = @id;
                                        insert into [dbo].[Instructors](Id) values(@id)";

                command.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { Value = myId });
                command.ExecuteNonQuery();
            }

But when i tried to got this new Instructor in same context i got error:但是当我试图在相同的上下文中获取这个新 Instructor 时,我得到了错误:

   var instructor = db.Instructors.FirstOrDefault(t=>t.Id = myId);

   All objects in the EntitySet 'myContext.Person' must have unique primary keys. However, an instance of type 'Person.Instructor' and an instance of type 'Person.Student' both have the same primary key value, 'EntitySet=Person;Id=1'. 

I tried to reload base entity:我试图重新加载基础实体:

var myPerson = db.Persons.FirstOrDefault(t=>t.Id = myId);

///
my sql where i delete Student and insert Instructor
///

db.Entry(myPerson).Reload();

var instructor = db.Instructors.FirstOrDefault(t=>t.Id = myId);

But got same error.但是得到了同样的错误。 So how to make this correctly?那么如何正确地做到这一点呢?
I mean maybe my solution completly wrong?我的意思是也许我的解决方案完全错误? Or if not that how can i reload entity?或者,如果不是,我该如何重新加载实体?

A meme of Sean Bean's Boromir stating "One does not simply change an entity's type" would be appropriate.肖恩·宾 (Sean Bean) 的博罗米尔 (Boromir) 的一个模因说“一个人不会简单地改变一个实体的类型”是合适的。 When it comes to inheritance at a simple level, a Dog and a Cat can inherit from Animal, but a Dog never becomes a Cat.当涉及到简单级别的继承时,狗和猫可以从动物继承,但狗永远不会成为猫。

A Person is a entity.一个人是一个实体。 What they do is a Role, not an entity, or if it is an entity, it can be associated to that person.他们所做的是角色,而不是实体,或者如果它是实体,它可以与那个人相关联。

For instance, using Person, Instructor, Student, Course:例如,使用 Person、Instructor、Student、Course:

A Course has an instructor and students.课程有教师和学生。 If Students and Instructors extend Person then a Student's PK is a PersonId, and an instructor's PK is PersonID.如果学生和教师扩展 Person,那么学生的 PK 是 PersonId,而教师的 PK 是 PersonID。 My table structure might look something like:我的表结构可能类似于:

Person [PersonId, Name, ... common fields] Person [PersonId, Name, ... 公共字段]

Instructor [PersonId, ... instructor fields]讲师[PersonId, ... 讲师字段]

Student [PersonId, ... student fields]学生[PersonId, ... 学生字段]

Course [CourseId, InstructorPersonId, Name, ... course fields]课程[CourseId, InstructorPersonId, Name, ... 课程字段]

CourseStudent [CourseId, StudentPersonId] CourseStudent [CourseId, StudentPersonId]

Or alternatively, Person/Student/Instructor schema could be:或者,Person/Student/Instructor 模式可以是:

Person [PersonId, Role, Name, ...][PersonId, Role, Name, ...]

Where Role is a discriminator that EF can use to differentiate between an Instructor and Student inheritance.其中 Role 是 EF 可以用来区分 Instructor 和 Student 继承的鉴别器。 Either way, it's not inherently a good model because what ensures that a course's instructor is actually pointing at a Person associated to an Instructor row?无论哪种方式,它本质上都不是一个好的模型,因为什么可以确保课程的讲师实际上指向与 Instructor 行相关联的 Person? If you were to merely delete an instructor row for a person to make them a student, a course could still consider them as the instructor.如果您只是删除一个人的讲师行以使他们成为学生,课程仍然可以将他们视为讲师。

Instead, you should consider association.相反,您应该考虑关联。 People don't change, merely their roles change.人不会变,只是角色变了。 Every course needs an instructor and it will have students and there will likely be details that are specific to that instructor (qualifications) and students.每门课程都需要一位讲师,并且会有学生,并且可能会有针对该讲师(资格)和学生的详细信息。 (grades) (成绩)

Person [PersonId, Name, ...][PersonId, 姓名, ...]

Role [RoleId, Name] // Ie "Instructor" Role [RoleId, Name] // 即“讲师”

PersonRole [PersonId, RoleId] PersonRole [PersonId, RoleId]

Instructor [InstructorId, PersonId, ...] // Think of as an "Instructor Position"讲师[InstructorId, PersonId, ...] // 认为是“讲师职位”

Student [StudentId, PersonId...] // Can be thought of as a "Student Spot" Student [StudentId, PersonId...] // 可以认为是一个“Student Spot”

Course [CourseId, InstructorId, Name, ...]课程[CourseId, InstructorId, Name, ...]

StudentCourse [StudentId, CourseId]学生课程 [StudentId, CourseId ]

In this case, Instructor and Student don't inherit from Person, they are associated to a person.在这种情况下,Instructor 和 Student 不是从 Person 继承的,而是与一个人关联的。 A person can hold associations to roles which can be considered when a person could be associated to an Instructor position or not.一个人可以持有与角色的关联,当一个人可以与讲师职位关联或不关联时,可以考虑这些关联。 The application will still need to regulate rules around associations such as if an instructor position gets filled by another person, and ensuring that a course doesn't have the same "person" serving as an instructor and a student and that student spots don't switch people.该应用程序仍需要规范有关关联的规则,例如教师职位是否由另一个人填补,并确保课程中不会有同一“人”担任教师和学生,并且学生名额不会换人。 (grades don't transfer) (成绩不转移)

In this way you can create/manage instructors and students independently of the people behind them.通过这种方式,您可以独立于他们背后的人来创建/管理教师和学生。 "Student" as an entity is entirely optional, instead the CourseStudent could just associate PersonId, and stuff like grades can be associated directly to Person. “Student”作为一个实体是完全可选的,CourseStudent 可以只关联 PersonId,而成绩之类的东西可以直接关联到 Person。 The fact that a person that was a student and had grades for instance earns a role of Instructor and can be associated to an Instructor position for a course doesn't break anything.例如,一个曾经是学生并且有成绩的人获得了讲师的角色并且可以与课程的讲师职位相关联这一事实并没有破坏任何东西。

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

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