あなたが必要...
this.Entry(person).State = EntityState.Modified;
this.Entry(person.Plan).State = EntityState.Modified;
... の状態を設定するperson
とModified
、 person は state のコンテキストにアタッチされますModified
が、関連するエンティティは stateperson.Plan
にアタッチされるためですUnchanged
。
Person
エンティティが切り離されている間にとの間の関係Plan
が変更された場合 (特にモデルのように、外部キーがプロパティとして公開されていない場合 (「独立した関連付け」))、エンティティを正しく更新することはより困難になります。基本的には、データベースから元のオブジェクト グラフを読み込み、関係が変更されている場合は切り離されたグラフと比較し、読み込まれたグラフに変更をマージする必要があります。ここに例があります(その回答の 2 番目のコード スニペットを参照してください)。
編集
動作することを示す例 (EF 5.0 を使用):
using System.Data;
using System.Data.Entity;
using System.Linq;
namespace EFModifyTest
{
public class Person
{
public int Id { get; set; }
public Plan Plan { get; set; }
public int Record { get; set; }
public int PersonTypeValue { get; set; }
}
public class Plan
{
public int Id { get; set; }
public string SomeText { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Person> Contacts { get; set; }
public DbSet<Plan> Plans { get; set; }
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
// Create a person with plan
using (var ctx = new MyContext())
{
ctx.Database.Initialize(true);
var plan = new Plan { SomeText = "Old Text" };
var person = new Person { Plan = plan, Record = 1, PersonTypeValue = 11 };
ctx.Contacts.Add(person);
ctx.SaveChanges();
}
// see screenshot 1 from SQL Server Management Studio
Person detachedPerson = null;
// Load the person with plan
using (var ctx = new MyContext())
{
detachedPerson = ctx.Contacts.Include(c => c.Plan).First();
}
// Modify person and plan while they are detached
detachedPerson.Record = 2;
detachedPerson.PersonTypeValue = 12;
detachedPerson.Plan.SomeText = "New Text";
// Attach person and plan to new context and set their states to Modified
using (var ctx = new MyContext())
{
ctx.Entry(detachedPerson).State = EntityState.Modified;
ctx.Entry(detachedPerson.Plan).State = EntityState.Modified;
ctx.SaveChanges();
}
// see screenshot 2 from SQL Server Management Studio
}
}
}
SQL Server Management Studio のスクリーンショット 1 (変更前、Person
表が左、Plan
表が右):
SQL Server Management Studio のスクリーンショット 2 (変更後、Person
表が左、Plan
表が右):
うまくいかない場合は、テスト モデルとコードに重要な違いがあるはずです。どれかわかりません。詳細を提供する必要があります。
編集 2
関係Person
を別の (既存の) に変更する場合Plan
は、元の関係をロードしてから関係を更新する必要があります。ObjectContext
独立した関連付け (モデルに FK プロパティなし) を使用すると、変更追跡を使用してのみ関係を更新できます (変更トラッカーでの関係エントリのより高度な変更は別として)。
var originalPerson = this.Contacts.Include(c => c.Plan)
.Single(c => c.Id == person.Id);
this.Plans.Attach(person.Plan);
this.Entry(originalPerson).CurrentValues.SetValues(person);
originalPerson.Plan = person.Plan;
this.SaveChanges();