EF Core - System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is closed

无人久伴 提交于 2019-11-30 17:18:40

问题


I'm running an ASP.NET Core 1.0 web app with Entity Framework Core. When the app has been running for a while (24 - 48 hours), the app starts crashing on every request to any endpoint or static resource throwing the error System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is closed. I can only recover from this by restarting the App Pool.

I am configuring Entity Framework like this:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));   
}

I am loading data in the owin pipeline with an extension method like this like this:

Startup.cs

app.LoadTenantData();

AppBuilderExtensions.cs:

public static void LoadTenantData(this IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            var dbContext = app.ApplicationServices.GetService<ApplicationDbContext>();        
            var club = dbContext.Clubs.Single(c => c.Id == GetClubIdFromUrl(context));
            context.Items[PipelineConstants.ClubKey] = club;
            await next();
        });
    }

Since the error only occurs when the app has been running for a long time, it is hard to reproduce, but I'm assuming it has something to do with EF opening and closing connections incorrectly.

How can I go about to debug this? Am I using EF incorrectly?


回答1:


I got same issue.

I think it is likely that the same dbcontext instance is being used concurrently by multiple threads.

You may need this: services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")),ServiceLifetime.Transient); There is a issue about that. https://github.com/aspnet/EntityFramework/issues/6491




回答2:


My app is very basic (write it fast, run it once, then forget), so a solution to the problem above was to simply introduce lock around the section that was doing multi-table inserts.

    public void CallGooglePlacesAPIAndSetCallback(string websiteName)
    {
        using (var db = new WebAnalyzerEntities())
        {
            IList<IRecord> addressesToBeSearched = db.Rent.Where<IRecord>(o => o.Url.Contains(websiteName) && o.SpatialAnalysis.Count == 0).ToList().Union(db.Sale.Where<IRecord>(oo => oo.Url.Contains(websiteName) && oo.SpatialAnalysis.Count == 0)).ToList();
            foreach (var locationTobeSearched in addressesToBeSearched)
            {
                try
                {
           //this is where I introduced the lock
                    lock (_lock)
                    {
                        dynamic res = null;
                        using (var client = new HttpClient())
                        {
                            while (res == null || HasProperty(res, "next_page_token"))
                            {
                                var url = $"https://maps.googleapis.com/maps/api/geocode/json?address={locationTobeSearched.Address}&key={googlePlacesApiKey}&bounds=51.222,-11.0133788|55.636,-5.6582363";
                                if (res != null && HasProperty(res, "next_page_token"))
                                    url += "&pagetoken=" + res["next_page_token"];
                                var response = client.GetStringAsync(url).Result;
                                JavaScriptSerializer json = new JavaScriptSerializer();
                                res = json.Deserialize<dynamic>(response);
                                if (res["status"] == "OK")
                                {
                                    Tuple<decimal?, decimal?, string> coordinatesAndPostCode = ReadResponse(res["results"][0]);
                                    if (coordinatesAndPostCode != null && coordinatesAndPostCode.Item1.HasValue && coordinatesAndPostCode.Item2.HasValue)
                                    {
           //this is the line where exception was thrown
                                        locationTobeSearched.SpatialAnalysis.Add(new SpatialAnalysis() { Point = CreatePoint(coordinatesAndPostCode.Item1.Value, coordinatesAndPostCode.Item2.Value) });
                                        locationTobeSearched.PostCode = coordinatesAndPostCode.Item3;
                                    }
                                }
                                else if (res["status"] == "OVER_QUERY_LIMIT")
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {

                }

                db.SaveChanges();
            }
        }
    }


来源:https://stackoverflow.com/questions/38697965/ef-core-system-invalidoperationexception-executereader-requires-an-open-and-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!