Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF Core 2.1中的动态数据种子迁移生成取决于DbContext bool标志,在OnModelCreating()中使用 现状_C#_Entity Framework_Ef Code First_Entity Framework Core_Ef Core 2.1 - Fatal编程技术网

C# EF Core 2.1中的动态数据种子迁移生成取决于DbContext bool标志,在OnModelCreating()中使用 现状

C# EF Core 2.1中的动态数据种子迁移生成取决于DbContext bool标志,在OnModelCreating()中使用 现状,c#,entity-framework,ef-code-first,entity-framework-core,ef-core-2.1,C#,Entity Framework,Ef Code First,Entity Framework Core,Ef Core 2.1,您好,我有一个dotnet标准库,其中我使用efcore2.1.1(代码优先方法)访问持久层。要创建迁移,我使用一个单独的dotnet核心控制台应用程序(在同一个解决方案中),该应用程序包含一个IDesignTimeDbContextFactory实现。 有必要对一些数据进行种子设定,我希望以一种舒适的方式实现它,因为将来要进行种子设定的数据将被扩展或修改。因此,在implementedientitypeconfiguration中,我使用扩展方法.HasData(),它获取一个要种子化的对象数

您好,我有一个dotnet标准库,其中我使用efcore2.1.1(代码优先方法)访问持久层。要创建迁移,我使用一个单独的dotnet核心控制台应用程序(在同一个解决方案中),该应用程序包含一个
IDesignTimeDbContextFactory
实现。
有必要对一些数据进行种子设定,我希望以一种舒适的方式实现它,因为将来要进行种子设定的数据将被扩展或修改。因此,在implemented
ientitypeconfiguration
中,我使用扩展方法
.HasData()
,它获取一个要种子化的对象数组。该数组将由一个单独的类(
TemplateReader
)提供,该类从一个JSON文件加载对象(将在该文件中完成扩展和修改工作)。因此,可以修改JSON文件的内容并添加新的迁移,该迁移将包含要插入(
modelBuilder.InsertData()
)、更新(
modelBuilder.UpdateData()
)或删除(
modelBuilder.DeleteData()
)语句的生成代码。
由于我不会发布JSON文件,并且我希望避免加载序列化数据以进行种子设定和执行
.HasData()
,因此我希望使用构造函数将赋予
DbContext
bool
值。
为了避免在不需要调用移植种子时使用bool值(以及
.HasData()
),我使用默认值false实现了一个重载构造函数。 此外,我不会使用
onconfigurang
,因为我希望能够灵活地在IoC容器中设置
DbContextOptions
对象或单独设置测试


代码 下面的代码包含重命名的变量,以便对项目的内容更加匿名,但表示当前实现的逻辑

MyDesignTimeDbContextFactory

public class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
    public MyDbContext CreateDbContext(string[] args)
    {
        var connectionString = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

        var contextOptionsBuilder = new DbContextOptionsBuilder<MyDbContext>()
            .UseSqlServer(connectionString);

        return new MyDbContext(contextOptionsBuilder.Options, true);
    }
}
public sealed class MyDbContext : DbContext
{
    private readonly bool _shouldSeedData;


    public DbSet<Content> Contents { get; set; }

    public DbSet<Template> Templates { get; set; }


    public MyDbContext(DbContextOptions<MyDbContext> options, bool shouldSeedData = false) :
        base(options)
    {
        ChangeTracker.LazyLoadingEnabled = false;

        _shouldSeedData = shouldSeedData;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("mySchema");

        modelBuilder.ApplyConfiguration(new TemplateTypeConfiguration(_shouldSeedData));

        base.OnModelCreating(modelBuilder);
    }
}
public class TemplateTypeConfiguration : IEntityTypeConfiguration<Template>
{
    private readonly bool _shouldSeedData;


    public TemplateTypeConfiguration(bool shouldSeedData)
    {
        _shouldSeedData = shouldSeedData;
    }


    public void Configure(EntityTypeBuilder<Template> builder)
    {
        builder.Property(p => p.ModuleKey)
            .IsRequired();

        builder.Property(p => p.Html)
            .IsRequired();


        if (_shouldSeedData)
        {
            // reads all templates from configuration file for seeding
            var templateReader = new TemplateReader(Directory.GetCurrentDirectory());

            var templates = templateReader.GetTemplates().ToArray();

            builder.HasData(templates);
        }
    }
}
公共类MyDesignTimeDbContextFactory:IDesignTimeDbContextFactory
{
公共MyDbContext CreateDbContext(字符串[]args)
{
var connectionString=ConfigurationManager.connectionString[“SqlServer”].connectionString;
var contextOptionsBuilder=new DbContextOptionsBuilder()
.UseSqlServer(connectionString);
返回新的MyDbContext(contextOptionsBuilder.Options,true);
}
}
MyDbContext

public class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
    public MyDbContext CreateDbContext(string[] args)
    {
        var connectionString = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

        var contextOptionsBuilder = new DbContextOptionsBuilder<MyDbContext>()
            .UseSqlServer(connectionString);

        return new MyDbContext(contextOptionsBuilder.Options, true);
    }
}
public sealed class MyDbContext : DbContext
{
    private readonly bool _shouldSeedData;


    public DbSet<Content> Contents { get; set; }

    public DbSet<Template> Templates { get; set; }


    public MyDbContext(DbContextOptions<MyDbContext> options, bool shouldSeedData = false) :
        base(options)
    {
        ChangeTracker.LazyLoadingEnabled = false;

        _shouldSeedData = shouldSeedData;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("mySchema");

        modelBuilder.ApplyConfiguration(new TemplateTypeConfiguration(_shouldSeedData));

        base.OnModelCreating(modelBuilder);
    }
}
public class TemplateTypeConfiguration : IEntityTypeConfiguration<Template>
{
    private readonly bool _shouldSeedData;


    public TemplateTypeConfiguration(bool shouldSeedData)
    {
        _shouldSeedData = shouldSeedData;
    }


    public void Configure(EntityTypeBuilder<Template> builder)
    {
        builder.Property(p => p.ModuleKey)
            .IsRequired();

        builder.Property(p => p.Html)
            .IsRequired();


        if (_shouldSeedData)
        {
            // reads all templates from configuration file for seeding
            var templateReader = new TemplateReader(Directory.GetCurrentDirectory());

            var templates = templateReader.GetTemplates().ToArray();

            builder.HasData(templates);
        }
    }
}
公共密封类MyDbContext:DbContext
{
私有只读bool_应为种子数据;
公共数据库集内容{get;set;}
公共数据库集模板{get;set;}
公共MyDbContext(DbContextOptions选项,bool shouldSeedData=false):
基本(选项)
{
ChangeTracker.LazyLoadingEnabled=false;
_shouldSeedData=shouldSeedData;
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
hasdaultschema(“mySchema”);
ApplyConfiguration(新的TemplateTypeConfiguration(_shouldSeedData));
基于模型创建(modelBuilder);
}
}
模板类型配置

public class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
    public MyDbContext CreateDbContext(string[] args)
    {
        var connectionString = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

        var contextOptionsBuilder = new DbContextOptionsBuilder<MyDbContext>()
            .UseSqlServer(connectionString);

        return new MyDbContext(contextOptionsBuilder.Options, true);
    }
}
public sealed class MyDbContext : DbContext
{
    private readonly bool _shouldSeedData;


    public DbSet<Content> Contents { get; set; }

    public DbSet<Template> Templates { get; set; }


    public MyDbContext(DbContextOptions<MyDbContext> options, bool shouldSeedData = false) :
        base(options)
    {
        ChangeTracker.LazyLoadingEnabled = false;

        _shouldSeedData = shouldSeedData;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("mySchema");

        modelBuilder.ApplyConfiguration(new TemplateTypeConfiguration(_shouldSeedData));

        base.OnModelCreating(modelBuilder);
    }
}
public class TemplateTypeConfiguration : IEntityTypeConfiguration<Template>
{
    private readonly bool _shouldSeedData;


    public TemplateTypeConfiguration(bool shouldSeedData)
    {
        _shouldSeedData = shouldSeedData;
    }


    public void Configure(EntityTypeBuilder<Template> builder)
    {
        builder.Property(p => p.ModuleKey)
            .IsRequired();

        builder.Property(p => p.Html)
            .IsRequired();


        if (_shouldSeedData)
        {
            // reads all templates from configuration file for seeding
            var templateReader = new TemplateReader(Directory.GetCurrentDirectory());

            var templates = templateReader.GetTemplates().ToArray();

            builder.HasData(templates);
        }
    }
}
公共类TemplateTypeConfiguration:IEntityTypeConfiguration
{
私有只读bool_应为种子数据;
公共模板类型配置(bool shouldSeedData)
{
_shouldSeedData=shouldSeedData;
}
公共void配置(EntityTypeBuilder)
{
builder.Property(p=>p.ModuleKey)
.IsRequired();
属性(p=>p.Html)
.IsRequired();
如果(_shouldSeedData)
{
//从配置文件中读取所有模板以进行种子设定
var templateReader=newtemplatereader(Directory.GetCurrentDirectory());
var templates=templateReader.GetTemplates().ToArray();
HasData(模板);
}
}
}
模板(实体):

公共类模板
{
公共int Id{get;set;}
公共字符串ModuleKey{get;set;}
公共字符串Html{get;set;}
公共虚拟ICollection内容{get;set;}
}

问题 据我所知,并且我已经测试了
OnModelCreating(ModelBuilder)
将在构造函数中设置构造函数的bool值之前被调用(
\u shouldseddata=shouldsedseeddata;
)。这是因为将立即调用基本构造函数,然后调用我的构造函数。因此,
\u应该将种子数据
的值设置为
false
,然后将其放入
模板类型配置

因此,如果我对上述JSON文件进行了任何修改,那么
Add迁移
将导致没有任何逻辑的“空”迁移


已经测试过的方法 我已经尝试将
IModelCacheKeyFactory
与自己的
ModelCacheKey
对象一起使用,但没有成功。作为模板,我使用了这个

我测试的另一种方法是将
\u shouldSeedData
设置为
公共静态
变量,并将其从
MyDesignTimeDbContextFactory
设置为
true
,但在我看来,这是一个非常肮脏的解决方案,我希望避免在生产代码中实现

还可以使用
DbContextOptionsBuilder
UseModel(IModel)
扩展方法,以避免在使用所需的
shouldsededata=false
创建模型和初始化
TemplateTypeConfiguration
时使用
。这种方法的一个缺点是有重复的代码,这些代码在
TemplateTypeConfiguration
的构造函数值中会有所不同。在我看来,这就像公众的静态方法一样令人讨厌


问题: 是否有一个干净的解决方案来实现由构造函数设置
\u shouldSeedData
,从而在模型创建时
可以在设计时使用正确的值(
true