✅ 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 !
return c; } and c is an EMPTY list - Data.Entities.Customer[0] !!!! What am I doing wrong ?? Thank you in advance !
59 Replies
i'm going to save you some time and tell you not to do this at all
It's not clear how those two methods are related
you shouldn't be creating your own unit of work and repository if you're using EF core
Presumably the first method is defined on
CustomerRepository
?second method calls first method
yes
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_unitOfWork.CustomerRepository.GetAllAsync(); IS public async Task<IEnumerable<Customer>> GetAllAsync()
(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 indexedIt is not empty, it has 4 entities
"and c is an EMPTY list" ?
yes
So is
c
empty, or does it have 4 elements?it has 4 elements when I just call the 1st method
but it has 0 when I call it fromthe second method
What about if you call the second method, but put a breakpoint on the 2nd line of the first method?
why are you hiding EF behing a generic repository in the first place
So this returns all records correctly : var customers = await customerRepository.GetAllAsync();
This returns empty : var c = await _unitOfWork.CustomerRepository.GetAllAsync();
Again, there's nothing in the code you posted which would take 4 elements, and throw them away
I know !
I've no idea what
customerRepository
or _unitOfWork.CustomerRepository
are, or how they relate, or why one might be doing something different to the otherboth are the same
(they're bad practice is what they are)
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?exactly
So, which is it?
i'd still like answers to my questions
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
i mean, there is a problem with this code
it shouldn't exist 😛
Yeah, we get that, architecturally
But technically...
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....
can you confirm that your unit of work is actually calling what you expect?
you need to step through the code with a debugger and find the first place that something goes wrong
yes
☝️
nothing happends
What do you mean by "nothing"?
debugger just skips
I don't think your 2nd method is calling your first....
Try stepping into with the debugger
the debugger doesn't skip
if your breakpoint doesn't hit, the code wasn't run
It gets me back to second method
"Gets me back"?
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);
}
}
Uh, so many things wrong there
Why the
Task.Run
? Why no await on SaveChangesAsync
?that works the same
Please try and use helpful words
"Works the same" doesn't carry any meaning. What works the same as what?
Both approaces work the same
Which two approaches? Work the same in what sense?
Not awaiting
SaveChangesAsync
is a problemWhy the Task.Run? Why no await on SaveChangesAsync? work the same
What?
no they don't
your code is using EF (and tasks) incorrectly
I pointed out two problems in your code. You respond with "work the same"
I'm just saying that DeleteAsync works fine, but GetAllAsync does not
if it works fine it's by pure chance
and it doesn't
could be
1. just await DeleteByIdAsync instead of using Task.Run
2. you must immediately await any async calls on a dbcontext
Right. I would not have guessed you were referring to GetAllAsync
Can you be more specific regarding "immediately await any async calls" ?
i can't
if the dbcontext/set method ends in Async, you need to await it
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@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 🙂