实体框架 MappingException:类型“XXX”被映射了多次

27

我在Web应用程序中使用Entity Framework。 对象上下文是每个请求(使用HttpContext)创建的,代码如下:

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString();
if (!HttpContext.Current.Items.Contains(ocKey))
{
    HttpContext.Current.Items.Add(ocKey, new ElevationEntityModel(EFConnectionString));
}
_eem = HttpContext.Current.Items[ocKey] as ElevationEntityModel;

并非每次都出现,但有时我会遇到这个异常:

System.Data.MappingException未被用户代码处理 Message=类型“XXX”已映射多次。 Source=System.Data.Entity

我很困惑,也不知道是什么引起了这个问题。

有人能帮帮我吗?

2个回答

19

看起来是一个同步问题。一个简单的解决方案是在你的类中使用共享锁对象:

private static object _lock = new object();

那么您的代码将变为:

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString(); 

lock (_lock) {
    if (!HttpContext.Current.Items.Contains(ocKey)) 
    { 
          HttpContext.Current.Items.Add(ocKey, new ElevationEntityModel(EFConnectionString)); 
    } 
    _eem = HttpContext.Current.Items[ocKey] as ElevationEntityModel; 

}

锁定块基本上意味着一旦一个线程进入“锁”块,直到第一个线程完成,其他线程都无法访问该块。这将防止“Contains”方法和“Add”方法之间的争用。

注意:如果您的应用程序中的任何其他地方都在访问HttpContext.Current中的Items集合,则还需要在那里进行同步。最好创建一个自定义集合,将其添加到Items集合中,并同步访问它。


我正在修复一个旧的、写得很差的Silverlight项目。这是RIA服务中偶尔出现的问题之一。目前,我正在尝试使用锁来防止它。 - Vad

11

当您进行多线程操作并且未先对线程进行同步,即访问相同的ObjectContext时,就会导致此问题发生...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接