实体框架核心,代码优先迁移和数据迁移

Kra*_*ram 6 c# ef-migrations entity-framework-core

我正在尝试先使用EF Core代码迁移来对现有表进行非规范化。

我有一个现有表LoginEvent,其数据如下所示:

???????????????????????????????????????????????????
?                   LoginEvent                    ?
???????????????????????????????????????????????????
? Id ? VenueRef ? VenueName ? OccurredAt ? UserId ?
???????????????????????????????????????????????????
? 1  ? ven01    ? Venue 1   ? 2018-01-29 ? 5      ?
???????????????????????????????????????????????????
? 2  ? ven02    ? Venue 2   ? 2018-01-30 ? 7      ?
???????????????????????????????????????????????????
? 3  ? ven01    ? Venue 1   ? 2018-02-01 ? 9      ?
???????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
public class LoginEvent
{
    [Key]
    public int Id { get; set; }
    public string VenueRef { get; set; }
    public string VenueName { get; set; }
    public DateTime OccurredAt { get; set; }
    public User User { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想将此标准化为两个表:LoginEventVenue,如下所示:

???????????????????????????????????????
?             LoginEvent              ?
???????????????????????????????????????
? Id ? VenueRef ? OccurredAt ? UserId ?
???????????????????????????????????????
? 1  ? ven01    ? 2018-01-29 ? 5      ?
???????????????????????????????????????
? 2  ? ven02    ? 2018-01-30 ? 7      ?
???????????????????????????????????????
? 3  ? ven01    ? 2018-02-01 ? 9      ?
???????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
????????????????????????
?        Venue         ?
????????????????????????
? VenueRef ? VenueName ?
????????????????????????
? ven01    ? Venue 1   ?
????????????????????????
? ven02    ? Venue 2   ?
????????????????????????
Run Code Online (Sandbox Code Playgroud)

现在,我通过添加一个新的Venue域对象并LoginEvent引用它来完成此操作,如下所示:

public class LoginEvent
{
    [Key]
    public int Id { get; set; }    
    public string VenueRef { get; set; }
    public DateTime OccurredAt { get; set; }
    public Venue Venue { get; set; }
    public User User { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
public class Venue
{
    [Key]
    public string VenueRef { get; set; }
    public string VenueName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,我创建了一个迁移,该迁移(正确)是:

  1. 创建新Venue
  2. VenueName
  3. 设置两者之间的外键约束

但是,我需要做的是在第1步和第2步之间运行数据迁移,以便在删除列和设置约束之前将现有的Venues放在新表中(否则,我将丢失数据并且约束失败,因为我没有相关的场地)。

我想在我的数据迁移中运行以下内容:

INSERT INTO Venue SELECT DISTINCT VenueRef, VenueName FROM LoginEvent
Run Code Online (Sandbox Code Playgroud)

我应该怎么做?

Geo*_*der 6

您可以使用执行任何SQL migrationBuilder.Sql(theSqlString)

就你而言

migrationBuilder.Sql("INSERT INTO Venue SELECT DISTINCT VenueRef, VenueName FROM LoginEvent");
Run Code Online (Sandbox Code Playgroud)

在创建新表之后Venue并删除旧列之前,请在迁移中运行此命令VenueName

另请参阅自定义迁移操作