c# - 如何使用代码优先正确初始化多对多关系

标签 c# entity-framework ef-code-first ef-code-first-mapping

我正在尝试使用 code-first 为我的数据库建模。

我在这里试图映射的是 UsersChallenges0 -> * 关系。

例如,一个用户可以有 0 个或多个与之相关的挑战。一个挑战可以有 0 个或多个与之关联的用户。

这是我正在使用的代码,问题是挑战表是使用 UserAccount_ID 属性生成的。

public class UserAccount
{
    public int Id { get; set; }
    public string Username { get; set; }

    public virtual List<Challenge> Challenges { get; set; }
}

public class Challenge
{
    public int Id { get; set; }
    public string ChallengeId {get; set;}
    public string Name { get; set; }
    public string Description { get; set; }

    public virtual List<Competitor> Competitors { get; set; }
}

public class Competitor
{
    public int Id { get; set; }
    public string Username { get; set; }
    public int Rank { get; set; }
}

错误的属性:

enter image description here

我已经尝试将它添加到我的上下文类中,但它没有任何效果:

protected override void OnModelCreating(DbModelBuilder mb)
{
    mb.Entity<UserAccount>()
        .HasMany(o1 => o1.Challenges)
        .WithOptional();

    base.OnModelCreating(mb);
}

编辑

更新的标题和问题 - 关系不是零对多,而是多对多。

最佳答案

该列来自您在 ChallengeUserAccount 之间的关系。您可以在模型中声明 FK 属性:

public class Challenge
{
    public int Id { get; set; }
    public string ChallengeId {get; set;}
    public string Name { get; set; }
    public string Description { get; set; }

    //Add these properties
    public int UserAccountId{get;set;}
    public UserAccount UserAccount{get;set;}

    public virtual List<Competitor> Competitors { get; set; }
}

默认情况下,EF 使用一些命名约定来标识模型中的 FK 属性,因此使用该名称应该没问题。现在,如果您使用的是 Fluent Api,那么我建议按照您的意愿配置关系:

protected override void OnModelCreating(DbModelBuilder mb)
{
    mb.Entity<UserAccount>()
        .HasMany(o1 => o1.Challenges)
        .WithOptional(e=>e.UserAccount);
        .HasForeignKey(e=>e.UserAccountId);

    base.OnModelCreating(mb);
}

现在,如果您不想在 Challenge 实体中包含 FK 属性和导航属性,但想重命名 FK 属性,您可以这样做:

protected override void OnModelCreating(DbModelBuilder mb)
{
    mb.Entity<UserAccount>()
        .HasMany(o1 => o1.Challenges)
        .WithOptional();
        .Map(m => m.MapKey("UserAccountId"));

    base.OnModelCreating(mb);
}

多想想你的模型,也许你真正追求的是多对多的关系,如果是这样的话你可以这样配置:

  mb.Entity<UserAccount>()
    .HasMany(r => r.Challenges)
    .WithMany() // No navigation property here
    .Map(m =>
        {
            m.MapLeftKey("UserAccountId");
            m.MapRightKey("ChallengeId");
            m.ToTable("UserAccountChallenge");
        });

关于c# - 如何使用代码优先正确初始化多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48254631/

相关文章:

c# - 动态 linq 查询不工作

MySQL 5.5 + .NET 连接器 + Entity Framework + 迁移 = FormatException

c# - 在 EF Code First 中拥有计算字段的正确方法

c# - 如何在关闭前等待串口清空

c# - .NET 字典作为属性

c# - 将列添加到数据库表后 Entity Framework 出现问题

c# - ADO.NET Entity Framework - 复合主键 CRUD

c# - 我可以通过 wcf 上传图像而不转换为字节数组吗

C# WPF 以编程方式在项目中设置构建属性

sql-server - 尝试部署 Entity Framework 代码优先应用程序但运气不佳?最佳部署策略?