我有以下类,我首先尝试使用Entity Framework 6代码存储在数据库中。
人:
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<WorkItem> WorkItems { get; set; }
}
工作项目:
public class WorkItem
{
public Guid Id { get; set; }
public string Description { get; set; }
public Person Creator { get; set; }
}
正如你所看到的,每个人都可以完成许多任务。但是(!)任务也有一个人的创造者。
我希望使用实体框架的add-migration创建的workitem表有两个外键。一个是工作项可以与Person的WorkItems集合相混合,另一个指向Workitem的创建者。如下图所示:
这似乎不是一个奇怪的场景,但它给我带来了很多问题。
如果您只是尝试使用add-migration创建数据库表,则可以通过以下方式创建WorkItem:
CreateTable(
"dbo.WorkItems",
c => new
{
Id = c.Guid(nullable: false),
Description = c.String(),
Creator_Id = c.Guid(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.People", t => t.Creator_Id)
.Index(t => t.Creator_Id);
正如您所看到的,没有任何内容可以使此人成为其工作项的所有者。如果我删除了Creator属性,它会按预期工作。当该类是所有者时,引用类似乎存在问题。
为什么这不是开箱即用的工具,解决问题的最佳方法是什么?导航属性?流畅的API?
答案 0 :(得分:2)
在DbContext.OnModelCreating中使用此配置配置实体(或者更好的是,添加单独的实体配置):
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasMany(p => p.WorkItems).WithMany();
modelBuilder.Entity<WorkItem>().HasRequired(t => t.Creator).WithMany().WillCascadeOnDelete(false);
}
这将为Person创建一个表,为WorkItem创建另一个表,另一个用于支持Person和WorkItem之间的多对多关系。它还将在WorkItem中创建一个单独的FK来引用Person:
我无法完全理解你的问题。我知道每个人都可以完成多项任务,但我不确定任务是否只能分配给一个人或多个人。如果只想要一对多关系,请使用以下配置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasMany(p => p.WorkItems).WithOptional();
modelBuilder.Entity<WorkItem>().HasRequired(t => t.Creator).WithMany().WillCascadeOnDelete(false);
}
这只创建了两个表,而在WorkItem中有两个FK-s引用Person表;一个用于创建者,另一个用于EF可以将Person中的引用连接到WorkItems:
答案 1 :(得分:0)
这看起来像是一对多的关系,因此您的Tasks
属性应为ICollection<WorkItem>
,您需要更新这两个类。
您的Person
课程就像:
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<WorkItem> Tasks { get; set; }
}
并且您还需要修改WorkItem
类以引用创建Person
的{{1}}实例,因此WorkItem
类将是:
WorkItem
现在这应该在迁移中生成正确的sql。
有关Entity Framework一对多关系的更多信息,请a look here
希望它适合你。