之前也遇到过类似的问题,属于Code First中稍微复杂点的关系处理,现将解决方法记录下来。
场景:
某网上书城欲推出书券功能,书券购买之后,会有一个唯一的Id,可用来直接兑换某本书。书券可以自己兑换,也可以将ID送给朋友来兑换。现在我们需要将书券的购买者和兑换者都记录下来。
类的设计和注意事项:
public class BookCoupon
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Index("BookCouponIdIndex")]
public Guid BookCouponId { get; set; }
[Index("BookIdIndex")]
public int BookId { get; set; }
[ForeignKey("BookId")]
public virtual Book Book { get; set; }
[Index("BuyUserIdIndex")]
public string BuyUserId { get; set; }
[ForeignKey("BuyUserId")]
public virtual User BuyUser { get; set; }
[Index("RedeemUserIdIndex")]
public string RedeemUserId { get; set; }
[ForeignKey("RedeemUserId")]
public virtual User RedeemUser { get; set; }
public DateTime BuyTime { get; set; }
public DateTime RedeemTime { get; set; }
}
public class User
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Index("UserIdIndex")]
public Guid UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<BookCoupon> BuyCoupons { get; set; }
public virtual ICollection<BookCoupon> RedeemCoupons { get; set; }
......
}
另外,在DbContext中需要override OnModelCreating方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.BuyCoupons).WithRequired(n => n.BuyUser).WillCascadeOnDelete(false);
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.RedeemCoupons).WithRequired(n => n.RedeemUser).WillCascadeOnDelete(false);
}
注意最后的.WillCascadeOnDelete(false)
,因为在这样多对多的绑定中,使用级联删除会报错。
by HADB @ Newegg