Can the Linq `Where` query result be different depending on whether the query is being executed lazily or not lazily?

The following is a simplified code for my code. I would expect that p1, and p2will be equal to, as well p1_after, and p2_afterare, given that the only difference between the GetPerson1()and GetPerson2()- the proposal .ToList(), compulsory execution of the request, without any change in the selection criteria.

Is my assumption wrong? I found an error in my program that boils down to p1_afterand p2_afterwhich are different ( p2_afterit is null, as expected, because the age was changed to 26. But p1_afterit still contains the same instance as p1).

Is this normal behavior? It seems illogical to me, so I would like to check. Moreover, it p1_after.Agereturns 26, despite the fact that it p1_afterwas chosen so that it Ageis equal to 25.

    public void OnGet()
    {
        Person p1 = GetPerson1();
        Person p2 = GetPerson2();

        p1.Age = 26;
        p2.Age = 26;

        Person p1_after = GetPerson1(); // not null, but p1_after.Age is 26
        Person p2_after = GetPerson2(); // null
    }

    public Person GetPerson1()
    {
        return _context
            .Persons
            .Where(p => p.Age == 25)
            .SingleOrDefault();
    }

    public Person GetPerson2()
    {
        return _context
            .Persons
            .ToList()
            .Where(p => p.Age == 25)
            .SingleOrDefault();
    }
+4
source share
1 answer

This is a wild guess, but I have an idea why your program behaves like this.

After you changed the age, you did not call any methods SaveChanges/ SaveChangesAsyncso that your changes were not reflected in the database and only local residents in your code.

, GetPerson1, , 25, , , .
GetPerson2 - GetPerson2 ToList, , GetPersons1 , , , GetPerson2 , EntityFramework , , , , , 25, p2_after null.

, :

  • :

    public void OnGet()
    {
        Person p1 = GetPerson1();
        Person p2 = GetPerson2();
    
        p1.Age = 26;
        p2.Age = 26;
    
        _context.SaveChanges();
    
        Person p1_after = GetPerson1();
        Person p2_after = GetPerson2();
    }
    

    , p1_after p2_after ( null), .

  • :

    public void OnGet()
    {
        Person p1 = GetPerson1();
        Person p2 = GetPerson2();
    
        p1.Age = 26;
        p2.Age = 26;
    
        Person p1_after = GetPerson1();
        Person p2_after = GetPerson2();
    }
    
    public Person GetPerson1()
    {
        using(var context = new ...)
        {
            return context
               .Persons
               .Where(p => p.Age == 25)
               .SingleOrDefault();
        }
    }
    
    public Person GetPerson2()
    {
        using(var context = new ...)
        {
            return context
               .Persons
               .ToList()
               .Where(p => p.Age == 25)
               .SingleOrDefault();
        }
    }
    

    , , p1_after p2_after ( p1 p2 ), , , .

  • AsNoTracking:

    public void OnGet()
    {
        Person p1 = GetPerson1();
        Person p2 = GetPerson2();
    
        p1.Age = 26;
        p2.Age = 26;
    
        Person p1_after = GetPerson1();
        Person p2_after = GetPerson2();
    }
    
    public Person GetPerson1()
    {
        return _context
            .Persons
            .AsNoTracking()
            .Where(p => p.Age == 25)
            .SingleOrDefault();
    }
    
    public Person GetPerson2()
    {
        return _context
            .Persons
            .ToList()
            .AsNoTracking()
            .Where(p => p.Age == 25)
            .SingleOrDefault();
    }
    

    , , p1_after p2_after ( p1 p2 ), EF . -

+2

Source: https://habr.com/ru/post/1690129/


All Articles