gpt4 book ai didi

c# - 如何防止 EF "The context cannot be used while the model is being created"错误?

转载 作者:IT王子 更新时间:2023-10-29 04:11:28 25 4
gpt4 key购买 nike

查看我的 Elmah 错误日志,我看到一些来自 Entity Framework 的 InvalidOperationException 处理:

The context cannot be used while the model is being created.

这是来自 Nuget 的最新 EF CodeFirst 库。我能够在网上找到的唯一信息是它是由将数据上下文作为单例引起的,这肯定不是我的情况。在我的 Windsor 安装程序中,我的 EF 工作单元结构正在注册:

container.Register(Component.For<IUnitOfWork>()
.ImplementedBy<EFUnitOfWork>()
.LifeStyle
.PerWebRequest);

我能够通过在 VS 中按 F5 启动调试 session 来重现错误,并且在 IIS 启动时将第二个网页加载到调试 session 。

我怀疑这是因为用户正尝试访问系统,而 Asp.net 由于缺乏事件而已卸载,这是有道理的,因为我的产品目前正在进行非常非常小的 beta 测试。然而,由于真实的人正在使用带有实时数据的网站,我需要尽可能少的错误发生。

有没有人知道如何防止这种情况发生?


编辑:我更新了我的温莎 Controller ,现在包含以下代码:

        container.Register(Component.For<IUnitOfWork>().ImplementedBy<EFUnitOfWork>().LifeStyle.PerWebRequest);
using (var context = new MyJobLeadsDbContext())
{
context.Set<UnitTestEntity>().Any();
}

但是,当我尝试在 IIS 加载应用程序时执行第二次 Web 请求时,之前的错误仍然出现


编辑 2: 根据要求,这里是堆栈

   at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)
at MyApp.DomainModel.Queries.Users.UserByEmailQuery.Execute() in C:\Users\KallDrexx\Documents\Projects\MyApp\MyApp.DomainModel\Queries\Users\UserByEmailQuery.cs:line 44
at MyApp.Infrastructure.MyAppMembershipProvider.GetUser(String email, Boolean userIsOnline) in C:\Users\KallDrexx\Documents\Projects\MyApp\MyApp\Infrastructure\MyAppMembershipProvider.cs:line 102
at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
at System.Web.Security.Membership.GetUser()
at MyApp.MyAppBaseController.Initialize(RequestContext requestContext) in C:\Users\KallDrexx\Documents\Projects\MyApp\MyApp\MyAppBaseController.cs:line 23
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

最佳答案

我终于弄清楚了这件事的真正原因,至少对我来说是这样。

问题是我在我的自定义 Asp.Net 成员资格提供程序中从 Windsor 检索 DbContext。这导致了一个问题,因为成员资格提供者具有整个应用程序的生命周期,而对数据库上下文的所有其他检索调用都是特定 Web 请求的新数据库上下文。这意味着两个数据库上下文同时“启动”,因此引发了此错误。

这也导致了很多难以调试的实体缓存问题,因此在其成员提供程序中使用 EF 的任何人都需要真正小心他们的上下文生命周期。


编辑:为了响应 DotNetWise,我通过将 Windsor 连接工厂存储在我的构造函数中,然后始终从那时的工厂。

例如:

public class CustomMembershipProvider : MembershipProvider
{
private IServiceFactory _serviceFactory;

public CustomMembershipProvider() : this(null) { }

public CustomMembershipProvider(IServiceFactory factory)
{
// IF no factory was provided, we need to get one from the bootstrapper
if (factory == null)
_serviceFactory = new WindsorServiceFactory(Bootstrapper.WindsorContainer);
else
_serviceFactory = factory;
}

public override string ResetPassword(string email, string answer)
{
var unitOfWork = GetUnitOfWork();
return new ResetUserPasswordCommand(unitOfWork).WithUserEmail(email).Execute();
}

private IUnitOfWork GetUnitOfWork()
{
return _serviceFactory.GetService<IUnitOfWork>();
}
}

想法是成员(member)提供者执行的任何操作都从 Windsor 获取 UnitOfWork 类,并使用它来执行操作(在这种情况下,我的 UnitOfWork 类是一个存储库持有者来包装我的 EF 数据上下文)

关于c# - 如何防止 EF "The context cannot be used while the model is being created"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6099781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com