如何在Entity Framework Core中使用复数DbSet属性名称搭建DbContext的脚手架?

24

2023年更新:对于现代EF Core版本(.NET 5+),复数形式默认启用,如https://dev59.com/zFsW5IYBdhLWcg3w0aDM#64801660中所示。尽管当时的讨论非常相关,但其余部分只是历史。

原始问题:

我在Package Manager Console中使用Scaffold-DbContext命令为现有的SQL Server数据库创建和重新创建上下文和实体:

Scaffold-DbContext -provider EntityFramework.MicrosoftSqlServer -connection "my connection string"

它完美地运行,除了一件事: DbSet 的属性名称是单数形式:
public partial class MyDbContext : DbContext
{
    public virtual DbSet<Request> Request { get; set; }
    public virtual DbSet<RequestHeader> RequestHeader { get; set; }
}

我更喜欢这些名称以复数形式出现(例如Requests)。除了网络搜索,我还检查了命令语法:

get-Help Scaffold-DbContext -detailed

并未找到任何更改此行为的方法。这是我的packages.config文件:

<packages>
  <package id="EntityFramework.Commands" version="7.0.0-rc1-final" targetFramework="net46" />
  <package id="EntityFramework.Core" version="7.0.0-rc1-final" targetFramework="net46" />
  ...
</packages>

如何在生成代码时将 DbSet 名称转换为复数形式? 更新 2017-04:在 Entity Framework Core 1.1 中,现在可以对数据库先有的表进行生成代码,并且可以将其转换为复数形式。请参阅下面 答案 以获取更多详细信息。

阅读这个和这个关于Entity Framework 7数据库模型复数化的两篇文章。 - Hamid Pourjam
医生 - 这已不再受支持,但类似的东西将在 RTM 后出现。 - ErikEJ
请查看我的回答:stackoverflow.com/a/47410837/869033 - Nick N.
@NickN。自EF Core 1.1以来,IDesignTimeServices技巧已经被广泛应用。请参考我的回答 =) https://dev59.com/zFsW5IYBdhLWcg3w0aDM#43320867 - Ilya Chumakov
IPluralizer接口是新的,不过现在更容易了。 - Nick N.
6个回答

7

简短回答

1. 安装包

Install-Package Bricelam.EntityFrameworkCore.Pluralizer

2. 运行Scaffold-DbContext命令

Scaffold-DbContext -Connection "Server=<server>;Database=<dbname>;user id=<userid>;password=<pwd>;" -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir Data/EFModels/


详细回答:

@natemcmaster的回答所述,可以使用名为Bricelam.EntityFrameworkCore.Pluralizer的软件包在EF Core中实现复数形式。可通过PackageManager Console (PMC)或

dotnet add package Bricelam.EntityFrameworkCore.Pluralizer

在Dotnet cli中安装软件包。

安装完软件包后,使用常规的Scaffold-DbContext命令即可。

Scaffold-DbContext -Connection "Server=<server>;Database=<dbname>;user id=<userid>;password=<pwd>;" -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir Data/EFModels/ -Force

了解有关Bricelam's Pluralizer的更多信息


1
最终,它适用于不同的提供商。我使用了唯一的更改命令来搭建一个PostgreSQL数据库:-Provider Npgsql.EntityFrameworkCore.PostgreSQL - Ilya Chumakov

7
您可以使用以下命令:
Scaffold-DbContext "connectionString" Microsoft.EntityFrameworkCore.SqlServer -o Models -UseDatabaseNames -NoPluralize -force

你之前使用过 NuGet 包:

Microsoft.EntityFrameworkCore.Design - version 5
Microsoft.EntityFrameworkCore - version 5
Microsoft.EntityFrameworkCore.SqlServer -version 5
Microsoft.EntityFrameworkCore.Tools - version 5
Microsoft.EntityFrameworkCore.Relational -version 5

3
NoPluralize会添加复数形式吗? - Greg Z.
默认情况下启用了复数形式,而-NoPluralize则禁用了它。 - Ilya Chumakov

5

更新 EntityFrameworkCore 5.0:在生成方案时,表名现在会自动进行复数形式处理。(至少使用提供程序 Microsoft.EntityFrameworkCore.SqlServer)


就是这样,无论选择哪个数据库提供程序,Scaffold-DbContext 默认启用了复数形式。 - Ilya Chumakov

2
在 EF Core 1.1 中可以实现复数形式。正如 Rowan Miller 在其博客中所描述的那样,您需要安装 Inflector 并实现 IDesignTimeServices 来控制脚手架生成时的复数形式。但是,请注意以下内容:

我们将这些服务放入 *.internal 命名空间,并保留在任何时候更改 API 的权利。

因此,完整的代码示例未在此处复制。出于同样的原因,此答案未被接受 - 我更喜欢等待稳定的 API。
另一个问题是,您应该考虑这个解决方案是依赖于提供程序的。它可以与 SQL Server(我测试过)很好地配合使用。其他 DBMS 提供程序可能尚未支持此 API。例如,最新的 Npgsql.EntityFrameworkCore.PostgreSQL 1.1.0 在使用自定义 IDesignTimeServices 进行脚手架生成时会失败。

1

2
Bricelam的解决方案非常好,很棒!但对我来说仍未解决的问题是,当表名中存在多个大写字母时(例如:GPSSettings),它会将除第一个字母外的所有字母转换为小写(例如:Gpssettings.cs)。 - Kalin Krastev
1
如果有人想知道@KalinKrastev上面评论中提到的Bricelam的解决方案是什么,可以查看https://www.bricelam.net/2018/03/02/efcore-pluralization.html。 - Hamza Khanzada

0

或许我来晚了,但在从.net Core 3.1升级到.net 6后,当我使用以下命令时:dbcontext scaffold "Server=(local);Database=XXXXXX;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models\Entities -c DBContext -f --verbose --no-onconfiguring --startup-project ../XXXX^,它通过生成它们的单数形式重复生成了我的实体。在升级之前,该命令给出的是实体名称而非添加了重复的单数形式。我发现使用--no-pluralize选项可以防止命令生成另一个带有单数形式的实体。我知道他们在.net Core 5中添加了默认的复数形式处理器,但我不知道为什么这样可以避免单数化。所以Cris Loli的回答似乎解决了我的问题。希望这能帮助某人解决他们的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接