Rya*_*ndy 28 c# entity-framework ef-code-first entity-framework-4.1
我正在使用Entity Framework 4.1(代码优先)开展一个小型示例项目.我的课程看起来像这样:
public class Context : DbContext
{
public IDbSet<Person> People { get; set; }
public IDbSet<EmployeeType> EmployeeTypes { get; set; }
}
public class Person
{
[Key]
public int Key { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
virtual public EmployeeType EmployeeType { get; set; }
}
public class EmployeeType
{
[Key]
public int Key { get; set; }
public string Text { get; set; }
virtual public ICollection<Person> People { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我已经将几个EmployeeTypes("first","second")保存到数据库中,并且我保存了第一个类型的Person.现在我要修改Person.我知道我可以通过加载Person,更改属性,然后保存来完成此操作.但是我想要做的事情,在我看来应该像它应该工作,是这样的:
var c = new Context();
var e = c.EmployeeTypes.Single(x => x.Text.Equals("second"));
var p = new Person {
Key = originalKey, // same key
FirstName = "NewFirst", // new first name
LastName = "NewLast", // new last name
EmployeeType = e }; // new employee type
c.Entry(p).State = EntityState.Modified;
c.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这会更改FirstName和LastName,但不会更改EmployeeType.如果我获得一个新的Context并请求此Person,那么EmployeeType将保持设置为"first",就像在此代码运行之前一样.
我需要做什么才能更新导航属性,而不仅仅是标量属性? (这尤其令人费解,因为对于EmployeeType,实际需要更改的唯一内容是Person表中的外键,并且该键是标量属性.)
(顺便说一下,我知道我可以通过首先检索Person,然后逐个更改属性来做到这一点,但是因为我在ASP.NET MVC中使用模型绑定,所以看起来这样会更容易因为我我的POST方法中已经有了更新的人物对象.)
Lad*_*nka 19
你可以尝试不同的方式:
var c = new Context();
var e = c.EmployeeTypes.Single(x => x.Text.Equals("second"));
var p = new Person {
Key = originalKey, // same key
FirstName = "NewFirst", // new first name
LastName = "NewLast"}; // new last name
c.People.Attach(p); // Attach person first so that changes are tracked
c.Entry(p).Reference(e => e.EmployeeType).Load();
p.EmployeeType = e; // Now context should know about the change
c.Entry(p).State = EntityState.Modified;
c.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
其他方法是在您的Person实体中公开外键,如:
public class Person
{
[Key]
public int Key { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[ForeignKey("EmployeeType")]
public int EmployeeTypeKey { get; set; }
public virtual EmployeeType EmployeeType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这将改变之间的关系的类型Person,并EmployeeType从独立的关联外键关联.而不是分配导航属性分配外键属性.这将允许您通过当前代码修改关系.
问题是独立关联(那些不使用外键属性)在状态管理器/更改跟踪器中作为单独的对象处理.因此,您对此人的修改并未影响现有关系的状态,也未设置新关系.我问在MSDN上如何使用的DbContext API做,但它可能只有当你施放DbContext到ObjectContext并使用ObjectStateManager和ChangeRelationshipState.