Muflix
Muflix

Reputation: 6798

How to define which foreign key navigation property should use?

I have two model classes

Registration

public class Registration
{
    // PK
    public int Id { get; private set; }
    
    // FK's
    public string AspNetUsersId { get; private set; }
    public int TimetableId { get; private set; }

    // EF Navigation properties
    public Timetable Timetable { get; set; }
    public ApplicationUser ApplicationUser { get; set; }

    // EF ctor
    private Registration()
    {
    }

    // public ctor
    public Registration(string aspNetUsersId, int timetableId)
    {
        AspNetUsersId = aspNetUsersId;
        TimetableId = timetableId;
    }
}

ApplicationUser

public class ApplicationUser : IdentityUser
{
   // some not relevant columns
}

When I try to execute this code

var registrationExists = _context.Registrations
     .Where(x => x.AspNetUsersId == user.Id 
          && x.TimetableId == timetable.Id)
     .SingleOrDefault();

I got an error

Microsoft.Data.SqlClient.SqlException: 'Invalid column name 'ApplicationUserId'.

I think that is because EF is trying to find (by default convention) Registration.ApplicationUserId column in database because of ApplicationUser navigation property. But the property (and sql column) is named AspNetUsersId and not ApplicationUserId. How can I override this naming in model builder (dbContext) ?

I tried something like

modelBuilder.Entity<Registration>(b => 
{
    b.HasAlternateKey(x => x.AspNetUsersId);
    b.HasOne(n => n.ApplicationUser); 
});

but I did not figure, how to map it together.

Upvotes: 0

Views: 2026

Answers (1)

Ulf M.
Ulf M.

Reputation: 126

You can write an annotation on the fields, e.g.

// PK
[Key]
public int Id { get; private set; }
    
// FK's
[ForeignKey(nameof(AspNetUsersId))]
public string AspNetUsersId { get; private set; }
[ForeignKey(nameof(TimetableId ))]
public int TimetableId { get; private set; }

Now, the property the [key] is the primary key and the properties with [ForeignKey()] are the FK's.

You can also use the modelBuilder:

modelBuilder.Entity<Registration>( 
  .HasAlternateKey(x => x.AspNetUsersId)
  .HasOne(n => n.ApplicationUser)
  .WithMany()
  .HasForeignKey(f => f.AspNetUsersId);

https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#single-navigation-property-1)

https://entityframeworkcore.com/model-relationships

Upvotes: 3

Related Questions