繁体   English   中英

使用EF Code First从程序集获取本地迁移而无需连接字符串

[英]Get local migrations from assembly using EF Code First without a connection string

因此,我遇到以下情况,也许你们可以对此有所了解:

脚本
我们的应用程序包含许多客户端应用程序(Winforms),每个应用程序都使用EF Code First Migrations使用特定版本的数据库模型。 客户端应用程序具有连接到多个不同数据库的能力,这些数据库均支持客户端所需的所需架构。

接下来,我们有一个中央服务应用程序。 该应用程序负责维护数据库(创建/删除),并将连接字符串返回给需要访问的客户端。 客户端可以向该中央服务发送请求以创建新数据库。 此调用的参数之一是它需要的架构版本(以字符串形式)。 这是问题所在:

问题
问题是要找出什么是迁移的最高版本,而没有提供任何要连接的连接字符串或数据库。 通常一个人会使用:

var configuration = new MigrationsConfiguration() { ContextType = typeof(CoreContext) };
var migrator = new DbMigrator(configuration);
var versions = migrator.GetLocalMigrations();

但这会自动导致连接到后台数据库(如果未提供,则只是。\\ SQLExpress)。 即使您将DatabaseInitializer显式设置为null并提供将AutomaticMigrations设置为false的DbMigrationsConfiguration实现,也会发生此行为。

尝试遵循stacktrace我看到以下内容:

at System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection)
at System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.<>c__DisplayClass1.<ResolveManifestToken>b__0(Tuple`3 k)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.ResolveManifestToken(DbConnection connection)
at System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInfo(DbConnection connection, DbProviderManifest& providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized()
at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
at System.Data.Entity.Utilities.DbContextExtensions.<>c__DisplayClass1.<GetModel>b__0(XmlWriter w)
at System.Data.Entity.Utilities.DbContextExtensions.GetModel(Action`1 writeXml)
at System.Data.Entity.Utilities.DbContextExtensions.GetModel(DbContext context)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)

对我来说,这有点像火箭科学。 也许有人可以向我解释在没有提供连接字符串或数据库的情况下是否可以使用EF Code First模型。 或者,也许我缺少关键的配置设置?

问候,帕特里克

PS。 我目前通过使用反映迁移所在的程序集/名称空间并选择其ID的方法找到了一种解决方法。 这实际上就是GetLocalMigrations()实际工作的方式。

好吧,您基本上回答了自己的问题,但只是为了证实自己的怀疑:如果不提供目标数据库,则无法通过DbMigrator类获得本地迁移。

关于使用Reflection的解决方案,您是对的,原始方法也在MigrationAssembly类中也使用了此方法,对于简化版本,可以使用如下代码:

var migrationsSimplified = (from t in migrationsAssembly.DefinedTypes.Select(t => t.AsType())
                            where t.IsSubclassOf(typeof(DbMigration))
                            select (IMigrationMetadata)Activator.CreateInstance(t))
                            .OrderBy(mm => mm.Id)
                            .ToList();

原始功能可以在这里找到: http : //entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Migrations/Infrastructure/MigrationAssembly.cs

问题的另一部分,如果您在异常的堆栈跟踪中向后看,您会发现

System.Data.Entity.Utilities.DbContextExtensions.GetModel(this DbContext context)

您可以在此处找到以下功能: http ://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Infrastructure/EdmxWriter.cs这将使用您在DbMigrationsConfiguration中指定的类型的上下文。

而且,如果您深入研究,您实际上会在DbConnectionExtensions类中找到GetProviderInfo信息,该类希望获取尚未定义的连接。

需要注意的一件事:调用GetLocalMigrations函数时不会发生此异常,因为上下文使用延迟初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM