coto2
coto2

Reputation: 179

Adding a Foreign Key referencing AspNetUser when creating a table using Code First - MVC5

I am creating a Visual Studios MVC5 Web application and I am trying to reference the id from AspNetUser table as a foreign key.

I am creating a new table :

public class Patient
{
    public int PatientId { get; set; }
    public string HCN { get; set; }
    public string GP { get; set; }
    public string MedHis { get; set; }
    public string Medication { get; set; }
    public string CurrentPrescription { get; set; }
    public string PresentRX { get; set; }

    [ForeignKey("UserId")]
    public virtual ApplicationUser UserId { get; set; }
}

My Patient config class :

public class PatientConfig : EntityTypeConfiguration<Patient>
{
    public PatientConfig()
    {
        ToTable("Patient");

        Property(x => x.PatientId).HasColumnName("IntId");
        HasKey(x => x.PatientId);

        Property(x => x.HCN).HasColumnName("strHCN");
        Property(x => x.GP).HasColumnName("strGP");
        Property(x => x.MedHis).HasColumnName("strMedHis");
        Property(x => x.Medication).HasColumnName("strMedication");

        Property(x => x.CurrentPrescription).HasColumnName("strCurrentPrescription");

        Property(x => x.PresentRX).HasColumnName("strPresentRX");
        Property(x => x.UserId).HasColumnName("intUserId");
    }
}

Firstly I was getting the error

Must be a non-nullable value type in order to use it as a parameter

underneath the UserId property so I removed it

Property(x=> x.UserId).HasColumnName("intUserId");

When I tried to add the migration I got the following error:

The ForeignKeyAttribute on property 'UserId' on type 'ModelTest.Models.Patient' is not valid. The foreign key name 'UserId' was not found on the dependent type 'ModelTest.Models.Patient'. The Name value should be a comma separated list of foreign key property names.

I don't understand how the UserId cannot be found, any advice would be greatly appreciated.

Thanks

Upvotes: 0

Views: 4543

Answers (2)

YawningThunder
YawningThunder

Reputation: 11

[ForeignKey("User")]<br/>
public string UserId { get; set; }<br/>
public virtual ApplicationUser User { get; set; }

When I add the above lines to the class, and then migrate and update the DB,
I get ApplicationUser Table created !

Upvotes: 0

Chris Pratt
Chris Pratt

Reputation: 239260

This works like any other relationship. There's nothing special about ApplicationUser. It seems you just don't really understand how to set up Entity Framework relationships in the first place.

If you don't care about having an explicit foreign key property that you can access in your application, then all you need to add to your entity is:

public virtual ApplicationUser User { get; set; }

That will cause Entity Framework to generate an implicit foreign key on your entity's table, but you won't be able to access this value directly in your application. User will be a full instance of ApplicationUser.

If you do want access to the foreign key property directly, then you need something like:

[ForeignKey("User")]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }

Now, there's an actual property on the entity to hold the foreign key value, in addition to the navigation property that allows you to access the appropriate ApplicationUser instance.

While Entity Framework should actually be able to figure out that UserId is the foreign key for the User navigation property on its own by convention, I find it better to always be explicit by using the ForeignKey attribute.

Also, notice that the type for UserId is string. This the type IdentityUser uses by default for the primary key. You can change that if you like, but if you just use the standard deployment, then it'll be a string rather than something like int, which you seem to have assumed it would be in your code.

Upvotes: 3

Related Questions