实体框架,代码优先:将主 - 细节与零到一关系相结合 [英] Entity Framework, code-first: combining master-detail with zero-to-one relationship

查看:81
本文介绍了实体框架,代码优先:将主 - 细节与零到一关系相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的主 - 细节关系使用代码第一EF:

  public class User 
{
public string Id {get;组; }
public ICollection< Tasks>任务{get;组;
}

public class Task
{
public string Id {get;组;

[必需]
public string UserId {get;组; }
public User User {get;组; }
}

现在我要修改它,以便用户可以拥有一个,最多重要任务。所以我修改User类来添加它:

  public class User 
{
public string Id {得到;组; }
public ICollection< Tasks>任务{get;组; }
public string MostImportantTaskId {get;组; }

[ForeignKey(MostImportantTaskId)]
public Task MostImportantTask {get;组;
}

当我运行添加迁移,但是,我得到了一个意想不到的结果。 EF尝试向 Tasks 表中添加一个 User_Id 列,我不想要,并删除外部关键我需要主/细节关系:

  public override void Up()
{
DropForeignKey (dbo.Tasks,UserId,dbo.Users);
AddColumn(dbo.Tasks,User_Id,c => c.String(maxLength:128));
AddColumn(dbo.Users,MostImportantTaskId,c => c.String(maxLength:128));
CreateIndex(dbo.Tasks,User_Id);
CreateIndex(dbo.Users,MostImportantTaskId);
AddForeignKey(dbo.Users,MostImportantTaskId,dbo.Tasks,Id);
AddForeignKey(dbo.Tasks,User_Id,dbo.Users,Id);
}

public override void Down()
{
// ...
}
/ pre>

那么如何维护用户和任务之间的主要细节关系,同时将一个任务的引用添加到 User class?

解决方案

这不是我过于熟悉的东西,但我相信你正在寻找是 InverseProperty 。由于您的用户类与 Task 有多个关系,您需要添加 InverseProperty 到您的任务集合,将其指向用户属性任务



所以如果您在用户

  [InverseProperty(User)] 
public ICollection< Task>任务{get;组;

然后当您运行迁移时,将生成以下代码,这些代码看起来是您的之后

  public override void Up()
{
AddColumn(dbo.Users,MostImportantTaskId ,c => c.String(maxLength:128));
CreateIndex(dbo.Users,MostImportantTaskId);
AddForeignKey(dbo.Users,MostImportantTaskId,dbo.Tasks,Id);
}

public override void Down()
{
DropForeignKey(dbo.Users,MostImportantTaskId,dbo.Tasks);
DropIndex(dbo.Users,new [] {MostImportantTaskId});
DropColumn(dbo.Users,MostImportantTaskId);
}

根据 entityframeworktutorial.net



注意:我假定你在代码中引用了一个 Tasks 类,它是 Task的错字。


I have a simple master-detail relationship using code first EF:

public class User
{
     public string Id { get; set; }
     public ICollection<Tasks> Tasks { get; set; }
}

public class Task
{
    public string Id { get; set; }

    [Required]
    public string UserId { get; set; }
    public User User { get; set; }
}

Now I want to modify it so that users can have a single, most important task. So I modify the User class to add it:

public class User
{
     public string Id { get; set; }
     public ICollection<Tasks> Tasks { get; set; }
     public string MostImportantTaskId { get; set; }

     [ForeignKey("MostImportantTaskId")]
     public Task MostImportantTask { get; set; }
}

When I run Add-Migration, however, I get an unexpected result. EF is trying to add a User_Id column to the Tasks table, which I don't want, and dropping the foreign key I need for the master/detail relationship:

public override void Up()
{
    DropForeignKey("dbo.Tasks", "UserId", "dbo.Users");
    AddColumn("dbo.Tasks", "User_Id", c => c.String(maxLength: 128));
    AddColumn("dbo.Users", "MostImportantTaskId", c => c.String(maxLength: 128));
    CreateIndex("dbo.Tasks", "User_Id");
    CreateIndex("dbo.Users", "MostImportantTaskId");
    AddForeignKey("dbo.Users", "MostImportantTaskId", "dbo.Tasks", "Id");
    AddForeignKey("dbo.Tasks", "User_Id", "dbo.Users", "Id");
}

public override void Down()
{
    // ...
}

So how do I maintain the master detail relationship between users and tasks, while adding a reference to a single task to the User class?

解决方案

It's not something I'm overly familiar with but I believe what you're looking for is InverseProperty. As your User class has multiple relationships with Task, you need to add the InverseProperty to your Tasks collection to point it to the User property on Task.

So if you make this change in your User class

[InverseProperty("User")]
public ICollection<Task> Tasks { get; set; }

then when you run a migration the following code gets generated, which looks to be what you're after

public override void Up()
{
    AddColumn("dbo.Users", "MostImportantTaskId", c => c.String(maxLength: 128));
    CreateIndex("dbo.Users", "MostImportantTaskId");
    AddForeignKey("dbo.Users", "MostImportantTaskId", "dbo.Tasks", "Id");
}

public override void Down()
{
    DropForeignKey("dbo.Users", "MostImportantTaskId", "dbo.Tasks");
    DropIndex("dbo.Users", new[] { "MostImportantTaskId" });
    DropColumn("dbo.Users", "MostImportantTaskId");
}

Based on an example at entityframeworktutorial.net.

Note: I've assumed where you've referenced a Tasks class in your code it was a typo for Task.

这篇关于实体框架,代码优先:将主 - 细节与零到一关系相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆