创建没有外键的导航 属性

Create navigation property without foreign key

我有两个 类 像这样:

[Table("GameLevels", Schema = "ref")]
public class GameLevel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public double PointsMin { get; set; }
    public double PointsMax { get; set; }
}

[Table("GameProfiles", Schema = "usr")]
public class UserGameProfile 
{
    [Key]
    [ForeignKey("ApplicationUser")]
    public string Id { get; set; }
    public int GamesPlayed { get; set; }
    public double Points { get; set; }
    public int WinCount { get; set; }
    public int LossCount { get; set; }
    public int DrawCount { get; set; }
    public int ForfeitCount { get; set; }
    public int GameLevelId { get; set; }

    public virtual GameLevel Level { get; set; }

    public virtual ApplicationUser ApplicationUser { get; set; }
}

Entity framework 构建它以便 UserGameProfile 有一个指向 GameLevel 的外键。我猜这是因为 GameLevelId 属性。

有什么方法可以让我在没有外键的情况下生成表格和导航属性?

我试过了:

modelBuilder.Entity<UserGameProfile>().HasOptional<GameLevel>(x => x.Level).WithMany();

但是随后数据库无法建立。出现此错误:

在模型生成过程中检测到一个或多个验证错误:

Project.Domain.Data.UserGameProfile_Level: : Multiplicity conflicts with the referential constraint in Role 'UserGameProfile_Level_Target' in relationship 'UserGameProfile_Level'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'.

基本上我想要的是零或一到零或多的关系。

如何在保持级别独立的同时又能够将级别添加到配置文件中?

你不能完全丢掉外键,否则,你指望两个实体(即表)如何链接?您可以做的是拥有一个可为空的 FK,这将有效地使关系成为零或一对多。

在您的 GameLevel class 中,添加导航 属性 作为 UserGameProfile:

的集合
public class GameLevel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public double PointsMin { get; set; }
    public double PointsMax { get; set; }

    public virtual ICollection<UserGameProfile> UserGameProfiles { get; set; }
}

然后在 UserGameProfile class 中,使 属性 GameLevelId 可为空:

public class UserGameProfile 
{
    // ...
    // ...

    public int? GameLevelId { get; set; }

    [ForeignKey("GameLevelId")]
    public virtual GameLevel GameLevel { get; set; }
}

这应该可以工作,甚至不必使用 Fluent API。