简体   繁体   English

我可以迁移到在Entity框架中无迁移创建的数据库吗?

[英]Can I migrate to database created without migration in Entity framework?

I had created a desktop application which uses SQL CE 4.0 and Entity framework with Code First mode. 我创建了一个桌面应用程序 ,它使用SQL CE 4.0Entity 框架Code First模式。 So, Initially I had installed application on a system, it worked fine. 所以,最初我在系统上安装了应用程序,它工作正常。

Now I added few properties to model class, so for this purpose I enabled migrations using Enable-Migrations and added new migration using Add-Migration "MyMigration" . 现在我为模型类添加了一些属性,因此为此我使用Enable-Migrations并使用Add-Migration "MyMigration"添加了新的迁移。 This was also successfull and I was able to install new version and upgrade database without any issue. 这也是成功的,我能够毫无问题地安装新版本和升级数据库。

But now when I install this setup on a system with no existing database then it fails, so after studying I realized that I need to add Initial Migration So, I revoked changes in model and also deleted my SQLCE database file, added initial migration, then Update-Database . 但是现在当我在没有现有数据库的系统上安装此设置时,它就失败了,所以在研究之后我意识到我需要添加初始迁移所以,我撤销了模型中的更改并删除了我的SQLCE数据库文件,添加了初始迁移,然后Update-Database So if I try to Update-Database using old-database which was created without enabling migrations then it fails, it tries to apply initial migration to database which it shouldn't according to me. 因此,如果我尝试使用在没有启用迁移的情况下创建的旧数据库来更新数据库,那么它会失败,它会尝试将初始迁移应用到数据库,而不应该根据我这样做。

Now if I delete old-database file and then Update-Database then new db is created and then once again added my changes to model and added expected migration. 现在,如果我删除旧数据库文件,然后删除Update-Database,则会创建新数据库,然后再次将我的更改添加到模型并添加预期的迁移。

So after this, turnaround I am able to install my application on blank system but it fails on a system with old database ie it doesn't upgrade database. 因此,在此之后,我可以在空白系统上安装我的应用程序但是在具有旧数据库的系统上失败,即它不会升级数据库。

It tries to apply Initial-Migration also, ie creating all the tables once again and fails saying that, The table already exists which isn't expected. 它也尝试应用初始迁移,即再次创建所有表并且不能说, 表已经存在 ,这是不期望的。

The thing is that it checks a table called Migrations, where I think it get information of the current squema and changes . 问题是,它检查一个名为Migrations的表, 我认为它获取当前squema和更改的信息 If you make a lof of changes of the DB without using EF, somehow you'll get to a point when a lot of clonflicts would happen. 如果你在不使用EF的情况下对数据库进行了大量更改,那么无论如何你都会遇到很多clonflicts会发生的事情。

You can use fluent migrations to do everything yourself and have more control of the changes and the rollbacks 您可以使用流畅的迁移来自己完成所有操作,并可以更好地控制更改和回滚

Example: 例:

 [Migration(201610250659)]
public class _201610250659_AddedMinimumValue_Prices : Migration
{
    public override void Up()
    {
        Alter.Table("Prices")
            .AddColumn("MinimunValue").AsInt32().NotNullable().WithDefaultValue(1);
    }

    public override void Down()
    {
        Delete.Column("MinimunValue")
            .FromTable("Prices");
    }
}

What you need is 你需要的是什么

update-database 

this will update the database accordingly. 这将相应地更新数据库。 Just remember everytime you add-migration you need to update-database, and when you install the system somewhere else, all you need is to do a update-database to get the older database on par with entity framework. 只需记住每次添加迁移时需要更新数据库,当您在其他地方安装系统时,您只需要执行更新数据库以使旧数据库与实体框架相同。

you need to check if into initial scripts, if table already exist or not. 你需要检查是否进入初始脚本,如果表已经存在或不存在。 Its not EF issue, even if your try to simply run create database scripts with table definition without checking existing one, it will fail. 它不是EF问题,即使您尝试简单地使用表定义运行创建数据库脚本而不检查现有数据库脚本,它也会失败。

For Example, 例如,

I don't have any database installed into my machine and I'm having script for create new with some table into it.. 我没有在我的机器上安装任何数据库,而且我正在创建带有一些表格的新脚本。

so this is script for creating table 所以这是创建表的脚本

    USE [TestStudent]
GO
/****** Object:  Table [dbo].[EmployeeInformation]    Script Date: 18-03-2017 19:12:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EmployeeInformation](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](50) NULL,
    [LastName] [nvarchar](50) NULL,
    [Designation] [nvarchar](50) NULL,
 CONSTRAINT [PK_EmployeeInformation] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
/****** Object:  Table [dbo].[sample]    Script Date: 18-03-2017 19:12:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[sample](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [TableId] [int] NULL,
 CONSTRAINT [PK_sample] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Notice that I'm just creating the tables not checking for object existence, now if I run this on new machine with blank database it will run without error.. 请注意,我只是创建表而不检查对象是否存在,现在如果我在具有空白数据库的新机器上运行它,它将运行而不会出现错误。

在此输入图像描述

Now, I try to run same script on existing database with existing objects may be for updating some tables like in your case but here's the trick, your update script will be at the bottom of this... so it will first try to create the tables and if existed it will throw you error.. 现在,我尝试在现有数据库上运行相同的脚本,现有的对象可能用于更新一些表,就像你的情况一样,但这里的诀窍,你的更新脚本将在这个底部...所以它将首先尝试创建表格如果存在则会引发错误..

在此输入图像描述

so you need to check the object existence before you create tables, like in this script... 所以你需要在创建表之前检查对象是否存在,就像在这个脚本中一样......

    USE [TestStudent]
GO
/****** Object:  Table [dbo].[EmployeeInformation]    Script Date: 18-03-2017 19:22:16 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EmployeeInformation]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[EmployeeInformation](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](50) NULL,
    [LastName] [nvarchar](50) NULL,
    [Designation] [nvarchar](50) NULL,
 CONSTRAINT [PK_EmployeeInformation] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
/****** Object:  Table [dbo].[sample]    Script Date: 18-03-2017 19:22:16 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[sample]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[sample](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [TableId] [int] NULL,
 CONSTRAINT [PK_sample] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO

so when you try to run this, it will skip the already existing objects that are in table will proceed to your update scripts... 因此,当您尝试运行此操作时,它将跳过表中已存在的对象将继续执行更新脚本...

在此输入图像描述

hope this helps... 希望这可以帮助...

OK, so if you have, say, 2 migrations: Initial and MyMigration and now you have an old database that has the changes represented by the first migration, but not the second and it keeps trying to apply the unneeded first migration - then you can resolve it this way: 好的,所以,如果你有2个迁移:初始和MyMigration,现在你有一个旧数据库,其中包含第一次迁移所代表的更改,但不是第二次迁移,并且它一直尝试应用不需要的第一次迁移 - 那么你可以以这种方式解决它:

1) Generate a complete migration script (BTW, this can be used to create a blank database of your model): 1)生成完整的迁移脚本(顺便说一句,这可用于创建模型的空白数据库):

Update-Database -Script -SourceMigration: $InitialDatabase

2) The code at the top of this script will check for the existance of __MigrationHistory and create it if it is missing. 2)此脚本顶部的代码将检查__MigrationHistory是否存在,如果缺少则创建它。

3A) Next, it will check for each migration with code like below. 3A)接下来,它将使用如下代码检查每次迁移。 Since your database already has these you should comment those lines out. 由于您的数据库已有这些,您应该注释掉这些行。

IF @CurrentMigration < '201702231958592_Initial'
BEGIN
     -- objects already exist, but EF doesn't know this
     -- CREATE TABLE, etc.
END

3B) Entity framework will insert a record into __MigrationHistory so it knows this migration has been applied. 3B)实体框架将一条记录插入__MigrationHistory,因此它知道已经应用了这种迁移。 Do not comment this line out! 不要评论这一行! (The long hex string is a representation of your model). (长十六进制字符串是模型的表示)。

INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N'201702231958592_Initial', N'MyApp.Data.Migrations.Configuration',  0x1F8B08000000

4) Steps 3A and 3B will be repeated for each migration, so leave them in there if they have not been applied. 4)对于每次迁移将重复步骤3A和3B,因此如果它们尚未应用则将它们留在那里。 Comment out the object changes if they do. 如果它们发生,请注释掉对象的更改。

Moving forward if you haven't messed with migrations EF will be smart enough to apply the changes to various deployments in different states of applied migrations. 如果您没有考虑迁移,那么向前发展EF将足够智能,可以将更改应用于应用迁移的不同状态中的各种部署。

As to your installer issue, you could either call this script via ADO.NET or you could use DbMigrator to do migrations in code. 至于安装程序问题,您可以通过ADO.NET调用此脚本,也可以使用DbMigrator在代码中进行迁移。

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

相关问题 如何使用Entity Framework 4.2执行数据库迁移? - How can I perform database migration using Entity Framework 4.2? 在实体框架中无需迁移即可更新数据库 - Update database without migration in Entity Framework 实体框架6更新数据库因使用-IgnoreChanges创建的迁移而失败 - Entity Framework 6 Update-Database fails for migration created with -IgnoreChanges 实体框架核心更新数据库 - 无需迁移的代码优先方法 - Entity Framework Core Update Database - Code First Approach Without Migration 如何使用没有迁移历史记录的实体框架更新数据库 - How to update database using entity framework without migration history 如何使用 Entity Framework Core 在加密的 SQLite 数据库上运行迁移? - How can I run a migration with Entity Framework Core on an encrypted SQLite database? 使用实体框架在 .NET Core 3.1 中进行迁移后,如何更新数据库 model? - How can I update the database model after doing a migration in .NET Core 3.1 using Entity Framework? 在Entity Framework迁移中更改数据库 - Alter database in Entity Framework migration 通过迁移更新实体框架数据库 - Updating Entity Framework Database by migration “脚本迁移”可以在 .NET Entity Framework Core 中创建数据库吗? - Can "Script-Migration" create the database in .NET Entity Framework Core?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM