我想在Entity Framework Core 3.1中为Team
和Players
建模。每个团队有很多球员,每个球员只有一个团队。此外,每个团队的球员名单中都有一名队长。如何将Fluent Api写成Captain
和Player
之间的关系(一对一)?
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public int? CaptainId { get; set; }
public Player Captain { get; set; }
public ICollection<Player> Players { get; set; }
}
public class Player
{
public int Id { get; set; }
public string Name { get; set; }
public int TeamId { get; set; }
public Team Team { get; set; }
}
我尝试了以下代码
builder.Entity<Team>()
.HasOne(e => e.Captain)
.WithOne()
.HasForeignKey<Team>(e => e.CaptainId)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity<Team>()
.HasMany(g => g.Players)
.WithOne(s => s.Team)
.HasForeignKey(s => s.TeamId);
但是此代码生成了两个一对多的关系...
答案 0 :(得分:0)
过去几天我一直在尝试这样的事情,在尝试了各种数据注释和 Fluent API 废话之后,我能想出的最简洁的解决方案非常简单,两者都不需要。它只需要将“私有”构造函数添加到注入“DbContext”对象的 Team 类(如果使用延迟加载,则为“受保护”构造函数)。只需将您的“Team”和“Player”类设置为正常的一对多关系,并且您的数据库上下文现在可从“Team”实体中使用,您可以使“Captain”属性简单地从以下位置返回查询使用 Find() 方法的数据库。 Find() 方法也使用了缓存,因此如果多次调用 getter,它只会访问一次数据库。
这是关于此能力的文档:https://docs.microsoft.com/en-us/ef/core/modeling/constructors#injecting-services
注意:'Captain' 属性是只读的。要修改它,请设置“CaptainId”属性。
class Team
{
public Team() { }
private MyDbContext Context { get; set; }
// make the following constructor 'protected' if you're using Lazy Loading
private Team(MyDbContext Context) { this.Context = Context; }
public int ID { get; set; }
public string Name { get; set; }
public int? CaptainID { get; set; }
public Player Captain { get { return Context.Players.Find(CaptainID); } }
}
class Player
{
public int ID { get; set; }
public string Name { get; set; }
public int TeamID { get; set; }
public Team Team { get; set; }
}