Closed qin-nz closed 2 years ago
@qin-nz Can you post the code you have for calling AddDbContext and overriding OnConfiguring, if you are using these things? Also, can you show or describe how you are creating DbContext instances?
Code for calling AddDbContext
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<Email2RssContext>(
options => options.UseSqlServer(connection,
b => b.MigrationsAssembly("Email2Rss.Core")));
All of DbContext instances are created by Dependency Injection. The following one is created in a Middleware.
private readonly Email2RssContext _context;
public V1Authorize(RequestDelegate next, ILogger<V1Authorize> logger, Email2RssContext context, IHostingEnvironment environment)
{
_next = next;
_logger = logger;
_context = context;
_environment = environment;
}
public async Task Invoke(HttpContext httpContext)
{
string key = await _context.Users // NOTICE HERE!
.AsNoTracking()
.Where(u => u.UserName == userName)
.Select(u => u.RssAccessToken)
.FirstOrDefaultAsync();
...
And I will got NullReferenceException at // NOTICE HERE!
for only some request.
Except that exception, I could also get following two exceptions.
The connection does not support MultipleActiveResultSets.
The connection was not closed. The connection's current state is connecting.
@qin-nz When you add DbContext in that way it is registered as a scoped service. Have scopes been created for all the places you get the context injected?
Also, DbContext is not thread safe. Have you ensured that multiple threads are not using the same context instance?
hi @ajcvickers , the only way I use DbContext is create it using controller(or middleware)'s constructor.
I have one context instant for each controller instant.
And I am not always using await/async
.
Is it okay?
@qin-nz Does the middleware have a scope per request?
Anytime you call an async method in EF the call must be awaited before making any other call into EF.
No, the middleware should not have a scope per request. And the only async method is awaited.
The SqlException only occur when the request rate is a little high. (about 10 requests per second)
The NullReferenceException at string key = await _context.Users...
still confused me.
May be some exceptions is caused by unstable SQL Azure service.
Because I can get following exceptions in Application Insights and it's last for more than an hour. (My web app is deploy in Azure East Asia data center)
Name resolution failed for d2d98bfbbd85.tr7.eastasia1-a.worker.database.windows.net. No such host is known
Name resolution failed for b0d1e31e14b4.tr7.eastasia1-a.worker.database.windows.net. This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server
@qin-nz I think it is likely that the same context instance is being used concurrently by multiple threads, especially given your statement that the middleware is not scoped by request, Can you do some investigation to ensure that the same context instance is not being used concurrently?
@ajcvickers I think you may be right.
Which ServiceLifeTime
should I use for DbContext? Currently I don't explicit set it.
I only need context in one middleware and in controllers.
I am doing the investigation and I will report it later.
@qin-nz The default lifetime is Scoped. This is because normally there will be one scope per request, so you will get a new context instance per request. It is also valid to use Transient, in which case every place you use a context will get a new instance.
The thing to be careful about it not depending on DbContext in a service that is a Singleton if that singleton service is going to be used by multiple requests/threads. If you have a singleton service, then it may be better to depend on DbContextOptions<Email2RssContext >
and then explicitly new up a context when needed passing in the context options that were injected:
using (var context = new Email2RssContext(contextOptions)
{
}
Closing for now as last activity was two weeks ago. Feel free to re-open if you have any additional information.
Steps to reproduce
Run an ASP.NET Core 1.0 web app with Entity Framework Core on Azure Web App. And the Web Project and the EF Project(or lib project) are separately.
The issue
I'm running an ASP.NET Core 1.0 web app with Entity Framework Core. And then a SqlException is occur. (It is my fault to case this exception.)
My issuse is: After above exception, the app starts crashing on every request which need a context. And throwing the error
I can only recover from this by restarting the Azure App.
Further technical details
EF Core version: 1.0.0 Operating system: Azure Web App Visual Studio version: VS2015
Other details about my project setup: