Cross context communication EF Core

141 Views Asked by At

I have Student and Backpack entities:

internal class Student
{
    public Guid Guid { get; set; }

    public string Name { get; set; }

    ICollection<Backpack> backpacks;

    public virtual ICollection<Backpack> Backpacks
    {
        get
        {
            if (backpacks == null && LazyLoader != null)
            {
                backpacks = LazyLoader.Load(this, ref backpacks);
            }
            return backpacks;
        }
        set
        {
            backpacks = value;
        }
    }

    ILazyLoader LazyLoader;

    public Student(ILazyLoader lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    public Student()
    {
    }
}

internal class Backpack
{
    public Backpack()
    {
    }

    ILazyLoader LazyLoader;

    public Backpack(ILazyLoader lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    public Guid Guid { get; set; }
    public string Name { get; set; }

    Student student;

    public virtual Student Student
    {
        get
        {
            if (student == null && LazyLoader != null)
            {
                student = LazyLoader.Load(this, ref student);
            }
            return student;
        }
        set
        {
            student = value;
        }
    }
}

When an entity is changed and saved from one context and is used in another context, I want to update them. For example:

Scenario 1: when changing primitive properties and saved, I am updating the entry using reload:

    var context1 = new MainContext();
    var studentDilshodFromContext1 = context1.Set<Student>().First(s => s.Name == "Mike");


    var context2 = new MainContext();
    var studentMikeFromContext2 = context2.Set<Student>().First(s => s.Name == "Mike");

    studentMikeFromContext1.Name = "Jake";
    context1.SaveChanges();

    context2.Entry(studentMikeFromContext2).Reload();
    Console.WriteLine(studentMikeFromContext2.Name); //Nice! it is Jake after reloading

Scenario 2: now, I want to change the navigation property:

    var context1 = new MainContext();
    var jakeStudent = context1.Set<Student>().First(s => s.Name == "Jake");
    var mikeBackpackFromContext1 = context1.Set<Backpack>().First(s => s.Name == "Mike's Backpack");
    mikeBackpackFromContext1.Student = jakeStudent;

    var context2 = new MainContext();
    var mikeBackpackFromContext2 = context2.Set<Backpack>().First(s => s.Name == "Mike's Backpack");

    context1.SaveChanges();
    context2.Entry(mikeBackpackFromContext2).Reload();
    Console.WriteLine(mikeBackpackFromContext2.Student.Name); //Object reference exception because Student is null. I am expecting Jake

Scenario 3: when the item was added to the navigation collection property, I would like to see it in context2:

var context1 = new MainContext();
var jakeStudentFromContext1 = context1.Set<Student>().First(s => s.Name == "Jake");
var newBackpack = new Backpack() { Student = jakeStudentFromContext1, Guid = Guid.NewGuid(), Name = "New Jake backpack" };
context1.Add(newBackpack);

var context2 = new MainContext();
var jakeStudentFromContext2 = context2.Set<Student>().First(s => s.Name == "Jake");
var backpacks = jakeStudentFromContext2.Backpacks;

context1.SaveChanges();

context2.Entry(jakeStudentFromContext2).Reload();
Console.WriteLine(jakeStudentFromContext2.Backpacks.Any(d => d.Guid == newBackpack.Guid)); //It is false but I am expecting true

As you can see entry.Reload() working fine only with primitive type properties, but not working with navigation properties. I tried NavigationEntry.Load and CollectionEntry.Load but they are not working as well.

So, in these scenarios how can I re-load my navigation properties?

0

There are 0 best solutions below