实体框架核心自定义脚手架

Dži*_*lić 8 c# entity-framework-core

我已经完成了我的SQLServer数据库的脚手架.它会在指定的文件夹中创建POCO对象.我想做的是它从我的基类延伸.我也使用存储库模式,所以我需要在每个实体上都有Id密钥,而且每次我重新填充数据库时我都不想改变它.

脚手架模型示例

public partial class Food
{
     public int Id { get; set; }
     public string Name { get; set; }
     public string Description { get; set; }
     public double Price { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

预期结果:

public partial class Food : EntityBase
{
     public string Name { get; set; }
     public string Description { get; set; }
     public double Price { get; set; }
}

public class EntityBase : IEntityBase
{
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Tor*_*dze 5

您可以使用DbContextWriterEntityTypeWriter来自定义脚手架输出.

在较新版本的实体核心编写器中重命名:

  • DBContextWriter == >> CSharpDbContextGenerator
  • EntityTypeWriter == >> CSharpEntityTypeGenerator

编写一些自定义类型编写器,您可以覆盖所有内容,您将获得自己的代码生成器:

//HERE YOU CAN CHANGE THE WAY TYPES ARE GENERATED AND YOU CAN ADD INTERFACE OR BASE CLASS AS PARENT.
public class CustomEntitiyTypeWriter : EntityTypeWriter
{
    public CustomEntitiyTypeWriter([NotNull] CSharpUtilities cSharpUtilities)
        : base(cSharpUtilities)
    { }

    // Write Code returns generated code for class and you can raplec it with your base class
    public override string WriteCode([NotNull] EntityConfiguration entityConfiguration)
    {
        var classStr = base.WriteCode(entityConfiguration);

        var defaultStr = "public partial class " + entityConfiguration.EntityType.Name;
        var baseStr = "public partial class " + entityConfiguration.EntityType.Name + " : EntityBase";

        classStr = classStr.Replace(defaultStr, baseStr);

        return classStr;
    }      
}
Run Code Online (Sandbox Code Playgroud)

在设置中声明它:

public static void ConfigureDesignTimeServices(IServiceCollection services)
           => services.AddSingleton<EntityTypeWriter, CustomEntitiyTypeWriter>();
Run Code Online (Sandbox Code Playgroud)

然后使用scaffold db,你可以使用CustomDBContextWriter为DBContext做同样的事情.

  • 如果我有一个单独的DAL库,其中DbContext是使用软件包管理器控制台中的Scaffold-DbContext命令生成的,该如何使用?在这种情况下,我没有任何启动文件... (3认同)
  • 这些链接不再有效? (2认同)

Chr*_*ock 5

@Tornike Choladze的出色答案将我引向了正确的方向,但是在最新版本的.Net Core(2.0>)中,就设置而言,这样做似乎必须有所不同。

自定义实体类型生成器:

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

    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);
    }
}
Run Code Online (Sandbox Code Playgroud)

设置由一个在同一程序集中并实现的类组成IDesignTimeServices

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


Dav*_*idC 5

如果您想修改实体名称(以及文件和类名称),以下内容可能会有所帮助:

根据 Chris Peacock 的回答(和评论),您可以构建两个类来修改实体和文件的名称(这适用于 Core 2.2)。

public class CustomEFUtilities : CSharpUtilities
{
    public override string Uniquifier(
        string proposedIdentifier, ICollection<string> existingIdentifiers)
    {
        var finalIdentifier = base.Uniquifier(proposedIdentifier, existingIdentifiers);
        
        // your changes here
        if (finalIdentifier.StartsWith("tl"))
        {
            finalIdentifier = finalIdentifier.Substring(2);
        }
        
        return finalIdentifier;
    }
}
Run Code Online (Sandbox Code Playgroud)

同样:

public class CustomEFDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddSingleton<ICSharpUtilities, CustomEFUtilities>();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑(EF 核心 3.1)

引入了重大更改(https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/break-changes#microsoftentityframeworkcoredesign-is-now-a-developmentdependency- package ) 所以你需要修改你的项目文件:

如果需要引用此包以覆盖 EF Core 的设计时行为,则可以更新项目中的 PackageReference 项元数据。

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
  <PrivateAssets>all</PrivateAssets>
  <!-- Remove IncludeAssets to allow compiling against the assembly -->
  <!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
</PackageReference>
Run Code Online (Sandbox Code Playgroud)