我正在尝试使用Entity Framework流畅的API在两个poco的之间定义一个简单的一对多关系。
~ Team ~
public int TeamId { get; set; }
public ICollection<User> TeamMembers { get; set; } // All the team players. Two way nav.
public Player CreatedBy { get; set; } // Which player created this team. One way navigation.
// Optional. Not all players create a team.
~ Player ~
public int PlayerId { get; set; }
public Team Team { get; set; } // The other side of the TeamMembers navigation.
注意:
我认为最接近的是这样的......
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Team>()
.HasOptional(x => x.TeamMembers)
.WithMany()
.WillCascadeOnDelete(false);
}
...哪个不起作用..而且我也不确定如何定义其他导航。
有人可以帮忙吗?
答案 0 :(得分:12)
我认为这个对象模型正是您所寻找的:
public class Team
{
public int TeamId { get; set; }
public ICollection<Player> TeamMembers { get; set; }
public Player CreatedBy { get; set; }
}
public class Player
{
public int PlayerId { get; set; }
public Team Team { get; set; }
}
public class Context : DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Team> Teams { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Player>()
.HasOptional(p => p.Team)
.WithMany(t => t.TeamMembers)
.Map(c => c.MapKey("TeamId"));
// Or alternatively you could start from the Team object:
modelBuilder.Entity<Team>()
.HasMany(t => t.TeamMembers)
.WithOptional(p => p.Team)
.Map(c => c.MapKey("TeamId"));
}
}
BTW,您使用的以下流畅的API代码不正确:
...HasOptional(x => x.TeamMembers)
因为TeamMembers是一个集合,并且 HasOptional 方法不能使用它,它总是必须用一个对象调用。
虽然他们都建立了一个关联,但他们提供的结果略有不同,并且有不同的要求:
如果它是FK关联(FK属性在依赖对象上公开),那么在使用 HasOptional 时它必须是可空类型,而在使用 HasRequired时它是非可空类型或Code First将抛出。
使用 HasRequired 方法时,Code First会自动切换级联删除。
另一个区别是删除时的EF运行时行为。考虑我们想要删除主要对象(例如Team
)同时它具有依赖对象(例如Player
)并且关闭级联删除的情况。使用 HasOptional EF运行时将静默地将依赖的FK列更新为null,而使用 HasRequired EF将抛出并要求您显式删除依赖对象或将其与另一个主体对象关联(如果你想尝试这个,你应该知道,在这两种情况下,主要和从属对象必须已经在上下文中加载,以便EF将跟踪它们。)
答案 1 :(得分:2)
通过这样做,我已经能够自动完成这项工作:
public class Team {
public int TeamId { get; set; }
...
public virtual ICollection<Player> Players { get; set; }
}
但是当你说“不起作用”时,你必须更明确地指出你究竟是什么意思。究竟什么不起作用?您收到错误消息了吗?如果是这样,它是什么? Player对象的Team属性是否始终返回null?