【问题标题】:foreign key assignments using code first外键分配首先使用代码
【发布时间】:2016-10-26 19:02:52
【问题描述】:

我正在创建一个 MVC 应用程序并希望使用 Code First 方法生成数据库。我已经用简单的表完成了这项工作,但现在我要引入外键关系,事情变得一团糟。

我有三个类,每个类在数据库中都有自己的表:

public class Device
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int InternalDeviceID { get; set; }

        public int DeviceID { get; set; }

        public string DeviceName { get; set; }

        public virtual EquipmentDevice EquipmentDevice { get; set; }
    }

public class Equipment
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int InternalEquipmentID { get; set; }

        public int EquipmentID { get; set; }

        public string EquipmentName { get; set; }

        public virtual EquipmentDevice EquipmentDevice { get; set; }
    }

public class EquipmentDevice
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int InternalEquipmentDeviceID { get; set; }

        public virtual ICollection<Equipment> EquipmentID { get; set; }

        public virtual ICollection<Device> DeviceID { get; set; }
    }

关系是一个设备可能有许多设备,一个设备可能属于许多设备(如果我没记错的话是多对多)。为了组织哪些设备与哪些设备相关联,我使用 EquipmentDevice 表,它将它们的 ID 与该表的内部 ID 配对。

根据我发现的其他示例,我认为这是编写这种情况的方式,其中关系的多方将具有单方的 ICollection 对象,而单方关系的一个虚拟对象将具有多方的虚拟对象(两个类都具有 N:N 的另一个的 ICollection,或者都具有 1:1 的虚拟对象)

但是,当我创建数据库时,我的表如下所示:

设备表

设备表

设备设备表

我是在为我的表设置外键的方式上简单地倒退,还是在这种情况下我完全遗漏了另一个问题?我找不到关于这个主题的非常有用的信息来源。我还附上了这些表格的图表,以帮助更清楚。

【问题讨论】:

    标签: c# mysql .net ef-code-first


    【解决方案1】:

    您已接近 - Equipment 和 Device 上的属性必须是 ICollections。您不需要为连接表定义一个类,EF 会为您处理。这是你的类应该是这样的(这是一个很好的参考:)

    http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx

        public class Device
                { 
                    public Device() 
                    { this.Equipments = new HashSet<Equipment>();}
    
                    [Key]
                    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
                    public int InternalDeviceID { get; set; }
    
                    public int DeviceID { get; set; }
    
                    public string DeviceName { get; set; }
    
                    public virtual ICollection<Equipment> Equipments { get; set; }
                }
    
        public class Equipment
            {
    
                public Equipment()
                { this.Devices = new HashSet<Device>(); }
    
                [Key]
                [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
                public int InternalEquipmentID { get; set; }
    
                public int EquipmentID { get; set; }
    
                public string EquipmentName { get; set; }
    
                public virtual ICollection<Devices> Devices { get; set; }
            }
    

    【讨论】:

    • 非常好 - 我不知道 EF 会为您创建关系表!虽然,您能否详细说明课程的“public Equipment() ... HashSet”和“public Device() ... HashSet”部分?到目前为止,我认为我在示例中没有遇到过这种情况
    • EF 使用 HashSet 对象来表示多对多关系任一侧的集合属性。您必须在构造函数中“新建”它们,以便可以从数据库或内存中填充它们,否则在数据库加载或尝试使用其中一个集合进行 CRUD 操作时,您会收到 NullReferenceException。跨度>
    • 那么假设我有 Table_A 和 Table_B。它们分别具有 1:N 的关系。我想将 Table_A 中的 ID 用作 Table_B 中的 FK,但不需要 Table_B 中的任何列出现在 Table_A 中。由于我没有从这种关系创建一个新表,Table_A 是否只有一个“公共虚拟 Table_B 对象名”属性,而 Table_B 有一个“公共虚拟 ICollection 对象名”属性,这会将外键从 A 带到 B ?
    • 是的,确实如此,但您还应该使用 Fluent API 设置一对多关系的外键约束,因为如果您尝试从表 A 中删除行,您会收到来自 EF 的错误如果表 B 中存在与表 A 中的行关联的外键值的行
    • 在查看借助此答案创建的表时,我刚刚意识到我应该指定“内部”ID 不是我制作 EquipmentDevice 表所需的,而是DeviceID 和 EquipmentID
    【解决方案2】:

    要生成外键,首先要做的是创建模型。

    public class Device
    {   
        [Key]
        public int DeviceID { get; set; }
        public string DeviceName { get; set; }
    
        public virtual ICollection<Equipment> Equipments { get; set; }
    }
    
    public class Equipment
    {        
        [Key]
        public int EquipmentID { get; set; }
        public string EquipmentName { get; set; }
    
        public virtual ICollection<Device> Devices { get; set; }
    }
    

    然后为每个模型生成并编译驱动程序。 通过生成第一个模型,创建“上下文”。

    加载项目后,检查您是否可以访问创建的驱动程序。

    现在检查数据库。该表有两个外键,新表是自动创建的。

    【讨论】:

    • 使用[Key]和[ForeignKey(string name)]有什么区别?
    • 键是主键。你分配一个外键 cuando utilizas
    • "[Key]" 是主键。外键是使用设备和设备模型的 ICollection 分配的。
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 2013-09-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多