LinqPad连接EF6 DbContext:如何避免查询__MigrationHistory及优化参数传递?
针对你遇到的通过VPN访问数据库时,EF6和LinqPad生成的额外迁移历史查询拖慢性能的问题,这里有几个可行的解决方案:
一、完全禁用迁移历史查询(推荐)
EF6默认会在初始化DbContext时检查迁移历史,我们可以通过关闭数据库初始化器来彻底避免这些查询:
1. LinqPad查询内临时设置
在你的LinqPad查询最开头添加以下代码,针对当前查询禁用初始化检查:
// 替换成你的DbContext类型 var ctx = new YourDbContext(); Database.SetInitializer<YourDbContext>(null);
这段代码告诉EF不要执行任何数据库初始化操作,包括迁移历史的校验,自然就不会生成那些额外的SQL了。
2. 全局修改DbContext(如果有权限修改代码)
如果你能修改DbContext的源代码,可以在构造函数里添加初始化设置,这样所有使用这个DbContext的地方(包括LinqPad)都会生效:
public class YourDbContext : DbContext { public YourDbContext() : base("YourConnectionString") { // 禁用初始化器 Database.SetInitializer<YourDbContext>(null); } // 你的DbSet定义... }
注意:如果你的项目其他地方需要使用Code First迁移功能,不要用这个全局方法,改用LinqPad内的临时设置即可。
二、传递正确的ContextKey替代[UserQuery]
如果因为某些原因不能禁用初始化检查,我们可以让EF使用正确的ContextKey,避免它尝试不同的查询条件:
LinqPad里的动态查询类会被EF识别为UserQuery,导致ContextKey错误。我们可以手动指定ContextKey为你的DbContext的完整类型名:
var ctx = new YourDbContext(); // 设置正确的ContextKey ctx.Configuration.Migrations.ContextKey = typeof(YourDbContext).FullName;
这样EF查询__MigrationHistory时会使用你实际DbContext的ContextKey,匹配数据库中已有的迁移记录,避免多次无效查询。
三、消除EdmMetadata查询
你提到的最后一条查询EdmMetadata表的语句是EF旧版本的遗留行为,EF6中Code First迁移已经不再使用这个表。通过上面的Database.SetInitializer(null)设置,同样可以避免这个查询。
另外,针对Devart dotconnect for Oracle的小提示:确保你的连接字符串和LinqPad中的Provider设置正确,不需要额外启用迁移相关的自动检查选项,这也能减少不必要的查询。
内容的提问来源于stack exchange,提问作者PeterB

