ASP.NET Core 3.0-无法更新数据库

时间:2019-10-14 06:58:42

标签: sql-server asp.net-core

我刚刚使用命令dotnet new angular -o <output_directory_name> -au Individual和脚手架标识创建了项目,然后安装了Microsoft.EntityFrameworkCore.SqlServer,但是当我运行命令update-database时,出现以下错误。

Failed executing DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetRoles] (
    [Id] TEXT NOT NULL,
    [Name] TEXT(256) NULL,
    [NormalizedName] TEXT(256) NULL,
    [ConcurrencyStamp] TEXT NULL,
    CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id])
);

,然后在最后结束另一个错误

  

错误号:2716,状态:1,类:16
  列,参数或变量2:无法在数据类型文本上指定列宽。

下面是生成的CreateIdentitySchema迁移

migrationBuilder.CreateTable(
    name: "AspNetRoles",
    columns: table => new
    {
        Id = table.Column<string>(nullable: false),
        Name = table.Column<string>(maxLength: 256, nullable: true),
        NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
        ConcurrencyStamp = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_AspNetRoles", x => x.Id);
    });

ApplicationDbContextModelSnapshot.cs

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
    b.Property<string>("Id")
        .HasColumnType("nvarchar(450)");

    b.Property<string>("ConcurrencyStamp")
        .IsConcurrencyToken()
        .HasColumnType("nvarchar(max)");

    b.Property<string>("Name")
        .HasColumnType("nvarchar(256)")
        .HasMaxLength(256);

    b.Property<string>("NormalizedName")
        .HasColumnType("nvarchar(256)")
        .HasMaxLength(256);

    b.HasKey("Id");

    b.HasIndex("NormalizedName")
        .IsUnique()
        .HasName("RoleNameIndex")
        .HasFilter("[NormalizedName] IS NOT NULL");

    b.ToTable("AspNetRoles");
});

如何解决此错误,以便我可以更新数据库?

00000000000000_CreateIdentitySchema.Designer.cs 中将“ TEXT”更改为“ VARCHAR”会导致以下错误。当我将其更改为“ NVARCHAR”时也会发生同样的情况

Data type 'VARCHAR' for property 'Id' is not supported in this form. Either specify the length explicitly in the type name, for example as 'NVARCHAR(16)', or remove the data type and use APIs such as HasMaxLength to allow EF choose the data type.

6 个答案:

答案 0 :(得分:5)

这些答案都很有帮助,尤其是@klent的答案。我使用以下方法生成了一个新项目:

dotnet新角度-o [我的项目] -au个人

这产生了一个新项目,该项目使用Sqlite作为数据提供程序,尽管我没有意识到。我将连接字符串更改为SQL Server,然后运行:

dotnet ef数据库更新

,并在原始问题中发布了错误。在查看了这里的答案之后,我意识到我使用的数据提供程序不正确,并且迁移针对的是Sqlite语法,该语法使用TEXT(256)作为列规范之一。因此,我要更正的具体步骤是:

  1. 删除Microsoft.EntityFrameworkCore.Sqlite Nuget程序包。
  2. 安装Microsoft.EntityFrameworkCore.SqlServer Nuget程序包。
  3. 在我的Startup.cs的ConfigureServices方法中,将services.AddDbContext调用更改为使用options.UseSqlServer而不是options.UseSqlite
  4. 从Migrations文件夹中删除_CreateIdentitySchema和ApplicationDbContentsModelSnapshot类。
  5. 确保AppSettings.json中的连接字符串指向SQL Server而不是Sqlite后,运行dotnet ef migrations add CreateIdentitySchema -o Data\Migrations。请注意,-o参数中指定的输出文件夹可能与您有所不同。
  6. 检查Visual Studio项目浏览器。现在,两个新类将出现在“迁移”文件夹中。
  7. 运行dotnet ef database update。这将在数​​据库中的连接字符串中创建表。

此外,如果希望表位于特定的架构(例如“ Auth”)中,请打开ApplicationDbContext类并添加:

protected override void OnModelCreating( ModelBuilder builder )
{
    base.OnModelCreating( builder );
    builder.HasDefaultSchema( "Auth" );
}

但是,这将为使用此DbContext的所有访问设置模式。这对我来说不是问题,因为我没有为应用程序数据使用EF,而仅为身份数据使用EF。 YMMV。

答案 1 :(得分:1)

正如其他一些人已经回答的那样,默认的Identity安装似乎创建了错误的列类型。也就是说,某些Id列应为varchar而不是text。

我遇到了与您完全相同的问题,并且花了很多时间试图有效地解决它。

对于所有遇到此问题的人,我发现解决它的最快方法是:

  • 创建新项目
  • 完全删除“迁移”文件夹
  • 安装Sql Server软件包(或您使用的任何数据系统)和连接字符串详细信息
  • 使用dotnet ef migrations add <MIGRATION NAME>Add-Migration添加您自己的迁移(这将使用正确的列结构从头开始编写新的迁移设计器文件
  • 最后,用dotnet ef database updateUpdate-Database来更新数据库

答案 2 :(得分:1)

我有此错误,可以按以下步骤解决。

步骤1.打开项目并删除2个迁移文件和1个快照文件。最有可能命名为0000 ... InitialCreate.cs,0000 ... InitialCreate.Designer.cs和... DbContextModelSnapshot.cs。离开DbContextClass。

第2步。删除数据库。

步骤3.使用dotnet创建新的迁移并更新数据库。我还编写了迁移脚本以进行检查。

dotnet ef迁移添加InitialCreate --context ApplicationDbContext -v

dotnet ef数据库更新--context ApplicationDbContext -v

dotnet ef迁移脚本--context ApplicationDbContext -v

答案 3 :(得分:0)

根据@sepupic和@PeterSmith的评论,问题在于00000000000000_CreateIdentitySchema.Designer.cs中自动生成的代码具有TEXT的{​​{1}}字段,因此我将其更改为{{1} },然后将HasMaxLength添加到所有VARCHAR ID中,然后我尝试再次更新数据库,并且该数据库正常工作。

我运行项目并尝试注册用户,但出现以下错误

  

System.InvalidCastException:无法将类型为“ System.Int32”的对象转换为类型为“ System.Bolean”

由于我仍然有错误,因此请执行以下操作:

  1. 我删除了生成的表,然后使用命令HasMaxLength(450)
  2. 创建了一个新项目。
  3. 我没有为新创建的项目提供新的身份
  4. 我从上一个项目复制了数据库名称,然后运行命令update-database
  5. 有两个丢失的表VARCHARdotnet new angular -o <output_directory_name> -au Individual,所以我运行命令DeviceCodes,但是它没有生成任何内容,因此我从上一个项目中复制了两个表的迁移代码并将其粘贴到我之前创建的空迁移代码中。
  6. 我再次运行该项目并注册一个新用户,它终于成功了

由于以前的项目对自动生成的代码没有任何问题,我仍然不知道为什么会出错。

答案 4 :(得分:0)

我有一个像你一样的错误

表“角色”中的列“ Id”的类型无效,不能用作索引中的键列。

因为我更改了Asp.Net Core Web应用程序的“个人身份”附带的表名。

简单地说,

  • 删除迁移文件夹中除 ApplicationDBContext 之外的所有内容。
  • 添加迁移
  • 确保表名在 BuildTargetModel
  • 中是否匹配
  • 然后更新数据库

对我有用!

编辑:我的主要观点是确保表名称在Up,Down和BuildTargetModel中是否匹配。之后,更新数据库将起作用。

答案 5 :(得分:0)

我通过@abCsharp 的第一个回答解决了这个数据库更新错误,但直到我注意到我从 Identity 选项开始的项目在项目文件夹下创建了一个新的迁移文件夹。原始迁移文件夹位于同样包含 ApplicationDbContext 的 Data 文件夹下。

我删除了原始文件夹(为了清洁)并运行了新创建的迁移。我还删除了数据库中的迁移历史记录表,其中包含我没有使用迁移的表。

FWIW 所有表中文本的所有数据类型都是 nvarchar。