Entity Framework 7 迁移未创建表
Entity Framework 7 migration not creating tables
我正在使用 Entity Framework 7 处理我的第一个项目,并正在连接到一个 SQL 服务器,数据库已在其中创建,但其中还没有 table。我已经创建了我的 DbContext
并创建了一个 class,然后在我的上下文中设置了一个 DbSet<>
。我 运行 命令启用迁移并创建第一个迁移,然后 运行d 命令更新数据库。一切看起来都工作正常,没有出现错误,但是当我查看数据库时,只创建了 EFMigraitonsHistory
table。当我查看为初始迁移创建的 class 时,它基本上是空白的。我做错了什么?
命令我是运行:
dnvm install latest -r coreclr
dnx ef migrations add MyFirstMigration
dnx ef database update
上下文:
namespace JobSight.DAL
{
public class JobSightDBContext : DbContext
{
public DbSet<NavigationMenu> NavigationMenu { get; set; }
}
}
Table Class:
namespace JobSight.DAL
{
public class NavigationMenu
{
[Required, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int16 ID { get; set; }
public string ControllerName { get; set; }
public string ActionName { get; set; }
public string ExternalURL { get; set; }
public string Title { get; set; }
public Int16? ParentID { get; set; }
public virtual NavigationMenu Parent { get; set; }
}
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<JobSightDBContext>(options =>
{
options.UseSqlServer(Configuration["Data:JobSightDatabase:ConnectionString"]);
});
}
Class 用于初始迁移(由 EF 自动生成):
namespace JobSight.WebUI.Migrations
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
编辑:
按照 Poke 的建议进行操作后,这是我新的自动生成的迁移。 table 仍然没有在数据库级别创建。
namespace JobSight.WebUI.Migrations
{
public partial class MyFirstMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "NavigationMenu",
columns: table => new
{
ID = table.Column<short>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
ActionName = table.Column<string>(nullable: true),
ControllerName = table.Column<string>(nullable: true),
ExternalURL = table.Column<string>(nullable: true),
ParentID = table.Column<short>(nullable: true),
Title = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_NavigationMenu", x => x.ID);
table.ForeignKey(
name: "FK_NavigationMenu_NavigationMenu_ParentID",
column: x => x.ParentID,
principalTable: "NavigationMenu",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable("NavigationMenu");
}
}
}
您需要先在数据库上下文中设置实体。至少,您需要这样做:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<NavigationMenu>();
}
您的迁移问题隐藏在您的项目布局中。因此,您拥有的是一个包含实体和数据库上下文的 JobSight.DAL
项目。然后你有一个项目 JobSight.WebUI
,它是包含 Startup.cs
和数据库设置的实际 ASP 项目。
这会导致问题,因为默认情况下 EF 将假定在当前程序集中找到所有内容。因此,如果您从 Web 项目启动 ef
命令,即使上下文在另一个项目中,它也会在其中创建迁移。但是当您随后尝试应用迁移时,EF 将找不到它,因为它只会在上下文的项目中查找。
因此,要解决此问题,您需要在 DAL
项目中创建迁移。您可以通过在调用 ef
命令时指定项目来做到这一点:
dnx ef migrations add Example -p JobSight.DAL
之后您可以通过 运行ning dnx ef migrations list
验证这是否有效。现在应该 return Example
迁移;以前,该命令没有 return 任何东西:它找不到迁移,这就是为什么 update
命令只说 Done
(没有应用迁移)并且数据库不存在的原因吨创建。因此,如果您现在在那里进行迁移,则可以使用以下方式应用它:
dnx ef database update
注意,由于现在迁移是在DAL项目中创建的,所以需要在那里添加对EntityFramework.MicrosoftSqlServer
的引用,否则项目将无法编译。您需要先执行此操作,然后才能 运行 上面的 list
命令。
最后,有关此的更多信息,请参阅 this issue。
虽然这不是原始问题的答案,但我 post 在这里回答是因为它可能对遇到类似问题的人有所帮助。我的问题还在于 table 未创建,但 dotnet ef migrations add InitialCreate
确实在 Migrations 文件夹中创建了 3 个 .cs 文件。但是 dotnet ef database update
只创建了 MigrationsHistory table 而 dotnet ef migrations list
没有 return 任何迁移。
原来问题出在 Migrations 文件夹被排除在 Visual Studio 项目之外。一旦我再次包含它,一切正常。
我遇到了同样的问题,我是这样解决的
- 我在 SQL
删除了我的数据库
- 我更改了之前迁移时使用的名称。我从 "Add-Migration InitialCreate" 更改为 "Add-Migration NewName"
我正在使用 Entity Framework 7 处理我的第一个项目,并正在连接到一个 SQL 服务器,数据库已在其中创建,但其中还没有 table。我已经创建了我的 DbContext
并创建了一个 class,然后在我的上下文中设置了一个 DbSet<>
。我 运行 命令启用迁移并创建第一个迁移,然后 运行d 命令更新数据库。一切看起来都工作正常,没有出现错误,但是当我查看数据库时,只创建了 EFMigraitonsHistory
table。当我查看为初始迁移创建的 class 时,它基本上是空白的。我做错了什么?
命令我是运行:
dnvm install latest -r coreclr
dnx ef migrations add MyFirstMigration
dnx ef database update
上下文:
namespace JobSight.DAL
{
public class JobSightDBContext : DbContext
{
public DbSet<NavigationMenu> NavigationMenu { get; set; }
}
}
Table Class:
namespace JobSight.DAL
{
public class NavigationMenu
{
[Required, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int16 ID { get; set; }
public string ControllerName { get; set; }
public string ActionName { get; set; }
public string ExternalURL { get; set; }
public string Title { get; set; }
public Int16? ParentID { get; set; }
public virtual NavigationMenu Parent { get; set; }
}
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<JobSightDBContext>(options =>
{
options.UseSqlServer(Configuration["Data:JobSightDatabase:ConnectionString"]);
});
}
Class 用于初始迁移(由 EF 自动生成):
namespace JobSight.WebUI.Migrations
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
编辑: 按照 Poke 的建议进行操作后,这是我新的自动生成的迁移。 table 仍然没有在数据库级别创建。
namespace JobSight.WebUI.Migrations
{
public partial class MyFirstMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "NavigationMenu",
columns: table => new
{
ID = table.Column<short>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
ActionName = table.Column<string>(nullable: true),
ControllerName = table.Column<string>(nullable: true),
ExternalURL = table.Column<string>(nullable: true),
ParentID = table.Column<short>(nullable: true),
Title = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_NavigationMenu", x => x.ID);
table.ForeignKey(
name: "FK_NavigationMenu_NavigationMenu_ParentID",
column: x => x.ParentID,
principalTable: "NavigationMenu",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable("NavigationMenu");
}
}
}
您需要先在数据库上下文中设置实体。至少,您需要这样做:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<NavigationMenu>();
}
您的迁移问题隐藏在您的项目布局中。因此,您拥有的是一个包含实体和数据库上下文的 JobSight.DAL
项目。然后你有一个项目 JobSight.WebUI
,它是包含 Startup.cs
和数据库设置的实际 ASP 项目。
这会导致问题,因为默认情况下 EF 将假定在当前程序集中找到所有内容。因此,如果您从 Web 项目启动 ef
命令,即使上下文在另一个项目中,它也会在其中创建迁移。但是当您随后尝试应用迁移时,EF 将找不到它,因为它只会在上下文的项目中查找。
因此,要解决此问题,您需要在 DAL
项目中创建迁移。您可以通过在调用 ef
命令时指定项目来做到这一点:
dnx ef migrations add Example -p JobSight.DAL
之后您可以通过 运行ning dnx ef migrations list
验证这是否有效。现在应该 return Example
迁移;以前,该命令没有 return 任何东西:它找不到迁移,这就是为什么 update
命令只说 Done
(没有应用迁移)并且数据库不存在的原因吨创建。因此,如果您现在在那里进行迁移,则可以使用以下方式应用它:
dnx ef database update
注意,由于现在迁移是在DAL项目中创建的,所以需要在那里添加对EntityFramework.MicrosoftSqlServer
的引用,否则项目将无法编译。您需要先执行此操作,然后才能 运行 上面的 list
命令。
最后,有关此的更多信息,请参阅 this issue。
虽然这不是原始问题的答案,但我 post 在这里回答是因为它可能对遇到类似问题的人有所帮助。我的问题还在于 table 未创建,但 dotnet ef migrations add InitialCreate
确实在 Migrations 文件夹中创建了 3 个 .cs 文件。但是 dotnet ef database update
只创建了 MigrationsHistory table 而 dotnet ef migrations list
没有 return 任何迁移。
原来问题出在 Migrations 文件夹被排除在 Visual Studio 项目之外。一旦我再次包含它,一切正常。
我遇到了同样的问题,我是这样解决的
- 我在 SQL 删除了我的数据库
- 我更改了之前迁移时使用的名称。我从 "Add-Migration InitialCreate" 更改为 "Add-Migration NewName"