在做一个评论功能的时候,发现用户的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);
}