MB_18
MB_18

Reputation: 2321

Entity Framework Context Lifetime in ASP.NET Core Blazor Server

My problem is when I perform CRUD operations on my context, the changes are not made in my components.

DbContext is registered as follows:

    services.AddDbContextFactory<DBContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("my_ConnectionStrings")),
        lifetime: ServiceLifetime.Transient);

In the above code, I configure ServiceLifetime as Transient. So a new instance of the service must be created every time it is requested.

Here is my code:

[Inject] IDbContextFactory<DBContext> DbFactory;

private string updateMessage(int messageID)
{
   DBContext _context = DbFactory.CreateDbContext();
   
   var result = _context.Messages.FirstOrDefault(s => s.MessageID == messageID);
   if (result != null)
   {
        result.LastUpdate= DateTime.Now.ToString("HH:mm:ss");
        _context.SaveChanges();
   }
 
   
   var assert = _context.Messages.FirstOrDefault(s => s.MessageID == messageID);
   return "Last update is: " + assert.LastUpdate;
}

In the above code, I inject the factory into my component and create new instances. But the context changes are not considered in my component. I want to observe the context changes in my components.

In the above code, I modify the context, but nothing has changed and the method returns the previous value of LastUpdate.

Upvotes: 2

Views: 1065

Answers (1)

MB_18
MB_18

Reputation: 2321

In Blazor Server, scoped service registrations can be problematic because the instance is shared across components within the user's circuit. DbContext isn't thread safe and isn't designed for concurrent use. The existing lifetimes are inappropriate. For more info see ASP.NET Core Blazor Server with Entity Framework Core.

You should create a new DbContext instance. One way to create a new DbContext instance is using using statement.

Try this code:

[Inject] IDbContextFactory<DBContext> DbFactory;

private string updateMessage(int messageID)
{
   using (DBContext _context = DbFactory.CreateDbContext())
   {
       var result = _context.Messages.FirstOrDefault(s => s.MessageID == messageID);
       if (result != null)
       {
            result.LastUpdate= DateTime.Now.ToString("HH:mm:ss");
            _context.SaveChanges();
       }
   }
    
   var assert = new Messages();
   using (DBContext _context = DbFactory.CreateDbContext())
   {
      assert = _context.Messages.FirstOrDefault(s => s.MessageID == messageID);
   }
   return "Last update is: " + assert.LastUpdate;
}

Upvotes: 4

Related Questions