当前位置: 首页 > 编程语言 > C#

在不创建数据库的情况下,将Mini-Profilier与EF 4.3和MVC 4配合使用分享

时间:2023-04-10 23:24:31 C#

C#学习教程:在不创建数据库的情况下将Mini-Profilier与EF4.3和MVC4一起使用现有数据库。我想将Mini-Profiler与EF一起使用并调用MvcMiniProfiler.MiniProfilerEF.Initialize();但是,由于我们实际上并未创建任何表,因此dbo.__MigrationHistory和dbo.EdmMetadata表不存在。解析器最终会崩溃,因为它们不存在。有没有办法让探查器忽略这些EFCodeFirst特定表?谢谢!编辑:这些是我得到的例外情况:(它们是分开的)无效的对象名称'dbo.__MigrationHistory'。在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,BooleanbreakConnection)在System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常,BooleanbreakConnection).SqlClient.TdsParser.Run(RunBehaviorrunBehavior,SqlCommandcmdHandler,SqlDataReaderdataStream,BulkCopySimpleResultSetbulkCopyHandler,TdsParserStateObjectstateObj)在System.Data。SqlClient.SqlDataReader.ConsumeMetaData()在System.Data.SqlClient.SqlDataReader.get_MetaData()CommandBehaviorcmdBehavior、RunBehaviorrunBehavior、BooleanreturnStream、Booleanasync)在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehaviorcmdBehavior,RunBehaviorrunBehavior,布尔returnStream,字符串方法,DbAsyncResult结果)在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehaviorcmdBehavior,RunBehaviorrunBehavior,布尔returnStream,字符串方法)在System.Data.SqlSystem.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior行为)处的.SqlCommand.ExecuteReader(CommandBehavior行为,字符串方法))在mvc-mini-profilerMvcMiniProfilerDataProfiledDbCommand.cs中:System.Data.Common.DbCommand.ExecuteReader(CommandBehavior行为)中的第155行'.在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,BooleanbreakConnection)在System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常,BooleanbreakConnection)在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()在System.Data.SqlClient.TdsParser.Run(RunBehaviorrunBehavior,SqlCommandcmdHandler,SqlDataReaderdataStream,BulkCopySimpleResultSetbulkCopyHandler,TdsParserStateObjectstateObj)在System.Data.SqlClient.SqlDataReader.ConsumeMetaData()在System.Data.SqlClient.SqlDataReader.get_MetaData()在System.Data.SqlClient.SqlDataReader.get_MetaData()SqlDataReaderds,RunBehaviorrunBehavior,字符串resetOptionsString)在System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehaviorcmdBehavior,RunBehaviorrunBehavior,布尔returnStream,布尔异步)在System.Data.SqlClient.SqlCommand.RunExecuteBehaviorrunExecuteBehavior,cmandBehaviorreturnStream、字符串方法、DbAsyncResult结果)在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehaviorcmdBehavior,RunBehaviorrunBehavior,BooleanreturnStream,字符串方法)在System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior行为,字符串方法.SqlCommand).ExecuteDbDataReader(CommandBehavior行为)在System.Data.Common.DbCommand.ExecuteReader(CommandBehavior行为)在MvcMiniProfiler.Data.ProfiledDbCommand.ExecuteDbDataReader(CommandBehavior行为)在mvc-mini-profilerMvcMiniProfilerDataProfiledDbCommand.cs.line15DbCommandBehavior行为中在System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommandentityCommand,CommandBehaviorbehavior)我启动了一个新的MVC4项目并安装/更新了以下NuGet包:数据库初始化策略在代码优先中关闭公共类EmployeeContext:DbContext{staticEmployeeContext(){Database.SetInitializer(null);//必须在miniprofiler运行之前关闭}publicIDbSetEmployees{get;放;迷你分析器工作正常。我手动创建了一个表数据库。在静态构造函数中关闭数据库初始化程序非常重要。如果您在别处执行此操作,迷你分析器代码可能会在您的代码之前运行,因此可能根本不会查询__MigrationHistory表。当我错过miniprofiler的设置时会发生此异常。可能的情况:布局标头中缺少包含@MvcMiniProfiler.MiniProfiler.RenderIncludes()App_Start文件夹中缺少“MiniProfiler.cs”。Application_Start()函数AreaRegistration.RegisterAllAreas()中缺少调用;RegisterGlobalFilters(GlobalFilters.Filters);RegisterRoutes(RouteTable.Routes);BundleTable.Bundles.RegisterTemplateBundles();MiniProfilerEF.Initialize();EF4.3用于测试。问题:如果在执行EntityFramework数据库初始化策略之前初始化MiniProfiler,则初始化失败并出现有关缺少迁移表的错误。如果首先执行实体框架数据库初始化策略,则由于试图将MiniProfilerDbConnection转换为SqlConnection变量(在内部一般情况下),因此访问实体会失败并出现类型转换异常。原因:当MiniProfiler初始化时,它使用反射从System.Data.Common.DbProviderFactories中的私有静态字段中检索数据库提供程序的集合。然后它使用MiniProfilershim提供程序重写此列表以替换本机提供程序。这允许MiniProfiler静默拦截对数据库的任何调用。当EntityFramework初始化时,它开始编译数据模型并在一些私有静态字段中创建存储在System.Data.Entity.Internal.LazyInternalContext中的缓存初始化数据库。创建这些后,对DbContext的查询将使用内部键控缓存模型和数据库来使用初始化时存在的提供程序。当EntityFramework数据库初始化策略运行时,它需要访问裸原生Sql提供程序,而不是MiniProfilershim,以便正确生成用于创建表的SQL。但是,一旦对本机提供程序进行了这些调用,本机提供程序就会缓存到LazyInternalContext中,并且我们无法在没有运行时失败的情况下注入MiniProfilershim。我的解决方案访问System.Data.Entity.Internal.LazyInternalContext中的私有集合并清除缓存的编译模型并初始化数据库。如果我在EF数据库初始化策略的操作和MiniProfiler的初始化之间执行此清理,我可以插入MiniProfilershim而不会导致以后的运行时故障。代码:这段代码对我有用:Typetype=typeof(DbContext).Assembly.GetType("System.Data.Entity.Internal.LazyInternalContext");objectconcurrentDictionary=(type.GetField("InitializedDatabases",BindingFlags.NonPublic|BindingFlags.Static)).GetValue(null);varinitializedDatabaseCache=(IDictionary)concurrentDictionary;if(initializedDatabaseCache!=null)initializedDatabaseCache.Clear();objectconcurrentDictionary2=(type.GetField("CachedModels",BindingPublags|.NonStatic)).GetValue(null);varmodelsCache=(IDictionary)concurrentDictionary2;如果(modelsCache!=null)modelsCache.Clear();警告:看起来LazyInternalContext中内部字段的名称在EF版本之间发生了变化,因此您可能需要修改此代码以使用项目中包含的EF的确切版本。我发现禁用EntityFramework数据库初始化(如果不需要)的额外“hack”存在问题。在初始化dbcontext和MiniProfiler之前,DB的DefaultInitializer应该设置为nullTypetype=typeof(DbContext).Assembly.GetType("System.Data.Entity.Internal.LazyInternalContext");varfield=type.GetField("DefaultCodeFirstInitializer",BindingFlags.NonPublic|BindingFlags.Static);如果(字段!=null)field.SetValue(null,null);else{varfield2=type.GetField("_defaultCodeFirstInitializer",BindingFlags.NonPublic|BindingFlags.Static);如果(field2!=null)field2.SetValue(null,null);因此,它将解决dbo.EdmMetadata和dbo.__MigrationHistory表的问题。EF4.3和MVC4一起使用以共享所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理会员删除。如需转载请注明出处: