β Collection appears to be null, even though it's not null on DB
I think the pictures already show the problem in more detail, there isn't much to it.
User and Person have a many to many relationship, and that is all, I think...
I don't have the slightest clue on why it says this.
Would appreciate some help on this, tkss π
45 Replies
The issue here is that I can't test if this user is already related to this person
originally it was just user.People.Add(person), but at some point I added those person lines too for some reason
yes, .Include(x => x.People) in the code inside GetUserAsync.
This is so that EF only gets from the DB what you ask for (otherwise it would write very inefficient SQL even if you only wanted a single field)
oh, that is what he meant, I did not understand when he answered
thank you a lot, will try it now
I might be doing something wrong again
is is suposed to be like this:
?
forgot to correct
ops
in discord
do you own the method "GetUserAsync"? (can you edit it)
nop, it is from Identity
this is the only User property that VS says is null
the rest of them are showing just fine (name, email, etc)
unfortunately you can't .Include the navigation property called .People then. So you will have to get the user from the _context itself
some properties are fine because they are columns in the same user table, but it won't go and get related entities from a different table (like .People)
I think I already done this, here
OOH
i think I understood it know
nah, I didn't :/
yep you've done the same thing, it's just that unfortunately you can't .Include that property when calling the built in Identity method - I thought you owned that code but you didn't
do you know what table your users are in?
in my db?
yeh, or the equivalent property name in your context
users are in an ApplicationUser table, all "persons" are in a People table, and there is an intermediary table ApplicationUsersPeople between this two that have both the ApplicationUserId and PersonId
for the many to many relationship
I think that was the answer to your question, I'm not sure if I answered correctly, sorry :/
then you will have to query or similar after the userManager.GetUserAsync(User) call
and then I change user in the code bellow for userWithPeople afterwards?
will try it, just a minute
yes that should work in a readable way
I have another code recommendation but we can solve this first
it said that the ApplicationUsers after _context was null
I'll change it for _userManager, just a sec
edit: this was just wrong
check this https://stackoverflow.com/questions/39837355/eager-loading-using-usermanager-with-ef-core, the answer for you actually in the question itself
oh, thank you, I'll read it
do you know if there is another approach for this? I still couldn't make it work
another approach would be entity framework lazy loading (in that case accessing .People will trigger additional SQL) but i'd avoid if possible - it's convenient but much less efficient!
you can investigate it to see if it suits your use case, but feel free to persist and post an update instead
you really do not want to use lazy loading in EF
surprise, synchronous, network IO on a property access is a nasty surprise
noooo, was half way into it already
well, I think I'll try another solution
this is way out of my current knowledge level, it's really frustrating sometimes
is there a reason why only People is not working here?
oh, is this asp.net identity?
yep
you might want to ask in #web or #database then
this might also help https://learn.microsoft.com/en-us/ef/core/querying/related-data/explicit
Explicit Loading of Related Data - EF Core
Explicit loading of related data with Entity Framework Core
it's empty because you are going via userManager, something provided to you via Identity.
It doesn't automatically know that you want all related data so it gives you the basics (column values). Anything more would result in a lot of SQL JOINs
so the line below that line crashes?
that's where explicit loading comes in
it lets you load after the fact, without the foot bazooka of lazy loading
see above where I recommended the explicit loading
the line bellow was the other attempt to correct this
it is like this
ApplicationUsers was null
you cannot explicitly load a navigation property via the user manager GetUserAsync(User) method, so you have to do it alone via the _context
hmm
yes, this was in a link you sent previously. Problem was that I couldn't make it work too :c
ApplicationUsers appeared null in this case
yeah ignore me. I am confusing @jcotton42 s responses by confusing eager loading with explicit loading, think ill go to sleep now.
yeah the naming isn't very good
classic microsoftism
so basically
do I need to put .Result after .GetUserAsync(User)?
no
that's what the await is for
also, looking at the docs, there's a LoadAsync https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.changetracking.collectionentry.loadasync?view=efcore-7.0#microsoft-entityframeworkcore-changetracking-collectionentry-loadasync(system-threading-cancellationtoken)
CollectionEntry.LoadAsync(CancellationToken) Method (Microsoft.Enti...
Loads entities referenced by this navigation property, unless IsLoaded is already set to true.
might want that
I'd still ask in #database and/or #web
I doubt you're the first to run into this
IT WORKED
I used the .Result after, VS was screaming with me if I didn't use it
no
you want
await foo
not foo.Result
using .Result
makes it synchronous, and can result in deadlockDon't Block on Async Code
This is a problem that is brought up repeatedly on the forums and Stack Overflow. I think itβs the most-asked question by async newcomers once theyβve learned the basics.
you need to change your controller method (FavoritePerson) to return Task<IActionResult> and add the async modifier
or follow the suggestions VS givees
if I take the Result off
stop working because b turns into a Task<ApplicationUser>
I can put .Result after the user, but I think it makes it synchronous the same way
@KooriByte that's why you await it
oh, I'm sorry, I forgot to add the await
Well, I'll close this. You both saved my day, thank you so much for helping π
I'll read the links you sent to understand this better