【问题标题】: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? PackageCity{get;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 PackagePlaceToVisit{get;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 实体的多对多中间表)
  • 连接表上的复合键通常是可以的。因此,我为此说“几乎总是一个坏主意”。但是,在您计划直接查询的表上使用复合键,尤其是如果您要与这些表建立进一步的关系时,这种情况开始迅速失控。

标签: c# data-annotations code-first


【解决方案1】:

关于数据库表如何在asp mvc模型中表示的总结

模型如何表示数据库表

在接下来的部分中,我将解释如何从代码优先应用程序为数据库创建数据模型,并介绍如何在 ASP MVC 中表示关系。

在此示例中,我们有三个具有以下架构的表:

学生桌

学生 ID、姓氏、名字、注册日期

课程表

CourseID、标题、学分

报名表

EnrollmentID、CourseID、StudentID、Grade

这些表中的每一个都必须在一个单独的模型中表示。

  1. 学生桌

    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 表的导航属性,并且应为集合

  1. 课程表 和学生一样

    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 属性,但不能包含集合。

【讨论】:

  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 2016-07-08
  • 2012-12-10
  • 1970-01-01
  • 2012-12-19
相关资源
最近更新 更多