Search code examples
c#ef-code-firstentity-framework-corelazy-loadingeager-loading

Relations between classes entityframeworkcore code-first


I am a beginner in entity framework core but I have used Linq to SQL before by creating the database first. I am trying to write the code first with entity.

I have a database with multiple tables, and cannot figure out why i cannot use the relationships between classes.

Simple Case: I have a Class Chat that relates with a many to many relationship with the class User.

Chat class

public int Id { get; set; }
public int StarterUserId { get; set; }
public User StarterUser { get; set; }
public int OtherUserId { get; set; }
public User OtherUser { get; set; }

User class has an Id property.

public int Id { get; set; }
public List<Chat> InChats { get; set; }
public List<Chat> OutChats { get; set; }

And I have defined in the OnModelCreating method:

modelBuilder.Entity<Chat>()
            .HasOne(x => x.StarterUser)
            .WithMany(m => m.OutChats)
            .HasForeignKey(x => x.StarterUserId);
modelBuilder.Entity<Chat>()
            .HasOne(x => x.OtherUser)
            .WithMany(m => m.InChats)
            .HasForeignKey(x => x.OtherUserId);

When I get a Chat object, and watch it properties, I have OtherUser as an object of User class, and OtherUserId=26 (GOOD)

But i have StarterUserId=1 and I have StarterUser as null.

In the database I can see the relationships that are defined correctly. StarterUserId and OtherUserId are both foreign keys in Users Table

Why is that? How can I fix this?

Solved: I enabled lazy loading and not i can get the related data.

  1. I installed Microsoft.EntityFrameworkCore.Proxies package from nuget
  2. When adding my DbContextI enabled lazy loading using .UseLazyLoadingProxies()
  3. Changed the modifiers from public to public virtual for the properties i needed to get the related data

Solution

  • Problem is in your query but you did not add your query to the question!!. I assume you are missing eager-loading the related entities.

    So you have to eager load the OtherUser using .Inlcude in your query and your query should be as follows:

    _dbContext.Chats.Include(c => c.StarterUser)
                    .Include(c => c.OtherUser).Where(c => c.Id == 1).FirstOrDefault();
    

    For more details: Loading Related Data in EF Core