✅ Do we need to explicitly set foreign keys in EF Core?
Hello guys, just a quick question. Say I want to implement the following table which contains 2 foreign keys. Can EF Core automatically infer that the MemberId and BookId are foreign key (Assume we add navigation property in each table where needed)?
34 Replies
No need to
EF works by convention in this case
yeah I see, what does it look for it to identify the foreign key ?
things like {Book}Id ?
Property
[Name]Id
will automatically be treated as a foreign key for property [Name]
YepYep I see, thanks !
Same for the primary key
[ClassName]Id
and Id
both workyep noted 👍
also fwiw, when setting the relationship you can change either the id or the actual object, you don't have to change both
Yep, I guess its better to change the Id, no ?
it depends on what you have at the time
sometimes you have the object, sometimes you only have the id
it's not worth a database roundtrip to pull the whole entity if you just need to change the id
if you're creating new entities then you don't even have an id to set and you have to set the object
Could technically do weird shenanigans with manually attaching the entity you created from just the ID, but... don't
This is what you guys mean by either using the id or the object?
is this what you mean please
did you try it?
For the option 1 yeah, I did it when creating a new lending object
This is what I did:
based on the book and member I added, I added a new record in Lending table
so you can just change BookId and MemberId in the last query to refer to the objects you created earlier
yeah 5 database roundtrips is not necessary, you can do it all in one
also, you are inconstently using both SaveChanges and SaveChangesAsync
if you added both a book and a lender at the same time, you wouldn't be able to use BookId since it doesn't have an id at that point
oh ok, but then I would do something like BookId = book.BookId ?
hmm what do you mean pls
yeah was just experimenting with but there is nothing to do with Async at this stage I think, I should remove that
just
Book = book
in that casehmm when we create the new lending, like instead of using BookId and MemberId, we say Book = book and Member = member ?
oh I see what you mean, like the context.SaveChanges, thing ?
3 pings in 4 minutes is crazy
ops, sorry :c
when writing
Book = book and Member = member
, behind the scenes, EF Core does the following: Book = book.BookId and Member = member.MemberId
?not necessarily
if they're new entities then EF doesn't know their IDs yet assuming they're database generated
it will produce an appropriate query for that
yeah I see, so the thing is, can we write something like that:
Here, notice we have 2
context.SaveChanges()
... what I thought is, we must first create the book and member objects to have valid foreign keys else, we won't know what book.BookId and member.MemberId are.you also don't have to re-query to get the ID of a new entity you've saved, that should be automatically updated by EF after calling SaveChanges iirc
you don't need to know what they are, EF can manage it
it knows what relationships should be set based on the object graph and it will set FKs as part of the change saving process
oh ok, so I can just write a single context.SaveChanges() at the end provided that, I write something like that:
it should work
yep noted, I will test and let you know, ty !!
Book, not BookId
i didn't say anything about that because the compiler will catch it :when:
Soo, so I write this:
This works well, it was save in the db. Now, what I tried to do next, is to change Book = book from Book = book.BookId and Member = member from Member = member.MemberId.
query.Lendings.Add(new Lending{DueDate = new DateTime(2025,08,08), IssueDate = DateTime.Now, Book = book.BookId, Member = member.MemberId});
But it seems I get a compiler error where Cannot convert source type 'int' to target type
.
Ok, so, the thing, here Book and Member represent book and member objects respectively, that's why I can directly assign an int like I was doing earlier when I was explicitly setting the foreign keys.
So, question:
Here, we set the navigation properties, we don't use the foreign keys them, we could also have said BookId = book.BookId, no? would there be a difference?
yeah I got an error when I use the foreign keys, BookId and MemberId
I shouldn't use them, unless may be if I use 2 context.SaveChanges(), like we create the book and member object first? but too much of work
I will stick with the navigation properties, I guess it's easier (waiting for your feedbacks :c)setting either the navigation or the id has the same effect on updating the FK
because if you haven't saved the entities yet their IDs will be 0
which isn't a problem if you save them all at once, EF can figure it out
but you can't mix creating new entities and assigning specific IDs as FKs at the same time
ahhh I see, like since we are creating the new entity without saving them yet, we don't really have a foreign key, that's why I can't really do
BookId = book.BookId
? EF does know that is the BookId
though when saving it all at once but in our code, we don't know yet ?yes, before you call SaveChanges it's all just C# code
so if
book.Id
is 0 and you set BookId = book.Id
, BookId
will be 0
EF doesn't know where that value came from so it can't figure out that you want it to match a book that you're creating
but if you set the actual Book
navigation, it not only knows that there's a whole new entity to create but also that you want it to be related to the lending
so it can handle updating the IDs behind the scenes as part of savingyep I see
It's clearer now, thanks guys ! Learn a lot of things 🔥
I guess all my doubts have been cleared, should be good for now, will come back if I have other questions, thanks once more !