为什么 Entity Framework 会在一段时间后忘记我的数据库模型中的内容?
Why does Entity Framework forget what's in the model for my database after a while?
Disclaimer/warning:我是 .net 的新手,一年前才开始使用它。
我在 Azure 上有一个使用 Entity Framework 5.0、.Net 4.6 和 MVC 4.0、运行 的 MVC webapp。此应用程序访问两个数据库,它们都带有 EDMX 文件,并且都位于同一台 Azure 服务器上。数据库的连接字符串作为开发连接在 web.config
中,但 Azure 应用程序具有覆盖它们的环境连接字符串。
两个 EDMX 文件都是由 "Updating the Model from Database" 生成的(即,数据库先存在,然后生成 edmx 以匹配它)。一个 EDMX 文件位于同一解决方案的第二个项目中,该项目是对我的应用程序的引用。
这个 EDMX 文件/模型工作正常。第二个 EDMX 文件位于我的应用程序的模型部分,仅代表三个 table 和少量存储过程。我已经一年没碰过这个 EDMX 了,在过去的一年里,它偶尔会出现无法访问数据库的问题,但可以通过重新启动应用程序来解决。
最近,我一直在对 webapp 进行更改(但仍然没有更改 EDMX 或 views/controllers 访问该数据库的模型),现在该应用程序经常无法访问数据库.当我重新启动或更改连接字符串时,它会再次开始工作,但一个小时左右后就会忘记数据库。
感觉 Web 应用程序正在以某种方式失去与数据库的连接。连接字符串良好,模型准确等(因为它在应用程序重新启动时有效)。
为什么一个数据库会出现这种情况,而另一个数据库不会出现这种情况?我能做些什么来修复它?我不能一直每小时重新启动应用程序。
这是我目前收到的两条错误消息:
当我尝试在名为 [Database] 的 table 中提取记录时(EF 在模型中调用了 Database)
Message: [InvalidOperationException: The entity type Databas is not part of the model for the current context.]
System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType):59
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType):13
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize():0
System.Data.Entity.Internal.Linq.InternalSet`1.Include(String path):0
System.Data.Entity.Infrastructure.DbQuery`1.Include(String path):21
CVSupportPortal.Models.ViewModels.CloudAdminViewModel..ctor(Firm f):482
CVSupportPortal.Areas.CVS.Controllers.FirmsController.Cloud(Int32 firmid):206
(unknown).lambda_method(Closure , ControllerBase , Object[] ):-1
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters):129
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41():0
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass37+<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33():30
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25+<>c__DisplayClass2a.<BeginInvokeAction>b__20():23
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult):0
当我调用存储过程时:
Message: [InvalidOperationException: The type parameter 'CVSupportPortal.Models.EF.Database_Status_List_Result' in ExecuteFunction is incompatible with the type 'CloudDatabasesModel.Database_Status_List_Result' returned by the function. ]
System.Data.Common.Utils.MetadataHelper.CheckFunctionImportReturnType[TElement](EdmType expectedEdmType, MetadataWorkspace workspace):46
System.Data.Common.Utils.MetadataHelper.GetAndCheckFunctionImportReturnType[TElement](EdmFunction functionImport, Int32 resultSetIndex, MetadataWorkspace workspace):25
System.Data.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, MergeOption mergeOption, ObjectParameter[] parameters):0
CVSupportPortal.Models.EF.CloudDatabasesEntities.Database_Status_List():0
(unknown).lambda_method(Closure , ControllerBase , Object[] ):-1
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters):129
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41():0
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass37+<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33():30
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25+<>c__DisplayClass2a.<BeginInvokeAction>b__20():23
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult):0
我仍然不知道问题的原因是什么,但我猜测 Entity Framework 以某种方式失去了与数据库的连接,因为其他位置可以访问数据库,只是不能通过Entity Framework 在 运行 一段时间后。我发现 DbContext class 有一个构造函数,允许您在实例化时指定连接字符串。我的解决方案是尝试使用它,希望它能启动与数据库的新连接,而不是尝试使用旧连接。
成功了。自从我开始使用它以来,我没有受到任何干扰。这是我更改的内容(我的数据库称为 CloudDatabases)。
CloudDatabases.Context.cs
// Already present
public CloudDatabasesEntities()
: base("name=CloudDatabasesEntities")
{
}
// Added this constructor
public CloudDatabasesEntities(string connStr)
: base(connStr)
{
}
在 classes 中,我需要实例化与数据库的连接:
// Old, normal way
var cdb = new CloudDatabaseEntitites();
// New, non-breaking way
var connStr = ConfigurationManager.ConnectionStrings["CloudDatabasesEntities"].ConnectionString.ToString();
var cdb = new CloudDatabaseEntitites(connStr);
我的 Web.config(或 Azure 环境变量)的连接字符串定义如下:
// Web.config
<add name="CloudDatabasesEntities" connectionString="metadata=res://*/CloudDatabases.csdl|res://*/CloudDatabases.ssdl|res://*/CloudDatabases.msl;provider=System.Data.SqlClient;provider connection string="data source=████████████████████████████████;initial catalog=CloudDatabases;persist security info=True;user id=████████████;password=██████████████████████;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
Disclaimer/warning:我是 .net 的新手,一年前才开始使用它。
我在 Azure 上有一个使用 Entity Framework 5.0、.Net 4.6 和 MVC 4.0、运行 的 MVC webapp。此应用程序访问两个数据库,它们都带有 EDMX 文件,并且都位于同一台 Azure 服务器上。数据库的连接字符串作为开发连接在 web.config
中,但 Azure 应用程序具有覆盖它们的环境连接字符串。
两个 EDMX 文件都是由 "Updating the Model from Database" 生成的(即,数据库先存在,然后生成 edmx 以匹配它)。一个 EDMX 文件位于同一解决方案的第二个项目中,该项目是对我的应用程序的引用。 这个 EDMX 文件/模型工作正常。第二个 EDMX 文件位于我的应用程序的模型部分,仅代表三个 table 和少量存储过程。我已经一年没碰过这个 EDMX 了,在过去的一年里,它偶尔会出现无法访问数据库的问题,但可以通过重新启动应用程序来解决。
最近,我一直在对 webapp 进行更改(但仍然没有更改 EDMX 或 views/controllers 访问该数据库的模型),现在该应用程序经常无法访问数据库.当我重新启动或更改连接字符串时,它会再次开始工作,但一个小时左右后就会忘记数据库。
感觉 Web 应用程序正在以某种方式失去与数据库的连接。连接字符串良好,模型准确等(因为它在应用程序重新启动时有效)。
为什么一个数据库会出现这种情况,而另一个数据库不会出现这种情况?我能做些什么来修复它?我不能一直每小时重新启动应用程序。
这是我目前收到的两条错误消息:
当我尝试在名为 [Database] 的 table 中提取记录时(EF 在模型中调用了 Database)
Message: [InvalidOperationException: The entity type Databas is not part of the model for the current context.]
System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType):59
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType):13
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize():0
System.Data.Entity.Internal.Linq.InternalSet`1.Include(String path):0
System.Data.Entity.Infrastructure.DbQuery`1.Include(String path):21
CVSupportPortal.Models.ViewModels.CloudAdminViewModel..ctor(Firm f):482
CVSupportPortal.Areas.CVS.Controllers.FirmsController.Cloud(Int32 firmid):206
(unknown).lambda_method(Closure , ControllerBase , Object[] ):-1
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters):129
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41():0
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass37+<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33():30
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25+<>c__DisplayClass2a.<BeginInvokeAction>b__20():23
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult):0
当我调用存储过程时:
Message: [InvalidOperationException: The type parameter 'CVSupportPortal.Models.EF.Database_Status_List_Result' in ExecuteFunction is incompatible with the type 'CloudDatabasesModel.Database_Status_List_Result' returned by the function. ]
System.Data.Common.Utils.MetadataHelper.CheckFunctionImportReturnType[TElement](EdmType expectedEdmType, MetadataWorkspace workspace):46
System.Data.Common.Utils.MetadataHelper.GetAndCheckFunctionImportReturnType[TElement](EdmFunction functionImport, Int32 resultSetIndex, MetadataWorkspace workspace):25
System.Data.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, MergeOption mergeOption, ObjectParameter[] parameters):0
CVSupportPortal.Models.EF.CloudDatabasesEntities.Database_Status_List():0
(unknown).lambda_method(Closure , ControllerBase , Object[] ):-1
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters):129
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41():0
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass37+<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33():30
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49():134
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult):0
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25+<>c__DisplayClass2a.<BeginInvokeAction>b__20():23
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult):0
我仍然不知道问题的原因是什么,但我猜测 Entity Framework 以某种方式失去了与数据库的连接,因为其他位置可以访问数据库,只是不能通过Entity Framework 在 运行 一段时间后。我发现 DbContext class 有一个构造函数,允许您在实例化时指定连接字符串。我的解决方案是尝试使用它,希望它能启动与数据库的新连接,而不是尝试使用旧连接。
成功了。自从我开始使用它以来,我没有受到任何干扰。这是我更改的内容(我的数据库称为 CloudDatabases)。
CloudDatabases.Context.cs
// Already present
public CloudDatabasesEntities()
: base("name=CloudDatabasesEntities")
{
}
// Added this constructor
public CloudDatabasesEntities(string connStr)
: base(connStr)
{
}
在 classes 中,我需要实例化与数据库的连接:
// Old, normal way
var cdb = new CloudDatabaseEntitites();
// New, non-breaking way
var connStr = ConfigurationManager.ConnectionStrings["CloudDatabasesEntities"].ConnectionString.ToString();
var cdb = new CloudDatabaseEntitites(connStr);
我的 Web.config(或 Azure 环境变量)的连接字符串定义如下:
// Web.config
<add name="CloudDatabasesEntities" connectionString="metadata=res://*/CloudDatabases.csdl|res://*/CloudDatabases.ssdl|res://*/CloudDatabases.msl;provider=System.Data.SqlClient;provider connection string="data source=████████████████████████████████;initial catalog=CloudDatabases;persist security info=True;user id=████████████;password=██████████████████████;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />