2014-09-19 214 views
0

我不确定这是否是一个错误,但看起来像我。我使用实体框架6.1.1代码首先,我有以下类:实体框架SaveChanges错误

public class User 
{ 
    public int Id { get; set; } 
    [Required] 
    [MaxLength(20)] 
    public string Username { get; set; } 
    [Required] 
    [MaxLength(200)] 
    public string Password { get; set; } 
    [Required] 
    public virtual Country Country { get; set; } 

} 

public class Country 
{ 
    [Key] 
    public int Id { get; set; } 
    [Required] 
    [MaxLength(3)] 
    public string CountryCode { get; set; } 
    [Required] 
    [MaxLength(20)] 
    public string CountryName { get; set; } 
} 

当我尝试更新与下面的代码的用户密码我得到一个错误:

User _user = db.Users.Find(Id); 
_user.Password = Password; 
db.Entry(_user).State = System.Data.Entity.EntityState.Modified; 
db.SaveChanges(); 

错误: 一个或多个实体的验证失败。有关更多详细信息,请参阅“EntityValidationErrors”属性。验证错误是:需要国家字段“}

的一点是,如果我这样做与物业_user.Country.Id任何交互,它的工作原理是这样的:。

User _user = db.Users.Find(Id); 
_user.Password = Password; 
Console.Write(_user.Country.Id.ToString()); 
db.Entry(_user).State = System.Data.Entity.EntityState.Modified; 
db.SaveChanges(); 

任何想法如果这是一个已知的bug或我做错了什么?

谢谢!

回答

0

用户配置了独立的关联的实体(有CountryId属性上User)中并用Required属性,这意味着Country属性需要有一个值。

此代码不会加载Country,因为它加载了延迟加载。

User _user = db.Users.Find(Id); 

除非你做类似的事情。

var country = _user.Country; // this will load the Country 

或者你可以使用预先加载主查询一起加载Country

User _user = db.Users.Include(x => x.Country).FirstOrDefault(x => x.Id == Id); 

提示:

  • _userEntityState.Modified标志是没有必要的,因为它是一个代理,变更跟踪器就会知道,如果实体将被修改。
+0

或者您可以完全禁用延迟加载。 'dbContext.Configuration.LazyLoadingEnabled = false;' – LazyTarget 2014-09-19 06:29:53

+0

谢谢!这真的解释和解决了这个问题。 – 2014-09-19 06:32:27

+0

@LazyTarget,不,重点在于'Country'必须有一个值,可以是延迟加载,急切加载,或者使用id手动设置它,并将其附加到上下文 – 2014-09-19 06:32:47

0

我从来没有明确设定当我使用实体框架的国家。如果删除线db.Entry(_user).State = System.Data.Entity.EntityState.Modified;将你的代码仍然可以工作并将数据保存到数据库?

+0

是的!我添加了这条线路来解决这个问题。如果我删除它,我会保持相同的行为。 – 2014-09-19 06:16:46