Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 当我更改Id时,EF导航属性似乎没有更新_.net_Entity Framework - Fatal编程技术网

.net 当我更改Id时,EF导航属性似乎没有更新

.net 当我更改Id时,EF导航属性似乎没有更新,.net,entity-framework,.net,Entity Framework,我有以下课程: 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 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.
因为上下文已经加载了作业,所以我假设在我更改ID时EF会更新_job的导航属性。但是,情况并非如此。在这种情况下_job.job仍然引用与原始Id 15关联的作业

我对EF如何处理导航属性的假设是错误的还是我在这个难题中遗漏了一块

谢谢。

您需要调用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中得到满足


当您调用SaveChanges时,它将产生相同的UPDATE语句。我刚刚在您的注释中读到,您希望在保存之前,引用与新id同步。但EF并不是自动做到这一点的。当您调用SaveChanges时会发生这种情况,但如果您希望在这之前发生这种情况,则必须调用SaveChanges

_context.ChangeTracker.DetectChanges();
假设您使用DbContext API

DetectChanges触发关系修复,这是一个同步外键中涉及的所有属性的过程


顺便说一句:你不必预先加载作业就可以成功。你到底想做什么?你是不是想改变这家伙的工作?你用哪种方法来构建数据库表?我是说,代码优先还是模型优先??但是,在任何一种情况下,EF都会生成一个关于实体键的错误…是的,我正在尝试更改这家伙的工作。然后我需要进行验证,但我的验证需要访问作业本身的一些属性。我希望在将任何内容持久化到数据库之前进行验证。正如您在上面的评论中所看到的,在将更改持久化到数据库之前,我需要引用新作业。有没有办法让EF在不调用SaveChanges的情况下连接属性?这基本上就是我正在做的。。。只是不明白进行更新需要SaveChanges或基于Gert的回答DetectChanges。谢谢汉克斯·格特。我真的很喜欢DetectChanges的简单性。。。如果我对许多实体进行了更改,并希望所有导航属性都得到更新,而不是必须对每个实体执行。查找,那么这将非常有用。我会记住这一点