在做一個評論功能的時候,發現用戶的id不對,打開數據庫一看,莫名其妙的新增了幾個用戶。明顯是將外鍵中的用戶新增到用戶表中了。
評論表:
public class CourseComment : BaseModel { public string Content { get; set; } [ForeignKey("UserId")] public virtual User FormUser { get; set; } public virtual int UserId { get; set; } public virtual CourseComment ReplayComment { get; set; } /// <summary> /// 父組 /// </summary> public int CourseId { get; set; } [Required] [ForeignKey("CourseId")] public virtual Course Course { get; set; } }
var user = GetUserById(id); var com = new CourseComent() { Content = comment, CourseId = id, FormUser = user }; _comRepository.Add(com);
//add public bool Add(CourseComent comment) { if (comment == null || string.IsNullOrEmpty(comment.Content)) return false; _db.CourseComents.Add(comment); _db.SaveChanges(); return true; }
而原因就是user和comment不是在一個上下文中。 修改一下add方法:
public bool Add(CourseComent comment) { if (comment == null || string.IsNullOrEmpty(comment.Content)) return false; var u = _db.Users.Find(comment.FormUser.Id); comment.FormUser = u; _db.CourseComents.Add(comment); _db.SaveChanges(); return true; }
這個時候添加 就不會出現新增了。我們也可以看到兩個對象的哈希值是不一樣的。
我曾試圖重寫對象的對比方法和GetHashGode方法,讓這兩個值一樣只要是id相同的話。但EF還是不識別,不知道它判斷的對象的方法是什么。在有外鍵的操作中,一定要保持在同一個上下文中,也是同一個db對象下。
但是,上面的寫法讓人不舒服,要取出來再賦值一次,其實只用賦值Id就行了。
model.UserId = GetCurrentUser().Id;
另外,一個對象有兩個以上的外鍵的時候,會報錯,這個時候要取消級聯刪除。保留一個外鍵級聯刪除就行。
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<User>().HasMany(t => t.Notes).WithRequired(p => p.User).WillCascadeOnDelete(false); base.OnModelCreating(modelBuilder); }