全部,是否可以为两个表使用相同的FK。可能这不是一个好习惯,但我有两个不同的课程可以预订:
public class Course {
public Course() {
BookingRefs = new HashSet<BookingRef>();
}
public long Id { get; set; }
public string Title { get; set; }
// other props ...
[InverseProperty(nameof(BookingRef.Course))]
public virtual ICollection<BookingRef> BookingRefs { get; set; }
}
public class GiftCard {
public GiftCard() {
BookingRefs = new HashSet<BookingRef>();
}
public long Id { get; set; }
public string Prop1 { get; set; }
public int Prop2 { get; set; }
// other props ...
[InverseProperty(nameof(BookingRef.Course))]
public virtual ICollection<BookingRef> BookingRefs { get; set; }
}
// this is the bookin reference for a Course or an GiftCard
public class BookingRef {
public BookingRef() {
}
public long Id { get; set; }
// other props ...
/// <summary>The item (usually the course but theoretically anything with a long id)</summary>
public long? ItemId { get; set; }
// maybe a generic Object?
[ForeignKey(nameof(ItemId))]
public Object GiftCard { get; set; }
// maybe 2 items possibly null?
[ForeignKey(nameof(ItemId))]
public Course Course { get; set; }
// maybe 2 items possibly null?
[ForeignKey(nameof(ItemId))]
public GiftCard GiftCard { get; set; }
}
从关系数据的角度考虑它。数据库如何知道“项目ID”指向哪个表?它会如何编入索引?
这将是在预订时对每个相关表使用无效FK的情况。这些FK不需要驻留在实体中,只需要驻留在导航属性中。您可以利用.Map(x => x.MapKey)
或EF Core中的.HasForeignKey("")
来利用shadow属性。
如果您希望预订仅与课程或礼品卡相关联,而不是两者兼而有之,则不会强制执行此操作。这需要在应用程序级别进行,我建议使用计划的维护任务来评估违反该规则的数据。 (查找同时包含课程ID和礼品卡ID的预订)
您可以选择保持连接“松散”并由应用程序基于类似于继承模型的鉴别器进行评估。 (ItemId + ItemType)但是,您必须根据ItemType在应用程序中单独解决关系加载,并丢失数据库中的任何FK,索引和数据完整性检查。这可能是节省添加几个FK的显着性能和维护成本。