EF Core - SQLServer迁移是否适用于SQLite?

时间:2017-10-05 13:37:21

标签: sql-server sqlite asp.net-core .net-core entity-framework-core

我有一个简单的项目,我最初使用SQL Server作为EF Core和Code-First方法的后端(遵循本教程:https://docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/new-db

现在我想将实现切换到SQLite。我以为我可以从SQL Server运行数据库创建的初始迁移并将其应用于SQLite。似乎它无法正常工作:例如。主键上的自动增量未应用,然后我看到一些不一致(sqlite抱怨'int'应该是'INTEGER')等。

那么,这是否意味着迁移依赖于后端?如果是,那么它们不应该在嵌套文件夹中创建(例如。./Migrations/SQLServer)?

有人可以解释一下这是如何工作的吗?

注意:抱歉,我是EF Code-First和迁移的新手......谢谢!

3 个答案:

答案 0 :(得分:3)

是的,迁移依赖于后端。每个后端都有自己的特性,因此迁移通常会有像列规范这样的后端细节。

在某些ORM中,可以映射“代码优先”'以抽象方式建模,让后端特定提供者将这个抽象模型映射到后端特定类型,但在任​​何相对复杂的模型中,很难保持整个映射后端独立。

要转移到SQLite,您可以在Startup.cs中更改配置,在此处将DbContext注册为

services.AddDbContext<YourContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")))

然后,您可以使用&#39; dotnet ef迁移添加&#39;来指定迁移的显式路径。命令。 This问题有关于设置显式文件夹路径的更多详细信息。

答案 1 :(得分:3)

// make the request var request = indexedDB.open( ... ); // hook up the event listener request.onupgradeneeded = function(e) { ... }; // hook up another event listener request.onsuccess = function(e) { ... }; / Add-Migration命令生成的迁移是特定于后端的,但您可以手动编辑它们以使它们与多个后端兼容。最简单的方法是生成两组迁移,如@alwayslearning's answer中所述,然后将它们组合到一个迁移集中。

例如,dotnet ef migrations add列可能如下所示:

Id

您还可以有条件地执行后端之间可能根本不同的事情:

Id = table.Column<int>(nullable: false)
    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
    .Annotation("Sqlite:Autoincrement", true);

答案 2 :(得分:0)

public class CompositeMigrationsAnnotationsProvider : IMigrationsAnnotationProvider
{
    private readonly IMigrationsAnnotationProvider[] _providers;

    public CompositeMigrationsAnnotationsProvider(MigrationsAnnotationProviderDependencies dependencies)
    {
        _providers = new IMigrationsAnnotationProvider[] {
            new SqlServerMigrationsAnnotationProvider(dependencies),
            new SqliteMigrationsAnnotationProvider(dependencies) 
        };
    }

    public IEnumerable<IAnnotation> For(IModel model) => _providers.SelectMany(p => p.For(model));
    public IEnumerable<IAnnotation> For(IProperty property) => _providers.SelectMany(p => p.For(property));
    public IEnumerable<IAnnotation> For(IIndex index) => _providers.SelectMany(p => p.For(index));
    public IEnumerable<IAnnotation> For(IKey key) => _providers.SelectMany(p => p.For(key));
    public IEnumerable<IAnnotation> For(IForeignKey foreignKey) => _providers.SelectMany(p => p.For(foreignKey));
    public IEnumerable<IAnnotation> For(IEntityType entityType) => _providers.SelectMany(p => p.For(entityType));
    public IEnumerable<IAnnotation> For(ISequence sequence) => _providers.SelectMany(p => p.For(sequence));
    public IEnumerable<IAnnotation> For(ICheckConstraint checkConstraint) => _providers.SelectMany(p => p.For(checkConstraint)); //EF Core 3.x
    public IEnumerable<IAnnotation> ForRemove(IModel model) => _providers.SelectMany(p => p.ForRemove(model));
    public IEnumerable<IAnnotation> ForRemove(IIndex index) => _providers.SelectMany(p => p.ForRemove(index));
    public IEnumerable<IAnnotation> ForRemove(IProperty property) => _providers.SelectMany(p => p.ForRemove(property));
    public IEnumerable<IAnnotation> ForRemove(IKey key) => _providers.SelectMany(p => p.ForRemove(key));
    public IEnumerable<IAnnotation> ForRemove(IForeignKey foreignKey) => _providers.SelectMany(p => p.ForRemove(foreignKey));
    public IEnumerable<IAnnotation> ForRemove(IEntityType entityType) => _providers.SelectMany(p => p.ForRemove(entityType));
    public IEnumerable<IAnnotation> ForRemove(ISequence sequence) => _providers.SelectMany(p => p.ForRemove(sequence));
    public IEnumerable<IAnnotation> ForRemove(ICheckConstraint checkConstraint) => _providers.SelectMany(p => p.ForRemove(checkConstraint)); //EF Core 3.x
}

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {

    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.ReplaceService<IMigrationsAnnotationProvider, CompositeMigrationsAnnotationsProvider>();
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.UseIdentityColumns(); //EF Core 3.x
        modelBuilder.ForSqlServerUseIdentityColumns(); //EF Core 2.x
    }
}