Creating a double linked list in Entity Framework

entity-framework entity-framework-6

Question

I have an object that has the option of referencing a subsequent or preceding record. Possibly like this:

public class Foo
{
  [Key]
  public int Id {get; set;}

  [ForeignKey("Previous")]
  public int? PreviousId {get; set;}

  public Foo Previous {get; set;}

  [InverseProperty("Previous")]
  public Foo Next {get; set;}
}

Sadly, this does not function and instead produces the error message.Unable to determine the principal end of an association between the types Foo and Foo .

It is intended that by adjusting thePreviousId the BeforeFoo obtain itsNext set by EF automatically. This is to avoid mistakes brought by byNext and Previous syncing up improperly. Also take note ofPreviousId can benull , in which case there should be no records in the database with aNext indicating that record Is there a way to put this into practice?

1
9
6/4/2014 9:36:57 AM

Popular Answer

I was able to accomplish your goal utilizing the fluent api approach. I have to remove the PreiousId field from the Foo class because mapping will add it later.

public class Foo
{
    [Key]
    public virtual int Id { get; set; }

    public virtual Foo Previous { get; set; }

    public virtual Foo Next { get; set; }
}

Additionally, convert all of your properties to virtual so that ef can dynamically monitor the state of the properties in memory. Then you must override the OnModelCreating function inside the DbContext derived class and define mapping there:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Foo>()
        .HasOptional(f => f.Next)
        .WithOptionalPrincipal(f => f.Previous)
        .Map(c => c.MapKey("PreviousId"));

    base.OnModelCreating(modelBuilder);
}

This will increase the PreviousId column's value in the Foo table, which will serve as the relationship's foreign key. The 1-0 relationship will be defined by it. A reference to the assigned entity will appear in the next property if you assign one Foo entity to another's Previous property. I put it to the test using the code below:

using(MyDbContext context = new MyDbContext("Test"))
{
    context.Database.Delete();
    Foo foo1 = context.Foos.Create();
    Foo foo2 = context.Foos.Create();
    foo1.Next = foo2;
    context.Foos.Add(foo1);
    context.Foos.Add(foo2);
    context.SaveChanges();
}
using (MyDbContext context = new MyDbContext("Test"))
{
    Foo foo1 = context.Foos.OrderBy(f => f.Id).First();
    Foo foo2 = context.Foos.OrderBy(f => f.Id).Skip(1).First();
    // foo1.Next == foo2 and foo2.Previous == foo1
}
7
6/4/2014 11:12:22 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow