简体   繁体   中英

EF6 Code First : Data Seeding with self reference

Goal
Having a root record in my table, which references itself as its parent.

Background Info
I usually work with EF Core, so everything is pretty straight forward using

modelBuilder.Entity<Type>().HasData(...);

However I can't seem to get it to work with EF6 Code First. Unfortunately I cannot migrate to EF Core, since the project is targeting .NET Framework 4.8 (which I am not able to change).
The code provided below unfortunately doesen't work as I was hoping it would.

Model

[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());
    }
}

Initializer

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);
    }
}

As commented by @Damien_The_Unbeliever & @BradleyUffner, having an object reference itself indicating it is the root object is actually not the suitable way.

It is a well known pattern to have the parent set to null as indication for the root element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM