【发布时间】:2018-01-21 01:45:29
【问题描述】:
我正在研究一种通过 EF Core 为表集合播种的机制。如何按外键依赖的顺序对 DbContext 的实体进行排序?由于某些表具有外键,因此某些表需要在其他表之前播种。似乎有一个简单的 API 可以执行这种排序,但我所能找到的只是几个复杂的递归 T-SQL 实现。
我确信对于这种普遍存在的问题有一个通用的解决方案,我只是无法找到它/不知道如何搜索它。
更新:
因为 EF Core 似乎还不支持Merge/Upsert/AddOrUpdate,所以我将沿着特定于数据库(在本例中为 MySQL 系列)的原始 SQL 查询的路径前进。所以,我有一个像下面这样的方法,我想调用一个实体集合,但是我需要按照TEntityType 的外键依赖关系的顺序调用这个方法。由于它是原始 SQL 查询而不是 EF API,因此我认为 EF 不能以正确的依赖顺序自动神奇地更新表(响应 @Gert's comment)。
private static void InsertOnDuplicateKeyUpdate<TEntityType>(DbContext dbContext) where TEntityType : class
{
var entityType = dbContext.Model.FindEntityType(typeof(TEntityType));
var properties = GetPropertiesLessValueGeneratedTimestamps(entityType);
var columns = string.Join(", ", properties.Select(x => x.Name));
var values = CreateValues<TEntityType>(properties);
var updates = CreateUpdates(properties);
var rawSqlString = "INSERT INTO " + entityType.Relational().TableName + " (" + columns + ") VALUES " +
values + " ON DUPLICATE KEY UPDATE " + updates;
dbContext.Set<TEntityType>().FromSql(rawSqlString);
dbContext.SaveChanges();
}
【问题讨论】:
-
你能发布代码或解释你到目前为止所尝试的吗?你有任何错误吗?
-
这里没有 API,你只需要了解你的实体模型并按照正确的顺序编写你的种子代码。
-
谢谢,@DavidG。这就是我害怕的答案。我真的希望有一些更自动化的东西,每次添加新实体时我都不必碰我的种子算法(这应该是不常见的,当然)。
-
当您将所有相关条目(设置了正确的 FK/导航属性)添加到上下文时,EF 对这些插入的顺序有两个非常简单的规则: 1. 首先插入父条目类型,因此没有在上下文中失败的 FK 约束将在数据库中失败, 2. 在此类排序中,如果 PK 类型实现 IComparable,则首先插入较低的 PK 值。至少在 EF6 之前是这种情况,我不明白他们为什么会为核心关闭它。
-
@DevilSuichiro 这意味着:EF 为您服务。 Collin:只需将实体添加到您的上下文中,确保它们之间具有正确的引用,EF 将计算出插入/更新/删除顺序。
标签: entity-framework foreign-keys .net-core relational-database entity-framework-core