Reputation: 696
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?
Upvotes: 3
Views: 1920
Reputation: 1735
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.
Upvotes: 3