1

Hopefully this is just a simple one but I have just upgraded to the release version of EF core and can no longer run any code against the DB.

I have 2 tables, a client table and a language table. The client has two references to the language table, one for language and the other for language at home. So the Language has

public ICollection<Client> Clients { get; set; }

And Client has

public Language Language { get; set; }
private int? _languageId;

public int? LanguageId
{
    get
    {
        if (_languageId != 0)
            return _languageId;
        if (Language != null)
            return Language.LanguageId;
        return null;
    }
    set { _languageId = value; }
}

public Language LanguageAtHome { get; set; }
private int? _languageAtHomeId;

public int? LanguageAtHomeId
{
    get
    {
        if (_languageAtHomeId != 0)
            return _languageAtHomeId;
        if (LanguageAtHome != null)
            return LanguageAtHome.LanguageId;
        return null;
    }
    set { _languageAtHomeId = value; }
}

in my OnModelCreating I have the following two lines

modelBuilder.Entity<Client>().HasOne(m => m.LanguageAtHome).WithMany(m => m.Clients).HasForeignKey(p => p.LanguageAtHomeId).HasConstraintName("ForeignKey_Client_LanguageAtHome");
modelBuilder.Entity<Client>().HasOne(m => m.Language).WithMany(m => m.Clients).HasForeignKey(p => p.LanguageId).HasConstraintName("ForeignKey_Client_Language");

I have looked at the upgrade documentation for RC2 to V1 and it doesn't say anything about changes to this. https://docs.efproject.net/en/latest/miscellaneous/rc2-rtm-upgrade.html

The exception is:

System.InvalidOperationException: Cannot create a relationship between 'Language.Clients' and 'Client.Language', because there already is a relationship between 'Language.Clients' and 'Client.LanguageAtHome'. Navigation properties can only participate in a single relationship.

I tried reversing it to

modelBuilder.Entity<Language>().HasMany(l => l.Clients).WithOne(c => c.LanguageAtHome).HasForeignKey(k => k.LanguageAtHomeId).HasConstraintName("ForeignKey_Client_LanguageAtHome");
modelBuilder.Entity<Language>().HasMany(l => l.Clients).WithOne(c => c.Language).HasForeignKey(k => k.LanguageId).HasConstraintName("ForeignKey_Client_Language");

But I get the exact same error.

looking at the EF source on git hub i traced the error back to the internal relationship builder line 2145 in this changeset https://github.com/aspnet/EntityFramework/commit/5765564bc4dc55f9acb1716a1f5b40a8f8b0b399.

My hunch is that this change has occurred between RC2 and V1.

My question is is am i doing something wrong or is this a bug that has been introduced?

UPDATE -- Solved thanks to Andriy

I Changed my language class to have 2 collections of client like so

public ICollection<Client> LanguageAtHomeClients { get; set; }
public ICollection<Client> LanguageClients { get; set; }

and modified the relationship in the OnModelCreating to

modelBuilder.Entity<Client>().HasOne(m => m.LanguageAtHome).WithMany(m => m.LanguageAtHomeClients).HasForeignKey(p => p.LanguageAtHomeId).HasConstraintName("ForeignKey_Client_LanguageAtHome");
modelBuilder.Entity<Client>().HasOne(m => m.Language).WithMany(m => m.LanguageClients).HasForeignKey(p => p.LanguageId).HasConstraintName("ForeignKey_Client_Language"); 

I just upgraded to EF Core V1 and it all works a treat!

rosco
  • 87
  • 4

2 Answers2

2

As the exception states a navigation property can only be part of one relationship. In RC2 EF would silently replace the first one with the second one, but in RTM it throws to alert you to this fact. You should create another property, say ClientsAtHome for the other relationship.

Andriy Svyryd
  • 2,021
  • 1
  • 19
  • 26
0

It is not mandatory to refer the second collection in a many-to-many relation look at this in https://stackoverflow.com/a/44574378/3855971

Alejo Ferrand
  • 71
  • 1
  • 3