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);