我想在会话中共享一个dbcontext。我知道使用共享的缓存Dbcontexts存在许多问题。
所以我创建了一个全局dbcontext并将其保存在一个静态类变量中。
我可以创建select,创建新实体,通过dbcontext在调用后的代码中进行插入和更新,而不会出现问题
出于并发原因,我想在我的webforms中的entitydatasource控件中使用相同的dbcontext。我通过使用OnContextCreating和ONContextdisposing事件来完成此操作。这适用于读取数据,但当我尝试通过entitydatasource(从数据视图,gridview等)进行更新时,我得到以下异常
AcceptChanges cannot continue because the object's key values conflict with
another object in the ObjectStateManager. Make sure that the key values are unique
before calling AcceptChanges.
我使用单个表和一个带有单个enitydatasource的webform页面将产生错误的系统简化为ef5.0数据模型。我已经复制了以下代码
public partial class _Default : Page
{
static QuantumDataEntities dbcontext = null;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void OnContextCreating(object sender, EntityDataSourceContextCreatingEventArgs e)
{
if (dbcontext == null)
dbcontext = new QuantumDataEntities();
e.Context = (dbcontext as IObjectContextAdapter).ObjectContext;
}
protected void OnContextDisposing(object sender, EntityDataSourceContextDisposingEventArgs e)
{
e.Cancel = true;
}
}
正如您所看到的,它非常简单。每当Entitydatasource需要一个objectcontext来读取,更新等时,它就会调用OnContextCreating。我在第一个OnContextCreating调用上创建dbcontext,在静态类变量中缓存并重用以后的OnContextCreating调用。 OnContextCreating事件被调用几次,首先是页面加载,接下来是按下编辑按钮时的回发,最后(我认为)是实际的dbsave。
如果我获得缓存并为每个调用创建一个新的dbcontext,它可以正常工作。即 取代
if (dbcontext == null)
dbcontext = new QuantumDataEntities();
e.Context = (dbcontext as IObjectContextAdapter).ObjectContext;
与
dbcontext = new QuantumDataEntities();
e.Context = (dbcontext as IObjectContextAdapter).ObjectContext;
此错误还有一些其他奇怪之处。如果我设置一个OnUpdating事件,应该在entitydataosource执行任何更新之前调用它,它永远不会被调用。 我已经包含了异常的堆栈跟踪和本文的结尾。
我想用EF 6.0 Alpha 3测试这个,但是设计师已经移动了对象上下文 进入另一个组件,使其与entitydatasouce不兼容
这是进一步发展我们网站的主要障碍。我们现在唯一的选择就是转移到非共享的dbcontext,这将导致极端的性能问题(即在页面加载时加载相同的20K数据集多次 - 是的,我们可以重新构建,我们需要数周/几个月,我们现在没有)
问题?
异常堆栈跟踪
[InvalidOperationException: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.]
System.Data.Objects.ObjectStateManager.FixupKey(EntityEntry entry) +2518309
System.Data.Objects.EntityEntry.AcceptChanges() +159
System.Data.Objects.ObjectContext.AcceptAllChanges() +356
System.Web.UI.WebControls.EntityDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) +376
System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values, IDictionary oldValues, DataSourceViewOperationCallback callback) +87
System.Web.UI.WebControls.DetailsView.HandleUpdate(String commandArg, Boolean causesValidation) +1091
System.Web.UI.WebControls.DetailsView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +425
System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +89
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent(Object source, EventArgs e) +80
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +121
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +156
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +9642898
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724