Update and retrieve data problem

raysefo

Well-known member
Joined
Feb 22, 2019
Messages
361
Programming Experience
10+
Hello guys,


In my Blazor Server Application, there is this master-detail data grid. This data grid is populated with IsActive = 1 data OnInitializedAsync method.
Here is the Order repository and related query which retrieves active data:
GetAllOrders:
public class OrderRepository : IOrderRepository
    {
        private readonly IMSContext _db;
        
        public OrderRepository(IMSContext db)
        {
            _db = db;
           
        }
public async Task<IEnumerable<Order?>> GetAllOrders(ClaimsPrincipal user)
        {
            if (user.IsInRole("Administrators"))
            {
                return await _db.Orders.Include(d => d.OrderDetails.Where(od => od.IsActive == 1)).ThenInclude(v => v.Vendor).ToListAsync();
            }
            
            return await _db.Orders.Where(u => u.DoneBy == user.Identity.Name).Include(d => d.OrderDetails.Where(od => od.IsActive == 1)).ThenInclude(v => v.Vendor).ToListAsync();

        }

And here is the OrderDetail repository which sets the related order detail to IsActive = 0
PassiveOrderDetailAsync:
namespace IMS.Plugins.EFCore
 {
     public class OrderDetailRepository : IOrderDetailRepository
     {
         private readonly IMSContext _db;
    
         public OrderDetailRepository(IMSContext db)
         {
             _db = db;
         }
    
    
         public async Task PassiveOrderDetailAsync(OrderDetail orderDetail)
         {
              
             var detail = await this._db.OrdersDetail.FindAsync(orderDetail.Id);
             if (detail != null)
             {
                    
                 detail.IsActive = 0; // 0-Passive
                    
                 await _db.SaveChangesAsync();
             }
         }
          
     }
 }

Here is the method I am updating record IsActive = 0 and get all the records which are IsActive = 1. (GetAllOrders)
PassiveDetail:
async Task PassiveDetail(OrderDetail orderDetail)
        {
            ...
    
             await PassiveOrderDetailUseCase.ExecuteAsync(orderDetail); // sets record IsActive=0
            _orders = await ViewAllOrdersUseCase.ExecuteAsync(user); //GetAllOrders, suppose to retrieve only IsActive = 1, but somehow it returns IsActive=0 the updated record
            
            StateHasChanged();       
    
        }
0.png
 
How else will I know if there is a problem in LINQ? My first linq was without AsNoTracking() but somehow it still got IsActive = 0.
 
Writing a t raw

Your alternate test is to use the same code (without AsNoTracking()),;/ but create a brand but IMSContext instance.
 
What do you mean by creating a brand new IMSContext instance? Can you please elaborate? By the way, I gave up using raw sql because I had to change too many things on the page.
 
Your repository classes take IMSContext in their constructors. If you were using standard practices, you would have let EF use .NET Core's dependency injection to have it pass in a per request instance of a class that implements IMSContext.

The reason why a per request instance is shared among all the code running within a request is so that there is a consistent "database session" that has a consistent "view" of the database. Often in ORMs, these "sessions" maintain the in memory tracking of objects that it has handed out so that the next time you ask for the same data, you will get back the object that represents that data. Any queries will try to give you back an object that it has already given out, before trying to read from the database. Presumably, when you used the AsNoTracking() no attempt is made to search for an existing object. Instead a fresh database read is done.

My suggestion to use a different instance is so that you get a new independent "database session" and "view" of the data that has been persisted into the database.

To be able to inject a different IMSContext, you'll need to understand how your IOC container/dependency injection framework works so that you can force to to use a fresh instance, instead of using the per request instance. I don't know enough about how the .NET Core's IOC framework to be able to even begin to guide you on going about this.

But there is hope! If you truly wrote your repositories to be unit testable, you can just not use the IOC framework and do all the creation of objects to pass into the repository constructors yourself. Do all that testing within a unit test instead of an interactive web app session.
 
Back
Top Bottom