【问题标题】:Create navigation property without foreign key创建没有外键的导航属性
【发布时间】:2019-03-13 00:16:56
【问题描述】:

我有两个这样的课程:

[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: : 多重性 与 Role 中的引用约束冲突 关系中的“UserGameProfile_Level_Target” 'UserGameProfile_Level'。因为所有的属性在 依赖角色是不可为空的,主要角色的多重性 必须是“1”。

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

我如何保持关卡独立,但又可以向个人资料添加关卡?

【问题讨论】:

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


    【解决方案1】:

    您不能完全删除外键,否则,您希望如何链接两个实体(即表)?相反,您可以做的是有一个可为空的 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。

    【讨论】:

    • 这仍然会创建一个从配置文件到级别的 FK,因此我无法创建没有级别的配置文件。
    • 不!拥有 FK 并不一定能阻止这种情况(只要 FK 可以为空)。你应该能够做到这一点。请阅读我回答的第一句话。具有可为空的字段(FK,或不)意味着该字段可以具有 null 值,在这种情况下,这意味着 FK 不必具有值(AKA,零或一)。
    • 是的,但是有一个外键约束意味着父级必须存在。在没有父母的情况下如何创造孩子?尝试插入没有违反 FK 约束的级别的配置文件时出现错误。
    • 再一次,拥有一个可为空的 FK 意味着“父”确实必须存在”。另一方面,没有 FK 意味着两个表 没有任何关系。如果在您修改代码以反映我在回答中显示的更改后,您仍然有该错误,请编辑您的问题并包含新代码(包括您如何创建和保存配置文件和任何相关的 Fluent API)。
    猜你喜欢
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多