从 .NET 4.5 迁移到 .NET Core 2.2 后如何 "re-pluralize" 数据库表?
How to "re-pluralize" database tables after moving from .NET 4.5 to .NET Core 2.2?
我有一个项目要从 .NET 4.5 迁移到 .NET Core,出于某种原因(我不记得了),我想防止 table 名称的复数化运行 像这样的 update-database
(.NET 4.5):
public class UncoveredLink : DbContext
{
//removed constructor for brevity
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//the line I'm talking about is here
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
因此,当我在 SQL Management Studio 中查看我的数据库时,我看到以下内容:
//what I see
dbo.Album
dbo.Artist
//what i want
dbo.Albums
dbo.Artists
我认为缺少复数是导致我尝试加载页面时出现此错误的原因:
SqlException: Invalid object name 'Albums'.
//further down the stack trace i see
UnLink.Services.AlbumService.GetAlbumByStringExt(string stringExt) in AlbumService.cs
album = _db.Albums.Where(x => x.StringExt == stringExt).FirstOrDefault();
看到了吗?我正在尝试调用 _db.Albums
但我相信我不能这样做,因为 table 没有复数并且我的核心上下文没有像我的 .NET 4.5 那样的复数 OnModelCreating
做了(似乎无法添加)。
我在 .NET Core 2.2 中的新 DbContext 如下所示:
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
如何更新 table 名称?我的核心 DbContext(如上所示)中的 tables 已经复数化,所以我无法更改将跟踪新 add-migration
的 DbContext ...我只是手动创建迁移文件并更新 table 名称,例如:
migrationBuilder.RenameTable(name: "Artist", schema: "dbo", newName: "Artists", newSchema: "dbo");
我认为为代码中实际上 changed/tracked 之外的内容创建迁移不是一个好的做法?
嗯,您已经对代码进行了更改,因为您以前有关于 Remove<Pluralizing>
的那一行,但现在没有了。不幸的是,Add-Migration
可能不会接受此更改,尤其是当您同时转换为 .Net Core 时。
由于您的模型与您的 table 不匹配,您有以下选择:
- 手动创建更改 table 名称的迁移:
migrationBuilder.RenameTable("Album", newName: "Albums");
或
2. 直接向SQL中的Db写一个查询来改变table的名字:
EXEC sp_rename 'dbo.Album', 'dbo.Albums';
我认为这会有所帮助:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
modelBuilder.Entity<Album>()
.ToTable("Album");
}
另一种方式是:
[Table("Album")]
public class Album
{
public int AlbumId { get; set; }
public string Name { get; set; }
}
EF Core 2.0 引入了一个新的 IPluralizer 服务,用于单数化实体类型名称和复数化 DbSet 名称。
也许你可以调查一下。这里有很多关于此的 post 或 here's 博客 post 关于那个
我有一个项目要从 .NET 4.5 迁移到 .NET Core,出于某种原因(我不记得了),我想防止 table 名称的复数化运行 像这样的 update-database
(.NET 4.5):
public class UncoveredLink : DbContext
{
//removed constructor for brevity
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//the line I'm talking about is here
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
因此,当我在 SQL Management Studio 中查看我的数据库时,我看到以下内容:
//what I see
dbo.Album
dbo.Artist
//what i want
dbo.Albums
dbo.Artists
我认为缺少复数是导致我尝试加载页面时出现此错误的原因:
SqlException: Invalid object name 'Albums'.
//further down the stack trace i see
UnLink.Services.AlbumService.GetAlbumByStringExt(string stringExt) in AlbumService.cs
album = _db.Albums.Where(x => x.StringExt == stringExt).FirstOrDefault();
看到了吗?我正在尝试调用 _db.Albums
但我相信我不能这样做,因为 table 没有复数并且我的核心上下文没有像我的 .NET 4.5 那样的复数 OnModelCreating
做了(似乎无法添加)。
我在 .NET Core 2.2 中的新 DbContext 如下所示:
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
如何更新 table 名称?我的核心 DbContext(如上所示)中的 tables 已经复数化,所以我无法更改将跟踪新 add-migration
的 DbContext ...我只是手动创建迁移文件并更新 table 名称,例如:
migrationBuilder.RenameTable(name: "Artist", schema: "dbo", newName: "Artists", newSchema: "dbo");
我认为为代码中实际上 changed/tracked 之外的内容创建迁移不是一个好的做法?
嗯,您已经对代码进行了更改,因为您以前有关于 Remove<Pluralizing>
的那一行,但现在没有了。不幸的是,Add-Migration
可能不会接受此更改,尤其是当您同时转换为 .Net Core 时。
由于您的模型与您的 table 不匹配,您有以下选择:
- 手动创建更改 table 名称的迁移:
migrationBuilder.RenameTable("Album", newName: "Albums");
或 2. 直接向SQL中的Db写一个查询来改变table的名字:
EXEC sp_rename 'dbo.Album', 'dbo.Albums';
我认为这会有所帮助:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
modelBuilder.Entity<Album>()
.ToTable("Album");
}
另一种方式是:
[Table("Album")]
public class Album
{
public int AlbumId { get; set; }
public string Name { get; set; }
}
EF Core 2.0 引入了一个新的 IPluralizer 服务,用于单数化实体类型名称和复数化 DbSet 名称。
也许你可以调查一下。这里有很多关于此的 post 或 here's 博客 post 关于那个