多个可为空的复合外键

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 外键组成的复合键是一个简单的灾难性想法。只需使用常规的 identityuniqueidentifier 列作为主键,就可以了。 你为什么把它放在 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 属性,但不能包含集合。

【讨论】:

非常感谢!

以上是关于多个可为空的复合外键的主要内容,如果未能解决你的问题,请参考以下文章

SQL 在 Where 子句中处理可为空的外键

将可为空的 int 映射到可为空的 int + automapper

检查可为空的布尔值是不是为空[重复]

如何从数据库中获取可为空的 DateTime

为啥 TargetNullValue 更新可为空的 Source

SqlCeCommand 可为空的值