Search code examples
asp.net-coreentity-framework-coreforeign-keysef-database-first

How do I map foreign keys in Entity Framework Core to an existing database?


Just as a heads up I'm completely new to this and this part has had me stumped for a bit. I haven't found a straight answer that worked (and everything else went right over my head) so please be patient with me, and preferably explain it like you would to a five year old.

I'm building a new API for an existing database, the models I have use non conventional naming schemes (Like "track_id" instead of Id) and the mapping isn't how EF likes it (Like foreign keys/columns only going in one direction, there's not column or property pointing back). Seeing how I'm a beginner, I followed a tutorial until their method of using One->Many did not apply to what I was making. Like I said before, nothing else on the internet worked out of the box, and my HTTP calls either return the foreign key properties/links as nulls or just return an exception.

Assume that the parent model I have is Student_Material and it has one of its foreign keys point to another child model called Track. Student_Material in the DB model stored an int value in the column named "track_id" that correlates with Track, there's nothing that points back (it's unnecessary for the purposes of this application).

I tried different combinations of: In the Student_Material model:

[Foreign Key("track_id")]

public virtual Track track {get; set;}

sometimes adding

public int track_id {get; set;}

but that breaks the code because EF keeps adding an extra column "track_id1" for whatever reason.

I tried constructing a relationship in DBContext but it was also fruitless..

modelBuilder.Entity<Student_Material>().HasKey(x => x.student_material_id);
modelBuilder.Entity<Student_Material>().HasOne(sm => sm.track)
    .WithMany(t => t.student_material)
    .HasForeignKey("track_id");

and back

modelBuilder.Entity<Track>().HasMany(t => t.student_materials)
    .WithOne(sm => sm.track);

I also tried to add a virtual ICollection in the track model but it's useless, always returns null:

public virtual ICollection<Student_Material> student_materials { get; set; }

I asked people about it irl, and one of them suggested to used a code-first approach, but if EF doesn't recognize the foreign key mapping no matter how I write it down, the resulting DB is foreign-keyless anyway. Any hints are appreciated.


Solution

  • For one-to-many relationship you could assign foreign key like below. Needn't construct relationship in context.

        public class Student_Material
        {
            [Key]
            public int student_material_id { get;set; }
    
         
            public int track_id { get; set; }
            [ForeignKey("track_id")]
            public virtual Track track { get; set; }
        }
    
        public class Track
        {
            [Key]
            public int track_id { get; set; }
    
            public ICollection<Student_Material> student_materials { get; set; }
    
        }