Bob.at.Indigo.Health
Bob.at.Indigo.Health

Reputation: 11895

Duplicate foreign key

I have two POCO entities, ApplicationUser and Account.

So, my entities are:

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

    public int AccountId { get; set; }
    public virtual Account Account { get; set; }
}

public class Account
{
    public int Id { get; set; }

    [ForeignKey("BillingContact")]
    public string BillingContactId { get; set; }
    public virtual ApplicationUser BillingContact { get; set; }

    public virtual ICollection<ApplicationUser> Users { get; set; }

My problem is that when I create a migration, code-first only partially understands that BillingContact is a foreign key. The migration code creates the Account table with the BillingContactId foreign key, but it also creates an extra Account_Id foreign key field.

I've found a workaround, but it seriously doesn't pass the "smell" test. The underlying problem is that I have multiple relationships between the two classes, which confuses code-first. In particular, the ApplicationUser entity does not have a navigation property that is the "other end" of the BillingContact foreign key.

If I add a navigation property to ApplicationUser, and mark it with the InverseProperty attribute then code-first seems to understand the foreign key and doesn't create the extra field:

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

    public int AccountId { get; set; }
    public virtual Account Account { get; set; }

    [InverseProperty("BillingContact")]
    public virtual ICollection<Account> MyBillingAccounts { get; set; }
}

The problem with this workaround is that the MyBillingAccounts navigation property is totally bogus. An Account has a related ApplicationUser that is the billing contact, but reverse relationship (navigating from an ApplicationUser back to the BillingContactId foreign key) makes no actual sense.

So... Is there a better (or proper) way to teach code-first about the BillingContactId foreign key?

Upvotes: 2

Views: 1746

Answers (1)

Gert Arnold
Gert Arnold

Reputation: 109109

You can only do this with fluent mapping. For example in an override of OnModelCreating of your context:

modelBuilder.Entity<Account>()
            .HasOptional(acc => acc.BillingContact)
            .WithMany()
            .HasForeignKey(acc => acc.BillingContactId);

The empty WithMany() call indicates that there is an inverse end of the association without a navigation property.

Upvotes: 3

Related Questions