使用接口为 EF Core 实体构建脚手架

5

我正在使用Entity Framework Core工具从现有数据库创建实体和DBContext。

Scaffold-DbContext "Server=XXXXXX;Database=MyDB;User ID=xxxx;Password=xxxxxxx" Microsoft.EntityFrameworkCore.SqlServer -ContextDir .-OutputDir Entities -Force

这个正在工作。但是有没有什么方法可以用已知接口脚手架所有实体?所以我有一个接口IEntityBase,我希望所有实体都有这个接口。
注意 这个问题特定于EF Core 2+和脚手架
更新1 根据SO建议,我创建了CSharpEntityTypeGeneratorIDesignTimeServices。 接受的答案对于EF Core > 2.*无效,因此我正在使用@Chris Peacock的建议。
public class MyEntityTypeGenerator: CSharpEntityTypeGenerator
{
    public MyEntityTypeGenerator(ICSharpHelper cSharpHelper)
        : base(cSharpHelper)
    {
    }

    public override string WriteCode(IEntityType entityType, string @namespace, bool useDataAnnotations)
    {
        string code = base.WriteCode(entityType, @namespace, useDataAnnotations);

        var oldString = "public partial class " + entityType.Name;
        var newString = "public partial class " + entityType.Name + " : EntityBase";

        return code.Replace(oldString, newString);
    }
}


public class MyDesignTimeServices: IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddSingleton<ICSharpEntityTypeGenerator, MyEntityTypeGenerator>();
    }
}

我需要做一个更改。 CSharpEntityTypeGenerator 构造函数的参数应该是 ICSharpHelper,而不是 ICSharpUtilities

这两个类在 Data 程序集中,不属于启动项目。

在“程序包管理器控制台”中再次执行脚手架命令,但是我发现生成的实体没有基类。

脚手架框架如何知道使用我的自定义生成器?我将生成器添加到了 serviceCollection 中,但似乎代码从未被执行过。

我有什么遗漏吗?


@AdamVincent 这不是重复的问题。我的问题与 .net core 有关,并且特定于使用 EF Core 工具进行脚手架。至少它不同于您链接的内容。 - LP13
只是为了明确,您希望脚手架操作在从数据库生成的所有类上附加“..:IEntityBase”吗? - Adam Vincent
可能是Entity Framework Core自定义脚手架的重复问题。 - Jan Paolo Go
@AdamVincent 是的,但 .net core 使用 EF Core。 - LP13
2个回答

3

我已经下载了Power Tool,但它默认不支持添加基类/接口。正如你所提到的,我必须使用Handlebars。我决定坚持C#的方法:)。如果Power Tool能够提供一个文本框来输入基类或接口名称,我将不得不使用它。对于更复杂的自定义,可以使用Handlebars。 - LP13

2
我认为这些选项本应该作为 EF Scaffolding 工具的默认部分提供。

但这是我的代码。我正在使用 Microsoft.EntityFrameworkCore.Design 2.2.4Microsoft.EntityFrameworkCore.SqlServer 2.2.4,根据我在 .NET Core 上的经验,这可能会在未来的版本中更改。

CSharpEntityTypeGenerator

public class MyEntityTypeGenerator: CSharpEntityTypeGenerator
{
    public MyEntityTypeGenerator(ICSharpHelper cSharpUtilities)
        : base(cSharpUtilities)
    {
    }

    public override string WriteCode(IEntityType entityType, string @namespace, bool useDataAnnotations)
    {
        Console.WriteLine(entityType.Name);

        string code = base.WriteCode(entityType, @namespace, useDataAnnotations);

        var oldString = "public partial class " + entityType.Name;
        var newString = "public partial class " + entityType.Name + " : EntityBase";

        return code.Replace(oldString, newString);
    }
}

默认情况下,脚手架生成的类与表名相同。在我们的例子中,表名是复数形式,但我们想要类名是单数形式。因此,您需要实现Microsoft.EntityFrameworkCore.Design.IPluralizer。我使用了Inflator工具。但请注意,我无法在.NET Core项目中使用Nuget添加Inflector。看起来它还不支持.NET Core。因此,我已经在我的项目中添加了单个代码文件

IPluralizer

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

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

IDesignTimeServices
您需要将此类添加到启动项目中。最初,我将此类放在与其他类相同的项目中,但那并没有起作用。我将此类移动到启动项目中(在我的情况下是ASP.NET Core项目),然后它正常工作了。

public class MyDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        // Start debugger
        System.Diagnostics.Debugger.Launch();
        serviceCollection.AddSingleton<ICSharpEntityTypeGenerator, MyEntityTypeGenerator>();
        serviceCollection.AddSingleton<IPluralizer, MyPluralizer>();
    }
}

请注意,EFCore 3 中的复数形式已经发生了变化,我自己也刚开始研究它,但以下链接可能对大家有用-https://github.com/dotnet/efcore/issues/17401 - d219
特别是“您需要将此类添加到启动项目中。最初,我将此类放在与其他类相同的项目中,但那样不起作用。我将此类移动到启动项目中(在我的情况下,这是ASP.NET Core项目),它也对我起作用了。” - Mustafa

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