EF6 Code First:使用自引用进行数据播种
EF6 Code First : Data Seeding with self reference
目标
在我的 table 中有根记录,它引用自己作为其父项。
背景信息
我通常使用 EF Core,所以使用
一切都非常简单
modelBuilder.Entity<Type>().HasData(...);
但是我似乎无法让它与 EF6 Code First 一起使用。
不幸的是,我无法迁移到 EF Core,因为该项目的目标是 .NET Framework 4.8(我无法更改)。
不幸的是,下面提供的代码不能像我希望的那样工作。
型号
[Table("PS_CONTAINERS")]
public class PasswordContainer
{
public int Id { get; set; }
public DateTime DateCreate { get; set; } = DateTime.Now;
public DateTime DateModified { get; set; } = DateTime.Now;
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public string DisplayName { get; set; }
public int? ParentContainerId { get; set; }
[ForeignKey("ParentContainerId")]
public PasswordContainer ParentContainer { get; set; }
public ICollection<PasswordContainer> ChildContainers { get; set; }
}
DbContext
public class SqlDbContext : DbContext
{
public DbSet<PasswordContainer> Containers { get; set; }
public DbSet<PasswordEntry> Passwords { get; set; }
public SqlDbContext(string connectionString) : base(connectionString) {
Database.SetInitializer(new CobraDbContextInitializer());
}
}
初始化器
public class SqlDbContextInitializer : DropCreateDatabaseIfModelChanges<SqlDbContext>
{
protected override void Seed(SqlDbContext context)
{
// add default container without referencing itself
var defaultContainer = new PasswordContainer()
{
Id = 0,
DateCreate = DateTime.Now,
DateModified = DateTime.Now,
CreatedBy = "System",
ModifiedBy = "System",
DisplayName = "System"
};
context.Containers.Add(defaultContainer);
context.SaveChanges();
// get it again and update it with reference to itself
var addedContainer = context.Containers.Find(0);
addedContainer.ParentContainer = addedContainer;
context.SaveChanges();
base.Seed(context);
}
}
正如@Damien_The_Unbeliever 和@BradleyUffner 所评论的那样,让对象引用本身表明它是根对象实际上不是合适的方式。
将父元素设置为 null
作为根元素的指示是一种众所周知的模式。
目标
在我的 table 中有根记录,它引用自己作为其父项。
背景信息
我通常使用 EF Core,所以使用
modelBuilder.Entity<Type>().HasData(...);
但是我似乎无法让它与 EF6 Code First 一起使用。
不幸的是,我无法迁移到 EF Core,因为该项目的目标是 .NET Framework 4.8(我无法更改)。
不幸的是,下面提供的代码不能像我希望的那样工作。
型号
[Table("PS_CONTAINERS")]
public class PasswordContainer
{
public int Id { get; set; }
public DateTime DateCreate { get; set; } = DateTime.Now;
public DateTime DateModified { get; set; } = DateTime.Now;
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public string DisplayName { get; set; }
public int? ParentContainerId { get; set; }
[ForeignKey("ParentContainerId")]
public PasswordContainer ParentContainer { get; set; }
public ICollection<PasswordContainer> ChildContainers { get; set; }
}
DbContext
public class SqlDbContext : DbContext
{
public DbSet<PasswordContainer> Containers { get; set; }
public DbSet<PasswordEntry> Passwords { get; set; }
public SqlDbContext(string connectionString) : base(connectionString) {
Database.SetInitializer(new CobraDbContextInitializer());
}
}
初始化器
public class SqlDbContextInitializer : DropCreateDatabaseIfModelChanges<SqlDbContext>
{
protected override void Seed(SqlDbContext context)
{
// add default container without referencing itself
var defaultContainer = new PasswordContainer()
{
Id = 0,
DateCreate = DateTime.Now,
DateModified = DateTime.Now,
CreatedBy = "System",
ModifiedBy = "System",
DisplayName = "System"
};
context.Containers.Add(defaultContainer);
context.SaveChanges();
// get it again and update it with reference to itself
var addedContainer = context.Containers.Find(0);
addedContainer.ParentContainer = addedContainer;
context.SaveChanges();
base.Seed(context);
}
}
正如@Damien_The_Unbeliever 和@BradleyUffner 所评论的那样,让对象引用本身表明它是根对象实际上不是合适的方式。
将父元素设置为 null
作为根元素的指示是一种众所周知的模式。