C
C#4mo ago
Mario K.

✅ Help with LINK Async !

Hi ! I am having a trouble with this code: public async Task<IEnumerable<Customer>> GetAllAsync() { var customers = await dbSet.ToListAsync(); return customers; } Awaiting this correctly returns all customers. However, this code does not work : public async Task<IEnumerable<Customer>> GetAllAsync() { var c = await _unitOfWork.CustomerRepository.GetAllAsync();
return c; } and c is an EMPTY list - Data.Entities.Customer[0] !!!! What am I doing wrong ?? Thank you in advance !
59 Replies
Jimmacle
Jimmacle4mo ago
i'm going to save you some time and tell you not to do this at all
canton7
canton74mo ago
It's not clear how those two methods are related
Jimmacle
Jimmacle4mo ago
you shouldn't be creating your own unit of work and repository if you're using EF core
canton7
canton74mo ago
Presumably the first method is defined on CustomerRepository?
Mario K.
Mario K.4mo ago
second method calls first method yes
canton7
canton74mo ago
Then I don't believe the premise of your question, quite bluntly. If the first GetAllAsync works correctly, there's nothing in the second one which will break things
Mario K.
Mario K.4mo ago
_unitOfWork.CustomerRepository.GetAllAsync(); IS public async Task<IEnumerable<Customer>> GetAllAsync()
canton7
canton74mo ago
(note that BOTH of your methods are "public async Task<IEnumerable<Customer>> GetAllAsync()") Also, it's not clear what you mean by "Data.Entities.Customer[0]". Is that accessing the first element of an array? Why would you do that if the array is empty? Plus, your methods return an IEnumerable which can't be indexed
Mario K.
Mario K.4mo ago
It is not empty, it has 4 entities
canton7
canton74mo ago
"and c is an EMPTY list" ?
Mario K.
Mario K.4mo ago
yes
canton7
canton74mo ago
So is c empty, or does it have 4 elements?
Mario K.
Mario K.4mo ago
it has 4 elements when I just call the 1st method but it has 0 when I call it fromthe second method
canton7
canton74mo ago
What about if you call the second method, but put a breakpoint on the 2nd line of the first method?
Jimmacle
Jimmacle4mo ago
why are you hiding EF behing a generic repository in the first place
Mario K.
Mario K.4mo ago
So this returns all records correctly : var customers = await customerRepository.GetAllAsync(); This returns empty : var c = await _unitOfWork.CustomerRepository.GetAllAsync();
canton7
canton74mo ago
Again, there's nothing in the code you posted which would take 4 elements, and throw them away
Mario K.
Mario K.4mo ago
I know !
canton7
canton74mo ago
I've no idea what customerRepository or _unitOfWork.CustomerRepository are, or how they relate, or why one might be doing something different to the other
Mario K.
Mario K.4mo ago
both are the same
Jimmacle
Jimmacle4mo ago
(they're bad practice is what they are)
canton7
canton74mo ago
Wait. You've confused me more A minute ago the problem was calling your 2nd method vs your first. Now it's calling customerRepository.GetAllAsync() vs _unitOfWork.CustomerRepository.GetAllAsync();, when customerRepository and _unitOfWork.CustomerRepository are the same object?
Mario K.
Mario K.4mo ago
exactly
canton7
canton74mo ago
So, which is it?
Jimmacle
Jimmacle4mo ago
i'd still like answers to my questions
canton7
canton74mo ago
A big problem is that you're only sharing small isolated snippets with no context, and expecting us to guess the rest Another big problem is that you've given us some code which has no issues, and are asking us what the issue is The problem is somewhere else. It's not in the code you've shared
Jimmacle
Jimmacle4mo ago
i mean, there is a problem with this code it shouldn't exist 😛
canton7
canton74mo ago
Yeah, we get that, architecturally But technically...
Mario K.
Mario K.4mo ago
So, first method is in a "data layer" the second one is in a "business layer" Apparently, that's cool 😦 The second method (llocaten in business layer) calls the first method (in data layer) that chain is somehow broken....
Anu6is
Anu6is4mo ago
can you confirm that your unit of work is actually calling what you expect?
Jimmacle
Jimmacle4mo ago
you need to step through the code with a debugger and find the first place that something goes wrong
Mario K.
Mario K.4mo ago
yes
canton7
canton74mo ago
☝️
Mario K.
Mario K.4mo ago
nothing happends
canton7
canton74mo ago
What do you mean by "nothing"?
Mario K.
Mario K.4mo ago
debugger just skips
canton7
canton74mo ago
I don't think your 2nd method is calling your first.... Try stepping into with the debugger
Jimmacle
Jimmacle4mo ago
the debugger doesn't skip if your breakpoint doesn't hit, the code wasn't run
Mario K.
Mario K.4mo ago
It gets me back to second method
canton7
canton74mo ago
"Gets me back"?
Mario K.
Mario K.4mo ago
yes, to second method this, for example, works like a charm: public async Task DeleteAsync(int modelId) { await Task.Run(() => _unitOfWork.CustomerRepository.DeleteByIdAsync(modelId)); await _unitOfWork.SaveAsync(); } public Task DeleteByIdAsync(int id) { Customer entity = dbSet.Find(id); try { dbSet.Remove(entity); context.SaveChangesAsync(); return Task.FromResult(id); } catch (Exception) { return Task.FromResult(id); } }
canton7
canton74mo ago
Uh, so many things wrong there Why the Task.Run? Why no await on SaveChangesAsync?
Mario K.
Mario K.4mo ago
that works the same
canton7
canton74mo ago
Please try and use helpful words "Works the same" doesn't carry any meaning. What works the same as what?
Mario K.
Mario K.4mo ago
Both approaces work the same
canton7
canton74mo ago
Which two approaches? Work the same in what sense? Not awaiting SaveChangesAsync is a problem
Mario K.
Mario K.4mo ago
Why the Task.Run? Why no await on SaveChangesAsync? work the same
canton7
canton74mo ago
What?
Jimmacle
Jimmacle4mo ago
no they don't your code is using EF (and tasks) incorrectly
canton7
canton74mo ago
I pointed out two problems in your code. You respond with "work the same"
Mario K.
Mario K.4mo ago
I'm just saying that DeleteAsync works fine, but GetAllAsync does not
Jimmacle
Jimmacle4mo ago
if it works fine it's by pure chance and it doesn't
Mario K.
Mario K.4mo ago
could be
Jimmacle
Jimmacle4mo ago
1. just await DeleteByIdAsync instead of using Task.Run 2. you must immediately await any async calls on a dbcontext
canton7
canton74mo ago
Right. I would not have guessed you were referring to GetAllAsync
Mario K.
Mario K.4mo ago
Can you be more specific regarding "immediately await any async calls" ?
Jimmacle
Jimmacle4mo ago
i can't if the dbcontext/set method ends in Async, you need to await it
canton7
canton74mo ago
Bad: context.FooAsync(); Good: await context.FooAsync(); Anyway, if you're debugging a call into your 2nd method, and it doesn't call into your 1st method, then that's a problem which you need to look at
Mario K.
Mario K.4mo ago
@canton7 @Jimmacle Thank you ! I appologize for stupid question ! Unfortunately, the other guy messed up the code and implemented wrong method call, so that GetAllAsync actually called GetAllWithDetailsAsync 🙂 Hence, naturally, the method I was writing never got called 🙂