你需要...
this.Entry(person).State = EntityState.Modified;
this.Entry(person.Plan).State = EntityState.Modified;
...因为当您将 person 的状态设置为状态时,person
该Modified
人会附加到 state 中的上下文,Modified
但相关实体(例如person.Plan
state )会附加到该上下文中Unchanged
。
Person
如果和之间的关系在Plan
实体分离时发生了变化,则更难以正确更新实体(尤其是在您的模型中,当没有外键作为属性公开时(“独立关联”))。您基本上需要从数据库中加载原始对象图,如果关系已更改,则将其与分离图进行比较,然后将更改合并到加载的图中。这里有一个示例(请参阅该答案中的第二个代码片段)。
编辑
显示它有效的示例(使用 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
则必须加载原始关系,然后更新关系。使用独立关联(模型中没有 FK 属性),您只能通过使用更改跟踪来更新关系(除了ObjectContext
更改跟踪器中关系条目的更高级修改):
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();