2014-09-19 211 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