【问题标题】:How to singularize entities with EntityFramework core如何使用 EntityFramework 核心来单一化实体
【发布时间】:2017-07-17 16:52:20
【问题描述】:

最近我创建了一个 ASP.NET Core(多平台)项目和一个 ClassLibrary,用于使用 VS2017 管理 SQL Server 数据库模型。

实际上我们在生产服务器中有一个数据库,我需要使用 dotnet ef dbcontext scaffold [arguments] [options] ... 命令行生成类,但是我需要在创建 DbContext 类时单数化类名。

请,需要帮助!谢谢

【问题讨论】:

  • 我从未这样做过,但我猜您将需要更新 T4 模板文件。它本质上是编写文件的说明。它是告诉代码为类文件创建什么的代码。如果您更新它可能相当于找到遍历表的循环,而不是为每个表创建一个文件,只需将一个类附加到单个文件。或者,您可以创建所有文件,然后创建一个售后应用程序,然后将它们混合到一个文件中。无论哪种方式都足够了。
  • 你能告诉我VS2017中T4模板文件的路径吗,我找到了路径C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\ItemTemplates\CSharp\Data,但是有几个文件夹在其中 tt 文件具有相同的名称
  • 没什么复杂的。当您创建实体文件(edmx)文件时。你有几个层次。有文件、说明((名称).context.tt 和(名称).tt)以及创建的文件。您需要扩展您的 edmx 文件并更新 (name).tt 文件以获得您想要的内容。但是你需要学习一点T4语言。请注意,您可能会在这条路线上严重破坏现有代码,因此请小心并进行备份。您也可以组成第二个 T4 来运行。这是一个链接:msdn.microsoft.com/en-us/library/…
  • 我通过实现 IDesignTimeServices 找到了替代方案,如romiller.com/2017/02/10/… 中所述,但是,没有很好地解释如何与 Scaffold-DbContext 或 dotnet ef dbcontext ...命令一起使用。有人知道哪种参数适用于这种实现吗?
  • 直截了当的文章meziantou.net/2017/06/26/…

标签: c# entity-framework asp.net-core ef-database-first


【解决方案1】:

我找到了解决办法!

最好的解决方案是实现 IDesignTimeServices 接口并使用https://romiller.com/2017/02/10/ef-core-1-1-pluralization-in-reverse-engineer/ 中解释的变形器工具。

要实施这样的解决方案,DesignTimeServiceDbContextWriterModelConfigurationRelationalScaffoldingModelFactory 自定义类和Inflector 类必须驻留在Startup 类所在的启动项目中。使用包管理器控制台执行以下命令:

Install-Package Microsoft.EntityFrameworkCore.Design 

Install-Package Microsoft.EntityFrameworkCore.Tools

在 Scaffold 过程中,Entity Framework Design 会在 Startup 项目中搜索任何实现 IDesignTimeServices 的类并执行其代码。

使用包管理器控制台根据需要执行以下命令替换值,请记住,如果需要将 Database First 进程中的模型类存储到其他项目(例如类库)中,请事先在 Visual Studio 包管理器中选择它控制台:

Scaffold-DbContext -provider Microsoft.EntityFrameworkCore.SqlServer -connection "<connection string here...>" -Context MyDbContext -OutputDir "folder path" -StartupProject MyMainProject -Force

就是这样,单一化和所需的任何定制都非常完美!

感谢 cmets 提供的帮助!

更新:

最近的 Entity Framework Core 2.0 版本改进了 Singularization/Pluralization 过程,避免了 DbContextWriter、ModelConfiguration 和 RelationalScaffoldingModelFactory 实现的要求,通过一个名为 IPluralizer 的新接口使这个过程更简单,您可以在实现 Pluralize 和 Singularize 方法的类中使用该接口.

需要安装 Microsoft.EntityFrameworkCore.Design、Microsoft.EntityFrameworkCore.Tools 和 Microsoft.EntityFrameworkCore.SqlServer 的相同包,如果您希望在您的解决方案中使用此数据库,但现在实现 IDesignTimeServices 的类只需要实现 IPluralizer 的类一个简单的方法:

public class CustomDesignTimeService : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
                => serviceCollection.AddSingleton<IPluralizer, CustomPluralizer>();
}

最后,CustomPluralizer 只是使用 Inflector 工具类方法:

public class CustomPluralizer : IPluralizer
{
    public string Pluralize(string identifier)
    {
        return Inflector.Pluralize(identifier) ?? identifier;
    }

    public string Singularize(string identifier)
    {
        return Inflector.Singularize(identifier) ?? identifier;
    }
}

如果您不想使用 Inflector 类,只需实现您自己的 Pluralize/Singularize 代码。

这就是我在新的 ASP.NET Core 2.0 项目中必须做的所有事情。希望对您有所帮助!

【讨论】:

  • 这应该是实体框架核心的默认行为,或者至少是 Scaffold-DbContext 命令上的一个选项(-pluralize?)
  • Inflector 也不适用于 .NET Core。您必须将代码从 raw.githubusercontent.com/markrendle/Inflector/master/Inflector/… 复制到您的项目中
  • 是的,将源代码复制到新的类文件中,在 .net core 中效果很好。
  • 我很好奇,为什么使用 Singularize 方法而不是 Pluralize?我没有特别告诉它使用 Singularize,只是提供了一个实现
  • 运行 Singularize 而不是 Pluralize 的主要原因是因为表名是复数形式的,所以当您运行脚手架命令时,运行 Pluralize 没有意义。但是,当您需要先运行代码时,Pluralize 才有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
  • 1970-01-01
相关资源
最近更新 更多