Entity Framework Code First 两个字段关联到同一张表
之前也遇到过类似的问题,属于 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)
,因为在这样多对多的绑定中,使用级联删除会报错。
评论区
在 Windows Server 2012 (R2) 上显示 “计算机”
2015-03-18
Windows Server 2012 (R2)的桌面上,默认是没有“计算机”的,而且桌面上右键也是不会出现个性化的,如下方法可以迅速打开“桌面图标设置”:
Windows 关屏小工具
2015-03-06
有时候下班的时候不想关机,有很多原因,比如有 N 个网页 Tab 开着,有些可能还需要进一步查阅,关了的话从历史里不太好找,又或者,VS 开着调试,没做完,而第二天重新跑一下要很久。于是便有了挂机。可是公然挂机其实并不好,公司有规定下班自觉关机。按显示器按钮太 LOW,高端人士怎么能用这么粗鲁的方法呢!以前我用的是设置 Windows 关屏时间,5 分钟不动鼠标就关闭屏幕。这个坏处是不够及时。有什么办法能立马关闭屏幕呢?于是找到了如下代码: