How can I include two relational properties of the same type?

asp.net-core c# code-first entity-framework-core relational-database

Question

I have an ApplicationUser model:

public class ApplicationUser : IdentityUser
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    public List<Project> Projects { get; set; }
}

... and a Project model:

public class Project
{
    public int Id { get; set; }
    public int? ParentProjectId { get; set; }

    [Required]
    public string ProjectCreatorId { get; set; }

    [Required]
    public string ProjectOwnerId { get; set; }

    public string Title { get; set; }
    public DateTime Created { get; set; }

    public ApplicationUser ProjectCreator { get; set; }
    public ApplicationUser ProjectOwner { get; set; }
    public Project ParentProject { get; set; }
    public virtual List<Project> ChildProjects { get; set; }
}

In OnModelCreating(), I tried this:

base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Project>()
    .HasMany(c => c.ChildProjects)
    .WithOne(p => p.ParentProject)
    .HasForeignKey(p => p.ParentProjectId);

modelBuilder.Entity<ApplicationUser>()
    .HasMany(p => p.Projects)
    .WithOne(o => o.ProjectOwner)
    .HasForeignKey(po => po.ProjectOwnerId);

modelBuilder.Entity<ApplicationUser>()
    .HasMany(p => p.Projects)
    .WithOne(c => c.ProjectCreator)
    .HasForeignKey(pc => pc.ProjectCreatorId);

But upon creating the database, I get

Cannot create a relationship between 'ApplicationUser.Projects' and 'Project.ProjectCreator', because there already is a relationship between 'ApplicationUser.Projects' and 'Project.ProjectOwner'. Navigation properties can only participate in a single relationship.

I tried the solutions to this old question, but wasn't able to make any of them work.

Is there another way I could keep track of both a Project's creator AND owner, and be able to .Include() them both in the queries?

1
0
4/8/2020 12:11:24 PM

Popular Answer

I went for this solution:

As mentioned in the comments, ApplicationUser would need two List<Project>-properties:

public List<Project> CreatedProjects { get; set; }
public List<Project> OwnedProjects { get; set; }

Then, in OnModelCreating():

modelBuilder.Entity<Project>()
    .HasOne(g => g.ProjectCreator)
    .WithMany(t => t.CreatedProjects)
    .HasForeignKey(t => t.ProjectCreatorId)
    .HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Project>()
    .HasOne(g => g.ProjectOwner)
    .WithMany(t => t.OwnedProjects)
    .HasForeignKey(t => t.ProjectOwnerId).OnDelete(DeleteBehavior.NoAction)
    .HasPrincipalKey(t => t.Id);

Now I'm able to include both creators and owners. :)

0
4/8/2020 5:39:35 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow