Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
628 views
in Technique[技术] by (71.8m points)

c# - Can many-to-many relationships in EF Core 5.0 be configured keeping just one navigation property (on one side)?

I've configured my DbContext (EF Core 5.0) with the following code:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>()
        .HasMany(p => p.Roles)
        .WithMany(p => p.Users)
        .UsingEntity<Dictionary<string, object>>("UsersToRoles",
            x => x.HasOne<Role>().WithMany().HasForeignKey("UserId"),
            x => x.HasOne<User>().WithMany().HasForeignKey("UserId"),
            x => x.ToTable("UsersToRoles"));

    modelBuilder.Entity<Role>()
        .ToTable("Roles")
        .Property(r => r.Application)
        .IsRequired();

    base.OnModelCreating(modelBuilder);
}

The thing is that I wouldn't like the Role entity to hold a collection of Users. I'm keeping it because EF Core requires it to configure the many-to-many relationship.

Is there a way to create the same relationship, but without having to define the Role.Users navigation property?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The short answer is - what are you asking is desired, but not supported yet, as clearly stated (although not enough emphasized, but nobody likes to highlight the limitations) in the beginning of the current Many-to-many section of the official EF Core documentation (emphasis is mine):

Many to many relationships require a collection navigation property on both sides.

Also at the end of the original tracking item Many-to-many (skip) navigation properties #19003 you can see basically the same question

Hello, is there a way to avoid defining the property for one of the entities? e.g.

builder.HasMany(p => p.Tags).WithMany(); // notice no parameter in `WithMany`

and the response from the team is

Not yet #3864

pointing straight to Support unidirectional many-to-many relationships through shadow navigations #3864, which is the corresponding current open issue, and seems like is scheduled for 6.0 release.

As of why exactly, only the team members can answer that, but most likely it's because of the usual lack of enough time to fit something in the limited timeframe for delivering a specific release. A brand new (and not fully complete) concept (skip navigations) used to implement the actual feature, with a lot of possible improvements like Support non-many-to-many skip navigations #21673, the one in question and many others - you can see the current list here Improve many-to-many, skip navigations, and indexer properties #22960. Plus technical difficulties, the lack of shadow navigation property support (although that doesn't stop the other types of relationships which can be configured even w/o a navigation at neither side (how that would be useful is another story)) etc.

A final note in case you are looking for workaround/a way to overcome the current limitation. I usually like to go beyond the EF Core limitations, but here first I don't see a value (I personally look at navigation properties more like metadata representing a relationship in the LINQ queries rather than a storage), and also attempts to overcome it with using directly internal metadata APIs, along with the ugly looking code just led to a different runtime exceptions, which to me proves that the current code really relies on having the "inverse" navigation, and that is constrained in many places.

So at minimum you need a private ICollection<User> Users property or field, excluded from serialization and fluently configured

modelBuilder.Entity<User>().HasMany(e => e.Roles).WithMany("Users");

and live with the fact that it will be populated from the EF Core navigation fixup. Or better off, just live with the public navigation property and wait for the official implementation of the feature.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...