我正在尝试使用code-first
来建模我的数据库。
我在这里想要映射的是0 -> *
和Users
的{{1}}关系。
例如,用户可以有0或更多与之相关的挑战。挑战可以有0个或更多与之关联的用户。
这是我正在使用的代码,问题是challenge表是使用Challenges
属性生成的。
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; }
}
修改
更新了标题和问题 - 关系不是零到多,而是多对多。
答案 0 :(得分:2)
该列来自您Challenge
和UserAccount
之间的关系。您可以在模型中声明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");
});
答案 1 :(得分:1)
在Many to Many
中,有多个公约可以实现One to Many
和entity framework
关系。将尝试提及所有。希望这些将有所帮助。
更新(因为OP需要多对多): 许多与很多关系
第1号惯例:
两个模型中的集合导航属性
public class UserAccount
{
public int Id { get; set; }
public string Username { get; set; }
public ICollection<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 ICollection<UserAccount> UserAccounts { get; set; }
}
实现相同的其他方式
mb.Entity<UserAccount>()
.HasMany(r => r.Challenges)
.WithMany()
.Map(m =>
{
m.MapLeftKey("UserAccountId");
m.MapRightKey("ChallengeId");
m.ToTable("UserAccountChallenge"); //Junction Table
});
ONE to MANY Relationship
第1号惯例:
这可以通过包含参考导航属性来实现 在
中输入UserAccount
Challenge
public class Challenge
{
public int Id { get; set; }
public string ChallengeId {get; set;}
public string Name { get; set; }
public string Description { get; set; }
public UserAccount UserAccount{get;set;}
}
第2号公约:
另一个惯例是包含集合导航属性
UserAccount
public class UserAccount
{
public int Id { get; set; }
public string Username { get; set; }
public ICollection<Challenge> Challenges { get; set; }
}
第3号公约:
包括两端的导航属性也会导致 一对多的关系
public class Challenge
{
public int Id { get; set; }
public string ChallengeId {get; set;}
public string Name { get; set; }
public string Description { get; set; }
public UserAccount UserAccount{get;set;}
}
public class UserAccount
{
public int Id { get; set; }
public string Username { get; set; }
public ICollection<Challenge> Challenges { get; set; }
}
第4号公约
两端完全定义的关系将创建一对多 关系
public class Challenge
{
public int Id { get; set; }
public string ChallengeId {get; set;}
public string Name { get; set; }
public string Description { get; set; }
public int UserAccountId { get; set; }
public UserAccount UserAccount{get;set;}
}
使用Fluent API配置一对多关系
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// configures one-to-many relationship
modelBuilder.Entity<UserAccount>()
.HasRequired<Challeng>(s => s.ChallengId)
.WithMany(g => g.UserAccount)
.HasForeignKey<int>(s => s.ChallengId);
}