-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding a join entity instance doesn't populate collections on the participating entities #23659
Comments
I've already investigated this to some extent, will soon paste a simplified repro on what is likely a bug. |
The issue here seems to be that inserting a M2M join entity (PlayerGame) referencing new instances (Playere, Game) does not cause the navigation properties on the instances to be populated. In contrast, when inserting a Player with a Game in its Games list, the Game's Players list is populated. @andleer as a workaround, you can reload the Player/Game from the database (see the use ChangerTracker.Clear below). Minimal reprovar player = new Player { Name = "Andrew", };
var game = new Game { Name = "Rocket League", };
var playerGame = new PlayerGame
{
Player = player,
Game = game
};
ctx.PlayerGames.Add(playerGame);
await ctx.SaveChangesAsync();
Console.WriteLine(player.Games is null); // True
ctx.ChangeTracker.Clear();
player = await ctx.Players.Include(p => p.Games).SingleAsync();
Console.WriteLine(player.Games is null); // False
public class BlogContext : DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Game> Games { get; set; }
public DbSet<PlayerGame> PlayerGames { get; set; }
static ILoggerFactory ContextLoggerFactory
=> LoggerFactory.Create(b => b.AddConsole().AddFilter("", LogLevel.Information));
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"...")
.EnableSensitiveDataLogging()
.UseLoggerFactory(ContextLoggerFactory);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Player>()
.HasMany(e => e.Games)
.WithMany(e => e.Players)
.UsingEntity<PlayerGame>
(
e => e.HasOne(k => k.Game).WithMany(k => k.PlayerGames),
e => e.HasOne(k => k.Player).WithMany(k => k.PlayerGames)
);
}
}
public class Player
{
public int PlayerId { get; set; }
public string Name { get; set; }
public virtual ICollection<Game> Games { get; set; }
public virtual ICollection<PlayerGame> PlayerGames { get; set; }
}
public class Game
{
public int GameId { get; set; }
public string Name { get; set; }
public virtual ICollection<Player> Players { get; set; }
public virtual ICollection<PlayerGame> PlayerGames { get; set; }
}
public class PlayerGame
{
public int PlayerId { get; set; }
public int GameId { get; set; }
public virtual Player Player { get; set; }
public virtual Game Game { get; set; }
} |
I agree with your assessment. Sorry I didn't spell that out before but it is pretty simple and I already have been using that as a workaround. But are you confirming it is a bug or possible future functionality? We're a little into the world of esoteric at this point so it doesn't matter much either way. I am good and appreciate the feedback. |
@andleer I think so, but let's let @AndriySvyryd confirm. |
… with generated key values This is a precursor to fixes for #23659, #23787. This test has no product changes, it just refactors the many-to-many tests so that they can be run with generated key values, as well as running with explicit keys values like they currently do. Generated keys result in more work being done in fixup by navigations, which is where both of these issues live. Once this is merged I will send out separate PRs to fix the two bugs.
Fixes #23659 If we encounter an unmapped entity during graph discovery of Attach, etc., then that entity is put aside for delayed fixup when it later becomes tracked. In this delayed fixup we were not populating skip navigations. The fix is to do this, just like happens in non-delayed fixup.
… with generated key values (#23807) This is a precursor to fixes for #23659, #23787. This test has no product changes, it just refactors the many-to-many tests so that they can be run with generated key values, as well as running with explicit keys values like they currently do. Generated keys result in more work being done in fixup by navigations, which is where both of these issues live. Once this is merged I will send out separate PRs to fix the two bugs.
Fixes #23659 If we encounter an unmapped entity during graph discovery of Attach, etc., then that entity is put aside for delayed fixup when it later becomes tracked. In this delayed fixup we were not populating skip navigations. The fix is to do this, just like happens in non-delayed fixup.
I don't know if this is a bug or am I missing something?
Two simple entities that are connected with a simple mapping table that contains a single payload item. Both (non-mapping) entities contain a collection of the opposing entity and a collection of the common mapping entity. If I add one of the non-mapping entities to the other's collection and attach the "base" entity to the context, the context mapping dbset is correctly populated but I am unable to default the mapping entity's payload in code or via fluent config.
I have tried populating the mapping entity along with the payload value and adding that to the context dbset and saving changes on the entity but the simple many to many collections on the non-mapping entities are not populated.
Seems like a catch 22.
Repo with tests:
https://github.com/andleer/BinaryOcean.EFCore5
EF Core version: 5.0.1
Database provider: Microsoft.EntityFrameworkCore.InMemory (5.0.1)
Target framework: .NET 5.0
Operating system: Win10
IDE: Microsoft Visual Studio Community 2019 Version 16.8.3
The text was updated successfully, but these errors were encountered: