Home > Software design >  EFCore navigational properties are not mapped
EFCore navigational properties are not mapped

Time:04-29

I have a model Contact with three navigational properties of type Place but when I make a request in to database ids are filled but navigational properties are null. If someone knows where the problem comes from I'll be grateful.

This is my Contact model:

public class Contact
{
    public string Id { get; set; } = Guid.NewGuid().ToString();

    public string Name { get; set; }

    public string? IdPlaceContinent { get; set; }

    public Place PlaceContinent { get; set; }

    public string? IdPlaceCountry { get; set; }

    public Place PlaceCountry { get; set; }

    public string? IdPlaceCity { get; set; }

    public Place PlaceCity { get; set; }
}

And this is Place model:

public string Id { get; set; } = Guid.NewGuid().ToString();

    [ForeignKey(nameof(ParentPlaceIsContainedIn))]
    public string? IdPlaceIsContainedIn { get; set; }

    public Place ParentPlaceIsContainedIn { get; set; }

    public string Name { get; set; }

    public int LevelNo { get; set; }

    public ICollection<Contact> ContinentContacts { get; set; } = new HashSet<Contact>();

    public ICollection<Contact> CountryContacts { get; set; } = new HashSet<Contact>();

    public ICollection<Contact> CityContacts { get; set; } = new HashSet<Contact>();

    public ICollection<Place> ChildPlaceIsContainedIn { get; set; } = new HashSet<Place>();

This is my DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Contact>().Property(x => x.Name).HasColumnType("nvarchar(100)");
        modelBuilder.Entity<Contact>().Property(x => x.Description).HasColumnType("ntext");
        modelBuilder.Entity<Contact>().Property(x => x.Phone).HasColumnType("varbinary(100)");
        modelBuilder.Entity<Contact>().Property(x => x.eMail).HasColumnType("varchar(100)");
        modelBuilder.Entity<Contact>().Property(x => x.Categories).HasColumnType("varchar(100)");
        modelBuilder.Entity<Contact>().Property(x => x.Areas).HasColumnType("varchar(100)");
        modelBuilder.Entity<Contact>().Property(x => x.Event).HasColumnType("varchar(100)");
        modelBuilder.Entity<Contact>().HasOne(x => x.PlaceCity).WithMany(x => x.CityContacts).HasForeignKey(x => x.IdPlaceCity).OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<Contact>().HasOne(x => x.PlaceContinent).WithMany(x => x.ContinentContacts).HasForeignKey(x => x.IdPlaceContinent).OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<Contact>().HasOne(x => x.PlaceCountry).WithMany(x => x.CountryContacts).HasForeignKey(x => x.IdPlaceCountry).OnDelete(DeleteBehavior.Restrict);

        modelBuilder.Entity<Place>().Property(x => x.Name).HasColumnType("nvarchar(50)");
        modelBuilder.Entity<Place>().Property(x => x.LevelNo).HasColumnType("tinyint");
        modelBuilder.Entity<Place>().HasOne(x => x.ParentPlaceIsContainedIn).WithMany(x => x.ChildPlaceIsContainedIn).OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<Place>().Property(x => x.IdPlaceIsContainedIn).IsRequired(false);
    }

CodePudding user response:

EF has lazy-loading enabled by default.

So, in your case, you have to explicitly include the related data. You can use Include, which is part of: Microsoft.EntityFrameworkCore.

var contact = await this.
  _dbContext.Contacts
  .Include(c => c.PlaceContinent)
  .Include(c => c.PlaceCountry)
  .Include(c => c.PlaceCity)
  .FirstOrDefaultAsync(x => x.Id == id);
  • Related