我有以下课程:
public class Person {
public int Id {get; set;}
...
public ICollection<PersonalJobs> Jobs {get; set;}
}
public class PersonalJob {
public int Id {get; set;}
public int PersonId {get; set;}
public int JobId {get; set;}
public Job Job {get; set;}
public DateTime StartDate {get; set;}
...
}
public class Job {
public int Id {get; set;}
public string Description {get; set;}
...
}
现在我执行以下操作:
var _personId = 1;
var _jobId = 15;
_context.Set<Jobs>().Load(); //Pre-Load all jobs
var _person = _context.Persons.Include(p => p.Jobs.Select(j => j.Job))
.SingleOrDefault(p => p.Id == _personId);
var _job = _person.Jobs.SingleOrDefault(p => p.JobId == _jobId);
_job.JobId = 23; //Change the job that this person is tied to.
// At this point, if I try to access _job.Job.Description, it still references the old job.
因为上下文已经加载了Jobs,所以我假设当我更改ID时,EF会更新_job的导航属性。然而,这种情况并非如此。在这种情况下,_job.Job仍然引用与原始Id(15)相关联的作业。
我假设EF如何处理导航属性,或者我只是错过了这个难题中的一块,我错了吗?
感谢。
答案 0 :(得分:1)
您需要调用SaveChanges()
来持久保存到数据库:
_job.JobId = 23;
_context.SaveChanges();
// _job.Job now points to Job 23
这仅适用,因为作业23已加载到您的DbContext
。
如果加载了某个对象,EF会在您拨打SaveChanges()
修改强>
您已加载所有作业,因此您可以自行设置该属性:
_job.Job = _context.Set<Jobs>().Find( 23 );
这不会导致任何数据库调用 - 您的DbContext
当您拨打UPDATE
SaveChanges()
语句
答案 1 :(得分:1)
我刚刚在您的评论中读到您希望引用在保存之前与新ID 同步。但这是EF不会自动完成的事情。当你打电话给SaveChanges
时会发生这种情况,但是如果你想在此之前发生这种情况,你必须致电
_context.ChangeTracker.DetectChanges();
(假设您使用DbContext
API)
DetectChanges
触发 relationship fixup ,这是一个同步外键中涉及的所有属性的进程。
顺便说一句:你没有必要预先加载工作才能成功。