Map Many to Many relationship without navigation property
Asked Answered
I

1

15

Is is possible to map a many to many relationship without having a navigation property on one of the ends? For example I have some widgets and some users who can star particular widgets. I'd like to be able to see what widgets a user cares stars, but I don't really care about seeing all the users who have starred a particular widget

Widget.cs

public int Id { get; set; }
public string Name { get; set; }

User.cs

public int Id { get; set; }
public string Username { get; set; }
public ICollection<Widget> StarredWidgets { get; set; }

With this setup, EF will generate a one-to-many relationship from Widgets to Users. However, it needs to be a many to many. I realize I could add a public ICollection<User> Users to Widget.cs, but just seeing if there was another way around this.

Ingravescent answered 23/5, 2013 at 16:1 Comment(0)
K
42

You can and this case must define the many-to-many relationship with Fluent API:

modelBuilder.Entity<User>()
    .HasMany(u => u.StarredWidgets)
    .WithMany() // <- no parameter here because there is no navigation property
    .Map(m =>
    {
        m.MapLeftKey("UserId");
        m.MapRightKey("WidgetId");
        m.ToTable("UserWidgets");
    });
Kilowatthour answered 23/5, 2013 at 16:27 Comment(4)
This seems to setup the database tables correctly and when I call myUserPrefObj.StarredWidgets.Add(myWidget) the entry gets added to the join table correctly. However, later when I try to reload myUserPrefObj using a different db context, the StarredWidgets property is null. Any ideas?Ingravescent
Nevermind. I realized I forgot to mark the navigation property virtual.Ingravescent
@Kyle: That's "normal" :) If you want to load an entity and include one of its navigation property you must use, well... Include: context.Users.Include(u => u.StarredWidgets).Where.... Or mark StarredWidgets as virtual, then lazy loading will load the collection, but it will require a second DB query. With Include you need only one query.Kilowatthour
The .Map() part may be omitted.Optimist

© 2022 - 2024 — McMap. All rights reserved.