多个可为空的复合外键
Posted
技术标签:
【中文标题】多个可为空的复合外键【英文标题】:Multiple nullable composite foreign keys 【发布时间】:2016-09-12 14:35:17 【问题描述】:我在 MVC 项目中使用实体框架 6.1 和代码优先方法。
public class PackageDaySchedule
public int Id get;set;
public DateTime Time get;set;
Public int PackageId get;set;
Public int? PackageCityget;set;
public int? PackageHotelId get;set;
Public int? PackagePlaceToVisitId get;set;
//navigation property
public virtual Package get;set;
public virtual PackageCity Package City get;st;
public virtual PackageHotel PackageHotel get;st;
public virtual PackagePlaceToVisit PackagePlaceToVisitget;set;
Public class Package
Public int PackageId get;set;
Public List<PackageCity> PackageCities get;set;
Public class PackageCity
[Key, Column(Order = 0)]
Public int PackageId get;set;
[Key, Column(Order = 1)]
public int CityId get;set;
public List<PackageHotel> PackageHotels get;set;
//virtual properties - Package and City
Public class PackageHotel
[Key, Column(Order = 0)]
Public int PackageId get;set;
[Key, Column(Order = 1)]
public int CityId get;set;
[Key, Column(Order = 2)]
Public int HotelId get;set;
//virtual properties - Package,City, Hotel
对于一个 PackageDaySchedule,应该有一个 packageCity 或 packagehotel 或 PackagePlaceToVist。我的问题是如何使用数据注释为 PackageDayShedule 表指定外键。 PackageId 常见于 PackageCity、PackageHotel 和 PackagePlaceToVist 导航属性。
【问题讨论】:
首先,使用复合键几乎总是一个坏主意。其次,使用由外键组成的复合键总是是个坏主意。第三,使用由 nullable 外键组成的复合键是一个简单的灾难性想法。只需使用常规的identity
或 uniqueidentifier
列作为主键,就可以了。
你为什么把它放在 MVC 中?
@ChrisPratt 非常感谢您的提示。我会根据你的建议改变设计。
@ChrisPratt 如果你不介意,你能解释一下为什么我不应该对 PackageCIty 表使用复合键。 PackageCity 是 Package 和 City 实体之间的多对多关联(中间)表。 (PackageHotel 是 City & Hotel 实体的多对多中间表)
连接表上的复合键通常是可以的。因此,我为此说“几乎总是一个坏主意”。但是,在您计划直接查询的表上使用复合键,尤其是如果您要与这些表建立进一步的关系时,这种情况开始迅速失控。
【参考方案1】:
关于数据库表如何在asp mvc模型中表示的总结
模型如何表示数据库表
在接下来的部分中,我将解释如何从代码优先应用程序为数据库创建数据模型,并介绍如何在 ASP MVC 中表示关系。
在此示例中,我们有三个具有以下架构的表:
学生桌
学生 ID、姓氏、名字、注册日期
课程表
CourseID、标题、学分
报名表
EnrollmentID、CourseID、StudentID、Grade
这些表中的每一个都必须在一个单独的模型中表示。
学生桌
public partial class Student
public int StudentID get; set;
public string LastName get; set;
public string FirstName get; set;
public Nullable<System.DateTime> EnrollmentDate get; set;
public virtual ICollection<Enrollment> Enrollments get; set;
公共虚拟注册是一个导航属性,其中包含与该实体相关的其他实体,例如在我们的案例中,学生实体将保存与他相关的所有注册实体的数据。
提示:具有 1:M 关系且位于 1 侧的表,其模型表示应包含 M 表的导航属性,并且应为集合
课程表 和学生一样
3.注册表
public partial class Enrollment
public int EnrollmentID get; set;
public Nullable<decimal> Grade get; set;
public int CourseID get; set;
public int StudentID get; set;
public virtual Course Course get; set;
public virtual Student Student get; set;
SudentID 属性是外键,对应的导航属性是 Student。一个注册实体与一个学生实体相关联,因此该属性只能保存一个学生实体,这就是我们没有使用 IEnumerable 的原因。 courseID 属性也是如此。
提示:M 侧的表应包含外键和对应的 Navigation 属性,但不能包含集合。
【讨论】:
非常感谢!以上是关于多个可为空的复合外键的主要内容,如果未能解决你的问题,请参考以下文章
将可为空的 int 映射到可为空的 int + automapper