0

I´m having trouble understand EF.

I have 2 tables in a N-to-N relationship. When I create the model in Visual Studio I get it like the picture below. Artist is related to Album, and Album is related to Artist. In the database I have a table to relate both tables.

My question is:

enter image description here

Why can I add an artist with two albums,

var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
var album1 = new Album { AlbumName = "Drive" };
var album2 = new Album { AlbumName = "Live at Texas Stadium" };
artist.Albums.Add(album1);
artist.Albums.Add(album2);
context.Artists.Add(artist);

But can´t do the other way around?

var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
var album = new Album { AlbumName = "Honkytonk University" };
artist1.Albums.Add(album);
artist2.Albums.Add(album);
context.Albums.Add(album);

context.SaveChanges();

It´s not making sense to me, since both tables in VS model have the Navigation Properties correct, isn´t the same adding to left or right? In my mind, in the second case EF should add artist1 and artist2 to DB.

Thanks for reading. FranciscoRC

CodeNotFound
  • 22,153
  • 10
  • 68
  • 69
  • 1
    If you want the exact other way around, the corresponding code should be `album.Artists.Add(artist1); album.Artists.Add(artist2); context.Albums.Add(album);` – Ivan Stoev Jun 18 '18 at 20:29

1 Answers1

1

To expand on Ivan's comment.

With this example:

var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
var album = new Album { AlbumName = "Honkytonk University" };
artist1.Albums.Add(album);
artist2.Albums.Add(album);
context.Albums.Add(album);

Prior to SaveChanges, album.Artists hasn't been set with anything, and all EF has to go on is what you've set on album.

In your case, you've created 2x artist objects, and 1 album. You've associated the album to the artist, but you've only notified EF of the album to be saved. Just as with POCOs just because an artist has an album and an album has an artist, setting the album on an artist doesn't automatically set the artist property on an album. EF does this behind the scenes provided that it sees the related entities on the entity(ies) you add to the context.

So the following should work:

var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
var album = new Album { AlbumName = "Honkytonk University" };
album.Artists.Add(artist1);
album.Artists.Add(artist2);
context.Albums.Add(album);

Prior to SaveChanges being called, artist1.Album will be null because you haven't set anything. After SaveChanges, artist1 & 2 .Album will reference to your new entity because EF resolved the Artists collection on the album and wired up the related references. (Even though Artists 1 & 2 were not added to the context explicitly.)

Steve Py
  • 26,149
  • 3
  • 25
  • 43
  • I guess in the end it's all a question of implementation. I think EF's change tracker could have been made smart enough to detect the added relationship from the `album`'s end (in your first code snippet), but it isn't. These many-to-many relationships are... [a handful](https://stackoverflow.com/a/20920753/861716). – Gert Arnold Jun 19 '18 at 07:15
  • Steve, thanks for the explanation. I think I go it. On the 2nd case, because I "start saving " by album, when EF looks at the List it doesn´t see any artist an stops. – Francisco Conceição Jun 19 '18 at 09:15