1

私は次のクラスを持っています:

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がナビゲーションプロパティを処理する方法についての私の仮定が間違っているのでしょうか、それともこのパズルのピースが欠けているだけでしょうか?

ありがとう。

4

2 に答える 2

2

保存する前に、参照を新しい ID と同期させたいというあなたのコメントを読みました。しかし、これは EF が自動的に行うものではありません。allrightを呼び出したときに発生しますがSaveChanges、その前に発生させたい場合は、呼び出す必要があります

_context.ChangeTracker.DetectChanges();

DbContext( APIを使用することを前提としています)

DetectChanges外部キーに関連するすべてのプロパティを同期するプロセスであるリレーションシップの修正をトリガーします。

ところで:これを成功させるためにジョブをプリロードする必要はありません。

于 2012-12-12T16:36:21.757 に答える
1

SaveChanges()データベースに永続化するには、次のように呼び出す必要があります。

_job.JobId = 23;

_context.SaveChanges();

// _job.Job now points to Job 23

これは、Job 23 がすでに にロードされているためにのみ機能しますDbContext

オブジェクトが読み込まれている場合、呼び出し時に EF がプロパティをフックします。SaveChanges()


編集:

すべてのジョブをロードしたので、自分でプロパティを設定するだけです:

_job.Job = _context.Set<Jobs>().Find( 23 );

これはデータベース呼び出しにはなりません - それはあなたから満たされますDbContext

呼び出すと同じUPDATEステートメントになりますSaveChanges()

于 2012-12-12T16:26:52.803 に答える