实体框架 6 编码第一个外键,而不使用相应的属性

本文关键字:属性 框架 编码 第一个 实体 | 更新日期: 2023-09-27 18:11:29

我有看起来像这样的表格

Users
 - UserID (PK)
 - UserName
 - ...
UserSettings
 - UserID (PK)
 - Settings

我的用户设置实体如下所示

public class UserSetting
{
    public UserSetting()
    {
    }
    [Key]
    [Column("UserID", TypeName ="nvarchar(128)")]
    public string ID { get; set; }
    [Required]
    public string Settings { get; set; }
}
我希望用户设置

的PK将FK从用户中的UserID添加到用户设置中的UserID,因为关系应该是1:1(如果您想知道设置字段是一个字符串,前端只是作为json字符串转储到数据库中,后端不关心里面的值(

如果我手动创建数据库并添加外键并且 EF 对此一无所知,这很好用,但我决定尝试让 EF 为此项目创建数据库。有没有办法告诉 EF 在不为与任一实体的关系添加实体属性的情况下创建该 FK?

实体框架 6 编码第一个外键,而不使用相应的属性

若要在 Code First 中创建关系,您需要在两端之一中至少有一个导航属性(这种关系称为单向关系(。典型的一对一关系配置如下:

public class User
{
    public User()
    {
    }
    [Key]
    [Column("ID", TypeName ="nvarchar(128)")]
    public string ID { get; set; }
    public string Name{ get; set; }
    public virtual UserSetting UserSetting {get;set;} 
}
public class UserSetting
{
    public UserSetting()
    {
    }
    [Key,ForeignKey("User"),Column("UserID")]
    public string ID { get; set; }
    //...
    public virtual User User{get;set;}
}
现在,

使用此模型,您不会向表中添加任何新列,它将是相同的,只是现在您将UserSettings表的PK配置为关系的FK(您正在尝试实现的目标(。

现在,正如我所说,EF 至少需要一个导航属性来创建关系。因此,如果需要,可以在 User 上删除 UserSetting nav. 属性,这没关系,将数据注释保留在UserSetting Id上,User导航属性足以先编码以创建关系。

若要首先使用 EF 代码自动生成外键关系,需要导航属性。

我发现解决此问题的最简单方法是手动更改迁移。

我的实体如下所示:

public class User
{
    public User() { }
    [Key]
    public string ID { get; set; }
    public string Name { get; set; }
}
public class UserSetting
{
    public UserSetting() { }
    [Key]
    public string ID { get; set; }
    public string Settings { get; set; }
}

执行迁移,这将生成以下迁移类:

...
        CreateTable(
            "dbo.Users",
            c => new
                {
                    ID = c.String(nullable: false, maxLength: 128),
                    Name = c.String(),
                })
            .PrimaryKey(t => t.ID);
        CreateTable(
            "dbo.UserSettings",
            c => new
                {
                    ID = c.String(nullable: false, maxLength: 128),
                    Settings = c.String(),
                })
            .PrimaryKey(t => t.ID);
...

现在更改与用户设置表相关的 CreateTable 语句:取代:

.PrimaryKey(t => t.ID);

.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Users", t => t.ID);

不要忘记更改 Down 方法以包含 DropForeignKey 语句。