EF -外键关系中组合键的一部分

本文关键字:组合 一部分 关系 EF | 更新日期: 2023-09-27 17:52:37

我正试图利用ADO.NET的"代码首先来自数据库"功能。生成工作成功,并输出了我想要的所有模型。我有几个EF模型,它们都将组合键作为主键。下面我给出了两个这样的模型作为例子。

public partial class LabRole
{
    public LabRole()
    {
        LabRolePermissions = new HashSet<LabRolePermission>();
        LabUserRoles = new HashSet<LabUserRole>();
        RoleSubscriptions = new HashSet<RoleSubscription>();
    }
    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string RoleID { get; set; }
    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string LabID { get; set; }
    public virtual ICollection<LabRolePermission> LabRolePermissions { get; set; }
    public virtual Lab Lab { get; set; }
    public virtual ICollection<LabUserRole> LabUserRoles { get; set; }
    public virtual ICollection<RoleSubscription> RoleSubscriptions { get; set; }
}

:

public partial class LabRolePermission
{
    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string LabID { get; set; }
    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string RoleID { get; set; }
    [Key]
    [Column(Order = 2)]
    [StringLength(50)]
    public string PermissionID { get; set; }
    public virtual Lab Lab { get; set; }
    public virtual LabRole LabRole { get; set; }
    public virtual Permission Permission { get; set; }
}

然后在其上设置外键关系:

modelBuilder.Entity<LabRole>()
            .HasMany(e => e.LabRolePermissions)
            .WithRequired(e => e.LabRole)
            .HasForeignKey(e => new { e.RoleID, e.LabID })
            .WillCascadeOnDelete(false);

我运行add-migration,一个初始迁移脚本成功生成。但是,当我尝试访问上下文中的内容时,它会出错:

Problem in mapping fragments starting at lines 119, 128: Foreign key constraint 'LabRole_LabRolePermissions' from table LabRolePermission (LabID, RoleID) to table LabRole (RoleID, LabID):: Insufficient mapping: Foreign key must be mapped to some AssociationSet or EntitySets participating in a foreign key association on the conceptual side.

有人能解释一下为什么会发生这种情况和/或解决这个问题的方法吗?

EF -外键关系中组合键的一部分

好的,我找到答案了。如果我不再使用数据注释来指定键,而是使用流畅的API来指定键,那么生成的数据库函数就会如预期的那样。

例如,如果我将模型更改为:

public partial class LabRole
{
    public LabRole()
    {
        LabRolePermissions = new HashSet<LabRolePermission>();
        LabUserRoles = new HashSet<LabUserRole>();
        RoleSubscriptions = new HashSet<RoleSubscription>();
    }
    [StringLength(50)]
    public string RoleID { get; set; }
    [StringLength(50)]
    public string LabID { get; set; }
    public virtual ICollection<LabRolePermission> LabRolePermissions { get; set; }
    public virtual Lab Lab { get; set; }
    public virtual ICollection<LabUserRole> LabUserRoles { get; set; }
    public virtual ICollection<RoleSubscription> RoleSubscriptions { get; set; }
}

:

public partial class LabRolePermission
{
    [StringLength(50)]
    public string LabID { get; set; }
    [StringLength(50)]
    public string RoleID { get; set; }
    [StringLength(50)]
    public string PermissionID { get; set; }
    public virtual Lab Lab { get; set; }
    public virtual LabRole LabRole { get; set; }
    public virtual Permission Permission { get; set; }
}

然后使用Fluent定义键,即

modelBuilder.Entity<LabRolePermission>().HasKey(e => new { e.LabID, e.RoleID, e.PermissionID });
modelBuilder.Entity<LabRole>().HasKey(e => new { e.RoleID, e.LabID });

我可以访问数据库没有任何问题。我不太确定为什么会这样,但确实如此。