我已经完成了一个新应用程序的编写,该应用程序现已部署到实时环境中,但是我的全局错误处理程序在一整天内多次拾取这些异常。这些错误分批进行,是粗体中的四个之一。
MVC 4,IIS 6,Windows Server 2003,.Net .4.0,EF 5(最新版NuGet)
“ARandomModelInMyContext”类型已多次映射。
指数超出范围。必须是非负数且小于集合的大小。
Parameter name: index
System.ThrowHelper.ThrowArgumentOutOfRangeException() at System.Data.Metadata.Edm.MetadataCollection`1.get_Item(Int32 index) at System.Data.Mapping.DefaultObjectMappingItemCollection.ContainsMap(GlobalItem cspaceItem, ObjectTypeMapping& map) at
创建模型时无法使用上下文。
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
基础提供程序在Open上失败。连接没有关闭。连接的当前状态是连接。
应用程序的结构是一个非常标准的MVC4应用程序,它带有服务层和存储库层。
public class MyRepository : BaseRepository<MyModel>, IMyRepository
使用构造函数:
public MyRepository() : base(new MyEntities())
{
}
Base Repository看起来像这样:
public class BaseRepository<TEntity> where TEntity : class
{
internal CRMEntities Context;
internal DbSet<TEntity> dbSet;
public BaseRepository(MyEntities context)
{
this.Context = context;
dbSet = context.Set<TEntity>();
}
}
不应该有任何并发问题,因为我没有直接使用任何线程或异步。
有什么想法吗?我的存储库结构可以改进吗?我已经让所有的构造函数都可以了,但是我还没有使用IoC容器。
将Context中的Context构造包装起来是否值得?例如:
public class BaseRepository<TEntity> where TEntity : class
{
internal MyEntities Context;
internal DbSet<TEntity> dbSet;
private static object _lock = new object();
public BaseRepository(MyEntities context)
{
lock (_lock)
{
this.Context = context;
dbSet = context.Set<TEntity>();
}
}
}
答案 0 :(得分:1)
它看起来非常像您的存储库(因此您的上下文)被多个请求使用。如果这是真的,那么这是多线程使用相同的上下文实例,这是不受支持的 - 上下文不是线程安全的。仅锁定初始化是不够的。 (另外,调用Set不会初始化上下文。)您需要保护对上下文的所有访问,或者更恰当地使用具有短期上下文实例的每个请求模型的上下文。