Reputation: 12904
I have defined a Many to Many relationship between 2 objects. Each object exposes the same Navigation property in order for me to traverse the relationships by code. The setup is as follows;
public class Message : Entity<int>
{
public int UserId { get; set; }
public User User { get; set; }
public Guid Reference { get; set; } = Guid.NewGuid();
public virtual ICollection<MessageGroup> MessageGroups { get; set; } = new HashSet<MessageGroup>();
}
}
public class Group : Entity<int>
{
public int UserId { get; set; }
public User User { get; set; }
public Guid Reference { get; set; } = Guid.NewGuid();
public virtual ICollection<MessageGroup> MessageGroups { get; set; } = new HashSet<MessageGroup>();
}
public class MessageGroup
{
public int MessageId { get; set; }
public Message Message { get; set; }
public int GroupId { get; set; }
public Group Group { get; set; }
}
and this in my Context;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MessageGroup>()
.HasKey(bc => new { bc.GroupId, bc.MessageId });
modelBuilder.Entity<MessageGroup>()
.HasRequired(bc => bc.Group)
.WithMany(b => b.MessageGroups)
.HasForeignKey(bc => bc.GroupId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<MessageGroup>()
.HasRequired(bc => bc.Message)
.WithMany(c => c.MessageGroups)
.HasForeignKey(bc => bc.MessageId)
.WillCascadeOnDelete(false);
}
However, when I attempt to load a Message that has multiple groups (records are correct in MessageGroup
table), only the Messages
are shown. For Information, I am loading these through the Messages
DbSet. When I then load the Group through the Groups
DbSet, the reverse happens, and only the Groups
are shown.
Loaded from Messages DbSet;
Loaded from Group DbSet;
I can get both by using the MessageGroup
DbSet and Including them;
var messageGroups = context.MessageGroups.Where(x => x.MessageId == id).Include(x => x.Group).Include(x => x.Message).ToList();
but I want to be able to load my Message or Group and have these available.
For information, my context is wrapped around another layer and I have exposed a few methods for each Type but ultimately, I am calling;
public T Get(U id)
{
return _dbSet.Find(id);
}
Upvotes: 1
Views: 477
Reputation: 205849
When a collection navigation property is loaded, the EF navigation property fixup also loads the corresponding inverse navigation property. But other navigation properties must be loaded explicitly (eager, explicit or lazy).
Since you seem to rely on lazy loading the MessageGroups
collection navigation properties, you should make the inverse reference navigation properties in MessageGroup
virtual
too:
public class MessageGroup
{
public int MessageId { get; set; }
public virtual Message Message { get; set; }
public int GroupId { get; set; }
public virtual Group Group { get; set; }
}
Upvotes: 2