I need help trying to understand why my Blazor (server-side) component in .net Core 6 is not updating my database when removing an entity, please take a look at my code sample: (beforehand, thanks for all your help!)
First, I'm injecting my db context as follow:
@inject AppDbContext db
then, below on my code, I decided to query for some data, in this case, Customers as follow:
@code {
private List<Customer> clients { get; set; }
protected override async Task OnInitializedAsync()
{
clients = await db.Customers.ToListAsync();
}
}
Now, I created a button with a method to delete the customer; first I search the entity, if found, then I remove the item from the "clients" list from the database, as follow:
private async Task DeleteCustomer(int CustomerId)
{
Customer? customer = clients.FirstOrDefault(f => f.Id == CustomerId);
if (customer is not null)
{
clients.Remove(customer);
await db.SaveChangesAsync();
}
}
THE PROBLEM is that the entity is removed from the list but not removed from the database, so when I refresh the item still there, I have to apply another command inside the if to make it work:
db.Remove(customer);
in other words, I have to remove it from the clients list and in the list also, making the work double, it seems to me it loses completely the connection (or ref) between the list coming from the DB and the database. This is the first time I see something like this, am I missing something? am I using the EF the way I am supposed to do? I can just add that command and make it work but I don't think is a good practice, please help!
CodePudding user response:
Yeah, that is because this is just how EF works.
The client list is contains the queried elements. Even after remove, it still is a queried element. There is no logical way for Ef to update clients - ESPECIALLY as Clients is a List which has no API for this in a sensible way.
So, you must remove it from both, which is logical.
Actually you get it totally wrong. Removing something from clients is not triggering anything from Ef because it makes no sense to start. I could remove them to THEN run code over it - and would trigger an automatic removal from the db just for filtering something out in the UI. Only the db.Remove actually tells Ef it is to remove it FROM THE DATABASE. This is not double, it is Ef not magically reading your mind.
CodePudding user response:
You have to remove item from dbcontext, not from the list. After you created view, all your dbcontext was disposed and list is not connected. When you try to delete you have a different db context already. So you need this
public async Task DeleteCustomer(int CustomerId)
{
var customer = await db.Customers.FirstOrDefaultAsync(f => f.Id == CustomerId);
if (customer!=null)
{
db.Customers.Remove(customer);
var result= await db.SaveChangesAsync();
// you can add if it makes a difference
if(result==1) clients.Remove(customer);
}
}
after deleting you can call
clients = await db.Customers.ToListAsync();
again and get an updated list of customers.