简体   繁体   English

如何创建一个表有两个外键使用实体框架代码首先指向同一个表

[英]How to create a table with two foreign keys pointing to the same table using Entity Framework Code First

I have the following classes, which I'm trying to store in a database using Entity Framework 6 code first. 我有以下类,我尝试首先使用Entity Framework 6代码存储在数据库中。

Person: 人:

public class Person
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public List<WorkItem> WorkItems { get; set; }
}

WorkItem: 工作项:

public class WorkItem
{
    public Guid Id { get; set; }

    public string Description { get; set; }

    public Person Creator { get; set; }

}

As you can see each person can have a number of task. 如您所见,每个人可以完成许多任务。 But(!) the task also has a creator that is a person. 但是(!)任务还有一个创建者,即一个人。

I expect the workitem table created by using entity framework's add-migration to have two foreign keys. 我期望通过使用实体框架的add-migration创建的工作项表具有两个外键。 One so that the workitem can bleong to the WorkItems collection of Person, and one that points to the creator of the Workitem. 一种使工作项可以讨厌Person的WorkItems集合,而另一种则指向工作项的创建者。 Like the picture below shows: 如下图所示:

在此处输入图片说明

This doesn't seem to be such a weird scenario, but it's causing me loads of problems. 这似乎不是一个怪异的情况,但它给我带来了很多问题。

If you just try to create database tables using add-migration the WorkItem is created in the following way: 如果您只是尝试使用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);

As you can see there is nothing that makes the Person an owner of its work items here. 如您所见,没有什么可以使此人成为其工作项的所有者。 If I remove the Creator property it works as expected. 如果删除了Creator属性,它将按预期工作。 There seems to be a problem referencing a class when that class is the owner. 当该类为所有者时,引用该类似乎存在问题。

Why doesn't this just work out of the box and what is the best way to fix it? 为什么这不是开箱即用,什么是最好的解决方法? Navigation property? 导航属性? Fluent API? 流利的API?

Configure your entities using this configuration in your DbContext.OnModelCreating (or better yet, add separate entityconfigurations): 使用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);
 }

This will create a table for Person and another for WorkItem and another one to support the many-to-many relationship between Person and WorkItem. 这将为Person创建一个表,为WorkItem创建另一个表,并为支持Person和WorkItem之间的多对多关系创建另一个表。 It will also create a separate FK in WorkItem to reference Person: 它还将在WorkItem中创建一个单独的FK来引用Person:

在此处输入图片说明

I couldn't understand your question entirely. 我无法完全理解您的问题。 I understand that every person can have multiple tasks, but I'm not sure whether a task can be assigned to only one person or multiple people. 我知道每个人可以执行多个任务,但是我不确定一个任务只能分配给一个人还是多个人。 If you want a one-to-many relationship only, use this configuration: 如果仅需要一对多关系,请使用以下配置:

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
   modelBuilder.Entity<Person>().HasMany(p => p.WorkItems).WithOptional();
   modelBuilder.Entity<WorkItem>().HasRequired(t => t.Creator).WithMany().WillCascadeOnDelete(false);
 }

This only creates the two tables and in WorkItem two FK-s to reference the Person table; 这仅创建两个表,并且在WorkItem中创建两个FK来引用Person表; one for the Creator and one so that EF can wire up the references in Person to the WorkItems: 一个用于创建者,另一个用于EF可以将Person中的引用连接到WorkItems:

在此处输入图片说明

This looks like as one to many relationship, so your Tasks property should be ICollection<WorkItem> , you need to update your both classes. 这看起来像一对多的关系,因此您的Tasks属性应该是ICollection<WorkItem> ,您需要更新两个类。

Your Person class would be like: 您的Person类如下所示:

public class Person
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public ICollection<WorkItem> Tasks { get; set; }
}

and you would also need to modify your WorkItem class to have reference to the Person instance who created the WorkItem , so WorkItem class would be like: 并且您还需要修改WorkItem类以引用创建WorkItemPerson实例,因此WorkItem类类似于:

public class WorkItem
{
    public Guid Id { get; set; }

    public string Description { get; set; }

    [ForeignKey("Person")]
    public Guid WorkItemCreatorId{ get; set; }

    public Person Creator { get; set; }

}

Now this should generate the correct sql in migrations. 现在,这将在迁移中生成正确的sql。

For more on Entity Framework one-to-many relationships, please have a look here 有关Entity Framework一对多关系的更多信息,请在此处查看

Hope it works for you. 希望对你有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架-表需要两个指向同一表的外键 - Entity Framework - table needs two foreign keys pointing at same table 实体框架代码优先 - 来自同一个表的两个外键 - Entity Framework Code First - two Foreign Keys from same table Entity Framework Core - 代码优先 - 两个外键 - 一张表 - Entity Framework Core - Code First - Two Foreign Keys - One Table 指向实体框架中相同表的多个外键是无法区分的 - Multiple foreign keys pointing to same table in Entity Framework are indistinguisible 实体框架DbContext混淆当两个外键指向同一张表时 - Entity Framework DbContext Confusion When two foreign keys pointing at same table 如何在实体框架代码中首先从表的主键制作两个外键 - How to make two foreign keys from a primary key of a table in Entity Framework Code First 如何在一个表中创建两个指向某个表中同一列的外键? - How to Create two Foreign Keys in one Table pointing to the same Column in some table? 如何将第一个表的主键值更新为第二个表的外键(实体框架代码第一个模型)? - How to update primary key values of first table into foreign keys in the second table (Entity framework code first model)? 实体框架核心两个外键 - 相同的表 - Entity Framework Core Two Foreign Keys - Same Table 实体框架6表具有许多外键,每个外键指向不同的表 - Entity Framework 6 table with many foreign keys each pointing to different tables
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM