0

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?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Dilshod K
  • 2,924
  • 1
  • 13
  • 46
  • With Entity there is a mapping between the database tables and the c# classes. When an SaveChanges is performed the data in the c# classes are written to the database. You navigation code is making a copy of the data in the c# classes which is not link to either the original c# classes nor the database. For the reload to work (reads the database values into the c# classes), the changes need to be written to the database. – jdweng Mar 17 '22 at 13:49
  • @jdweng I am not sure that I understood you. But, I am not planning to save context2 here, I want to get updates when I saved context1 – Dilshod K Mar 17 '22 at 16:43
  • You need to update context1 and then save to database. Looks like you are querying database with name that is in context2 : mikeBackpackFromContext2.Student.Name. If context 2 is not saved in database than person is not in the database. – jdweng Mar 17 '22 at 17:21
  • @jdweng That's why I am trying to implement cross-context communication. When context1 is saved, and context2 is not saved yet, I need to refresh entities in context2 – Dilshod K Mar 18 '22 at 04:00
  • You can't refresh if the data isn't saved back to the database. – jdweng Mar 18 '22 at 08:51
  • @jdweng Data is already saved in the database. Look at the code, there is context1.SaveChanges(); – Dilshod K Mar 18 '22 at 08:53
  • But if you add a new student to context2 it does not get saved. The error you are getting is from mikeBackpackFromContext2.Student.Name which means there is a name in contect2 that is not in the database. – jdweng Mar 18 '22 at 09:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243060/discussion-between-dilshod-k-and-jdweng). – Dilshod K Mar 18 '22 at 10:34

0 Answers0