创建没有外键的导航属性

时间:2019-03-13 00:16:57

标签: c# entity-framework entity-framework-6

我有两个这样的班级:

[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; }
}

实体框架对此进行构建,以使UserGameProfile具有指向GameLevel的外键。我猜这是因为GameLevelId属性。

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

我尝试过:

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

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

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

  

Project.Domain.Data.UserGameProfile_Level::多重性   与角色中的引用约束冲突   关系中的“ UserGameProfile_Level_Target”   “ UserGameProfile_Level”。因为中的所有属性   从属角色是不可为空的,主要角色是多个   必须为“ 1”。

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

如何保持各个级别的独立性,但能够向个人资料添加级别?

1 个答案:

答案 0 :(得分:0)

您不能完全删除外键,否则,您如何期望两个实体(即表)链接?相反,您可以做的是使用可为空的FK,这将有效地使关系变为零或一对多。

在您的GameLevel类中,添加一个导航属性作为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类中,使属性GameLevelId可为空:

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

    public int? GameLevelId { get; set; }

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

这应该无需使用Fluent API即可工作。