【问题标题】:EF6 Code First : Data Seeding with self referenceEF6 代码优先:具有自我参考的数据播种
【发布时间】:2021-09-27 23:18:19
【问题描述】:

目标
在我的表中有一个根记录,它引用自己作为其父项。

背景信息
我通常使用 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 使用可为空的属性只是让它工作的另一种尝试。不知何故感觉……对我来说错了,使用 null 作为根元素。感觉有更好(或正确)的方法来做到这一点。但是你会建议只用 null 来标记我的根元素?
  • 我见过的大多数树结构的实现都使用null 作为Parent 来表示根节点。这是一种非常常见且易于理解的模式。另一方面,我个人从未参与过Parent 将其自身作为根标志的项目。我会觉得这很混乱。
  • @BradleyUffner 明白了。然后我会适应这种模式。谢谢你的好先生。

标签: c# entity-framework seeding .net-framework-4.8


【解决方案1】:

正如@Damien_The_Unbeliever 和@BradleyUffner 所评论的,拥有一个对象引用本身表明它是根对象实际上不是合适的方式。

将父级设置为null 作为根元素的指示是一种众所周知的模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    相关资源
    最近更新 更多