我正在学习EF Code First,在更新现有记录时遇到了麻烦。我把它归结为这个简单的例子:
这有效:
using(var db = new DataContext()){
var p = db.People.Find(1);
p.Name="New Name";
Console.WriteLine(p.Gender.Name); //<--Unnecessary property access
db.SaveChanges(); //Success
}
...但是这失败了(当删除WriteLine时):
using(var db = new DataContext()){
var p = db.People.Find(1);
p.Name="New Name";
db.SaveChanges(); //DbValidationError "Gender field is required."
}
如果我没有使用它并且数据已经正确存储在数据库中,为什么我必须访问/加载Gender属性?我只想更改现有记录上的名称。在此示例中,Gender是在People表中存储为Gender_Id的一对多关联。这些类的定义如下:
public class Person
{
[Key]
public int PersonId { get; set; }
[Required, MaxLength(50)]
public string Name { get; set; }
[Required, Column("Gender")]
virtual public GenderCode Gender { get; set; }
}
public class GenderCode
{
[Key]
public int Id { get; set; }
[Required, MaxLength(10)]
public string Name { get; set; }
}
public class DataContext:DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<GenderCode> GenderCodes { get; set; }
}
当然,完全定义的类要有更多的字段。每次我想要修改一个不相关的值时,我宁愿不必访问每个依赖属性。
有没有办法加载对象,更改字段并保存它而不先加载所有相关对象?
答案 0 :(得分:1)
是的,这是必要的,因为EF中有一些可怕的设计错误。
查看我的类似问题EF: Validation failing on update when using lazy-loaded, required properties
一个技巧是声明FK属性以及OO关系:
[ForeignKey("GenderId"), Column("Gender")]
virtual public GenderCode Gender { get; set; }
[Required]
public int GenderId { get; set; }
答案 1 :(得分:0)
这是因为您正在使用数据注释,Required
属性对验证也有意义。通过数据注释将导航属性设置为Required
后,当您要将实体持久保存到数据库时,必须填充/加载它。