Эшафот EF Основные объекты с интерфейсом - PullRequest
0 голосов
/ 05 июня 2019

Я использую Основные средства Entity Framework для создания сущностей и 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 Offer я создал CSharpEntityTypeGenerator и IDesignTimeServices Принятый ответ недействителен для 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 сборке, которая не является проектом запуска.

В консоли диспетчера пакетов я снова выполнил команду scaffolding. Однако я не вижу сгенерированные объекты имеют базовый класс.

Как фреймворк для скаффолдинга узнает, как использовать мой собственный генератор? Я добавляю генератор в serviceCollection, но похоже, что код никогда не выполняется

Я что-то упустил?

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Для этого вы можете использовать EF Core Power Tools с шаблонами Handlebars.

https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering#customize-code-using-handlebars

0 голосов
/ 06 июня 2019

Я думаю, что эти опции должны были быть предоставлены как часть инструмента EF Scaffolding по умолчанию.

Но вот мой код.Я использую Microsoft.EntityFrameworkCore.Design 2.2.4 и Microsoft.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);
    }
}

По умолчанию строительные лесагенерирует классы с тем же именем, что и имя таблицы.В нашем случае имена таблиц Pluralize, но нам нужно имя класса Singularize.Таким образом, вы должны реализовать Microsoft.EntityFrameworkCore.Design.IPluralizer.Я использовал утилиту Inflator .Тем не менее, обратите внимание, что я не мог добавить Inflector, используя Nuget в проекте .Net Core.Похоже, он пока не поддерживает .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>();
    }
}
...