实体框架4.1代码优先中的一对多关系

Posted

技术标签:

【中文标题】实体框架4.1代码优先中的一对多关系【英文标题】:one to many relationship in entity framewrok 4.1 code first 【发布时间】:2011-04-24 13:35:56 【问题描述】:

我正在初始化这样的实体:

    TasksListDB db = new TasksListDB();

    public ActionResult Index()
    

        var tasks1 = new List<Task>()
        
            new Task  Id=1, Name = "Task 1", Difficulty = 1, DateCreated = DateTime.Parse("1/12/2011") , IsDone= true ,
            new Task  Id=2, Name = "Task 2", Difficulty = 2, DateCreated = DateTime.Parse("11/2/2011") , IsDone = false               
        ;

        var tasks2 = new List<Task>()
        
             new Task  Id=3, Name = "Task 3", Difficulty = 3, DateCreated = DateTime.Parse("11/2/2011") , IsDone = false,
            new Task  Id=4, Name = "Task 4", Difficulty = 5, DateCreated = DateTime.Parse("1/2/2010") , IsDone= true 
        ;

        tasks1.ForEach(t => db.Tasks.Add(t));
        tasks2.ForEach(t => db.Tasks.Add(t));

        var Persons = new List<Person>  
     new Person  Id= 1 , Age= 10, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed" ,
     new Person  Id= 2 , Age= 10, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed"  ,
     new Person  Id= 3 , Age= 10, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed"  ,
     new Person  Id= 4 , Age= 10, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed"  ;

        Persons.ForEach(p => db.Persons.Add(p));

        return View(db.Tasks);
    

我的数据库上下文如下所示:

public class TasksListDB : DbContext

    public DbSet<Person> Persons  get; set; 
    public DbSet<Task> Tasks  get; set;    

我想将任务分配给人员,我该怎么做?

我的模型如下所示:

public class Person

    public int Id  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 
    public int Age  get; set;         
    public string EmailAddress  get; set;         
    public virtual ICollection<Task> Tasks  get; set; 


public class Task

    public int Id  get; set; 
    public string Name  get; set; 
    [Required]
    public DateTime DateCreated  get; set; 
    [Required]
    [Range(1,5,ErrorMessage="Difficulty must be between 1 and 5")]
    public int Difficulty  get; set; 
    public bool IsDone  get; set; 

    public virtual Person Person  get; set; 

当我运行我的 mvc 应用程序时,会创建 Person 和 Task 表,但未创建联结表 PersonTask。

[编辑]

I am assigning tasks like this in initializer class:

   var t1 = new Task  Id = 1, Name = "Urgent Task", DateCreated = DateTime.Now, Difficulty = 2, IsDone = true ;
            var t2 = new Task  Id = 2, Name = "Business Task", DateCreated = DateTime.Now, Difficulty = 1, IsDone = true ;
            var t3 = new Task  Id = 3, Name = "Home Task", DateCreated = DateTime.Now, Difficulty = 2, IsDone = false ;

 context.Tasks.Add(t1);
            context.Tasks.Add(t2);
            context.Tasks.Add(t3);

    var Persons = new List<Person>  
         new Person  Id= 1 , Age= 40, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed", Tasks= new List<Task>  t1,t2 ,
         new Person  Id= 2 , Age= 30, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed" , Tasks= new List<Task>  t1  ,
         new Person  Id= 3 , Age= 29, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed" , Tasks= new List<Task>  t3,t2  ,
         new Person  Id= 4 , Age= 35, EmailAddress= "asif_hameed_37@hotmail.com", FirstName= "Asif", LastName="Hameed" , Tasks= new List<Task>  t1,t3  ;

 context.Persons.Add(Persons[0]);
            context.Persons.Add(Persons[1]);
            context.Persons.Add(Persons[2]);
            context.Persons.Add(Persons[3]);

            context.SaveChanges();

but when i see the task table in sql server, it looks like this:

Id  Name          DateCreated          Difficulty   IsDone  Person_Id
1   Urgent Task 2011-04-24 19:32:03.990 2   1   4
2   Business Task   2011-04-24 19:32:03.990 1   1   3
3   Home Task   2011-04-24 19:32:03.990 2   0   4

我假设人员表应该有任务而不是任务表应该有人员 ID

Please suggest solution.

【问题讨论】:

【参考方案1】:

不会创建联结表,因为您定义了一对多关系而不是多对多关系。模型中的 Task 实体只能分配给单个 Person 而不能分配给很多人。

如果您想将Task 分配给Person,只需运行:

person.Tasks.Add(task);

【讨论】:

@Ladislav:非常好的观点。谢谢。我已经更新了问题。我假设人员表应该有任务 ID,但我在任务中获取人员 ID。你能告诉我我的代码有什么问题吗? 确保您在 Task 中获得 PersonId,因为您的 Task 具有单个相关 Person - 任务位于定义 FK 的关系的多端。 @Ladislave:但任务表未显示分配给人员 2 和人员 3 的任务 因为你的代码初始化不正确。如果您使用一对多关系,则不能将单个任务分配给多个人。每个任务只能分配给一个人。更改您的初始化或将Task 实体更改为具有ICollection&lt;Person&gt; Persons 而不是Person Person @Ladisalv:我希望一个人可以完成多项任务。我需要在初始化/模型类中做什么?

以上是关于实体框架4.1代码优先中的一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

同一实体类型代码的多个一对多关系优先

一对多和递归关系 - 强制设置值

实体框架 4.1 代码优先外键 ID

实体框架中的可选一对多关系[关闭]

实体框架代码优先的多对多关系的最佳方法

实体框架代码优先关系 - 如何定义两个对象之间的关系:两个实体之间的可选一对一