3

I'm using Entity Framework Core 2.0 to map exist DB, the DB has two tabels: Teams and SupportTeam.

Team Fields: ID, Name

TeamSupport: TeamID (ForeignKey on Team Table), SupportTeamID (ForeignKey on Team Table)

I tried to map them as following:

 public class Team
 {
     public int Id { get; set; }
     public string name { get; set; }

     public List<TeamSupport> SupportTeams { get; set; }

 }

 public class TeamSupport
 {
     public int TeamId { get; set; }
     public virtual Team Team { get; set; }

     public int SupportTeamId { get; set; } // In lack of better name.
     public virtual Team SupportTeam { get; set; }
 }

But I had the follwing error when i run "add-migration":

Unable to determine the relationship represented by navigation property 'Team.SupportTeams' of type 'List'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
Shannak
  • 376
  • 4
  • 10

1 Answers1

2

The TeamSupport entity has two reference navigation properties to Team (which define two many-to-one relationships between TeamSupport and Team), but the Team entity has only one collection navigation property, hence EF does not know how to map it (to Team.Team or Team.SupportTeam) and throws the exception in question.

In such scenarios you have to resolve the mapping explicitly. Usually it's enough to use [InverseProperty] data annotation, but multiple references to the same table always lead to multiple cascade paths problem, which requires turning the delete cascade off for one or more of the relationships. And the later can be done only with fluent configuration, so it's better to do the whole mapping with fluent configuration as well.

The minimal configuration needed by your model the way it is now is:

modelBuilder.Entity<TeamSupport>()
    .HasOne(e => e.Team)
    .WithMany(e => e.SupportTeams);

modelBuilder.Entity<TeamSupport>()
    .HasOne(e => e.SupportTeam)
    .WithMany()
    .OnDelete(DeleteBehavior.Restrict);

Note that since there is no corresponding collection navigation property, the second relationships configuration uses the parameterless WithMany overload to indicate that. In case you decide to add such collection to the model

public class Team
{
    public int Id { get; set; }
    public string name { get; set; }

    public List<TeamSupport> SupportTeams { get; set; }
    public List<TeamSupport> SupportOfTeams { get; set; } // <--
}

don't forget to specify that in the corresponding mapping

.WithMany(e => e.SupportOfTeams)

otherwise EF will create a third relationship.

For more info, see Relationhips section of the EF Core documentation.

Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • in this case the SupportTeams type is List. how can I reaturn SupportTeams as List. – Shannak Apr 15 '18 at 08:24
  • 1
    If you mean at model level, you can't currently as mentioned in the [Many-to-many](https://learn.microsoft.com/en-us/ef/core/modeling/relationships#many-to-many) subsection in the documentation link from the answer: *"Many-to-many relationships without an entity class to represent the join table **are not yet supported**."* But you can always extract the `SupportTeam` property from `TeamSupport` list using LINQ `Select`. – Ivan Stoev Apr 15 '18 at 08:30