- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
你好,我有一个 dotnet 标准库,我在其中使用 EF Core 2.1.1(代码优先方法)来访问持久层。为了创建迁移,我使用了一个单独的 dotnet 核心控制台应用程序(在同一解决方案中),其中包含 IDesignTimeDbContextFactory<T>
实现。
有必要播种一些数据,我想以一种舒适的方式实现它,因为将来要播种的数据将被扩展或修改。因此在实现IEntityTypeConfiguration
我使用扩展方法 .HasData()
它获取要播种的对象数组。该数组将由一个单独的类 ( TemplateReader
) 提供,该类从 JSON 文件加载对象(将在其中完成扩展和修改工作)。因此,可以修改 JSON 文件的内容并添加一个新的迁移,该迁移将包含生成的代码到插入(modelBuilder.InsertData()
)、更新(modelBuilder.UpdateData()
)或删除(modelBuilder.DeleteData()
)语句。
因为我不会发送 JSON 文件并且我想避免加载序列化数据以进行播种和执行 .HasData()
, 我想用 bool
将赋予 DbContext
的值由构造函数。
为了避免在不需要为迁移调用种子设定(和 .HasData()
)时使用 bool 值,我有一个重载的构造函数,它使用默认值 false 实现。此外,我不会使用 OnConfiguring
因为我想灵活地设置DbContextOptions<T>
在我的 IoC 容器中或单独进行测试的对象。
以下代码包含重命名的变量,以更加匿名地描述项目内容,但代表当前实现的逻辑。
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);
}
}
MyDbContext:
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);
}
}
}
模板(实体):
public class Template
{
public int Id { get; set; }
public string ModuleKey { get; set; }
public string Html { get; set; }
public virtual ICollection<Content> Contents { get; set; }
}
据我所知,我已经测试了 OnModelCreating(ModelBuilder)
将在构造函数中设置构造函数的 bool 值之前调用 ( _shouldSeedData = shouldSeedData;
)。那是因为 base constructor 将被立即调用,然后是我的。因此 _shouldSeedData
的值为 false
什么时候给TemplateTypeConfiguration
.
正因为如此,一个 Add-Migration
如果我对上述 JSON 文件进行了任何修改,则会导致没有任何逻辑的“空”迁移。
我已经尝试使用 IModelCacheKeyFactory
拥有自己的ModelCacheKey
没有任何成功的对象。作为模板,我使用了这个 SO-question .
我测试的另一种方法是设置 _shouldSeedData
作为public static
变量并从 MyDesignTimeDbContextFactory
设置它至 true
,但在我看来,这是一个非常肮脏的解决方案,我想避免在生产代码中实现。
应该也可以使用 DbContextOptionsBuilder<T>
的 UseModel(IModel)
避免使用 OnModelCreating
的扩展方法并初始化 TemplateTypeConfiguration
需要 shouldSeedData = false
.这种方法的一个缺点是有重复的代码,这些代码在 TemplateTypeConfiguration
中会有所不同。的构造函数值。在我看来,与公共(public)静态方法一样令人讨厌。
是否有一个干净的解决方案来实现设置 _shouldSeedData
通过 OnModelCreating
的构造函数可以在设计时以正确的值 ( true
) 使用它吗?
在生产中它应该是false
并提到 TemplateReader
在TemplateTypeConfiguration
由于 if 条件,不应调用。
最佳答案
OnModelCreating
不是 由基本 DbContext
构造函数调用触发,因此保存传递给类成员的参数绝对没有问题。
在您的具体场景中,OnModelCreating
是通过在存储传递的参数之前访问 ChangeTracker
属性触发的:
public MyDbContext(DbContextOptions<MyDbContext> options, bool shouldSeedData = false) :
base(options)
{
ChangeTracker.LazyLoadingEnabled = false; // <--
_shouldSeedData = shouldSeedData;
}
只需交换线路即可解决问题。通常,始终在访问任何上下文属性之前初始化您的类成员。
关于c# - EF Core 2.1 中的动态数据播种迁移生成取决于在 OnModelCreating() 中使用的 DbContext bool-flag,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51168127/
从 PHP7 开始,为 PRNG 引入了一个新函数:random_int ( http://php.net/manual/en/function.random-int.php ) PHP 手册中没有与
在 .net 核心项目中,我像这样在 Program.cs 文件中播种: var host = BuildWebHost(args); using (var scope = host.Services
我有一张谷歌地图,上面有大约 200 个标记。使用谷歌距离矩阵服务,我可以找到从一个地址到 map 上所有标记的行驶距离。由于 API 限制,我每次调用只能提交 25 个目的地,因此我必须将操作分解为
下面的脚本抛出错误(自定义字段未定义)。我需要以不同的方式传递元素 ID 吗? 我正在尝试使用我要计算的表单字段来为数组播种。它应该迭代数组中的每个表单字段,并用表单元素的值递增 sum 变量。 jQ
我正在学习“Laravel 5 Essentials”中的教程。当我尝试使用命令为我的数据库播种时 php artisan db:seed 我收到错误 [ReflectionException]
我正在关注 docs为 users 表设置种子,该表显示正在使用 User::create class UserTableSeeder extends Seeder { public func
让我首先说明我要完成的任务: 我需要在一定范围内随机生成一组数字 我希望这些数字稍微均匀分布 我需要能够为随机数生成播种,这样,给定一个种子,生成的随机数将始终相同。 在对 drand48()、ran
这个问题在这里已经有了答案: Recommended way to initialize srand? (15 个答案) 关闭 9 年前。 我学习的方法是最初使用 srand(time(NULL))
SQLite 是否支持播种 RANDOM() 的功能与 MySQL 对 RAND() 的处理方式相同? $query = "SELECT * FROM table ORDER BY RAND(" .
我正在使用不支持的 Visual Studio 2010 ,所以我必须播种 default_random_engine .因此,我决定用 rand 播种它如下 srand((unsigned int
在 google OR-tools 库中,“原始”CP-Solver(此处讨论: https://developers.google.com/optimization/cp/original_cp_s
我正在尝试为 AspNetRole 表设置初始系统角色。 播种扩展: public static void EnsureRolesAreCreated(this IApplicationBuilder
我似乎无法弄清楚如何使用 Sequelize 为 ARRAY(ENUM) 播种。当我通过我的应用程序注册用户时,我可以很好地创建一个新用户,但是当我在种子文件中使用 queryInterface.bu
以下代码应创建两个具有相同种子的 Random 对象: System.out.println("System time before: " + System.currentTimeMillis());
尝试从集合中选择伪随机元素时,我看到了非确定性行为,即使 RNG 已播种(示例代码如下所示)。为什么会发生这种情况,我是否应该期望其他 Python 数据类型表现出类似的行为? 注意:我只在 Pyth
关于在 openssl/bn.h 中使用 BN_generate_prime 生成质数的内容,我无法找到答案。另外,我将如何播种此函数使用的任何 PRNG? 单独的问题但与我的代码相关(我正在编写一个
所以,我是 MEAN 堆栈的新手,我在尝试播种 MongoDB 时碰壁了。我正在使用 Mongoose 与数据库进行通信,并且有一堆文档建议我应该能够使用填充的 JSON 文件进行播种。 我尝试过的:
我有一个非常简单的情况:我想使用 testcontainers 测试 AWS 中现有的 mysql 数据库。 我遵循了官方指南( https://www.testcontainers.org/modu
我有一个很长(500K+ 行)的两列电子表格,如下所示: Name Code 1234 A 1234 B 1456 C 4556 A 4556 B 4556
我有一个要播种的数据透视表。除了 PK 和 FK,该表还包含另外两列:Arrival & Departure(类型:时间戳)。我正在使用 Carbon 随机填充前面的列。这是我的代码: $faker
我是一名优秀的程序员,十分优秀!