Use EF Code First Local extention

104 Views Asked by At

The following method works properly in my service layer:

public override IList<City> GetAll()
 {
           var query = from item in _tEntities
                       select item;
           query.Load();
           return _tEntities.Local;
 }

but when i try to run following method, the method returns old data loaded by GetAll() method.

public override IList<City> GetAll(Func<City, bool> predicate)
       {
           var query = from item in _tEntities
                       select item;
           query.Where<City>(predicate);
           query.Load();
           return _tEntities.Local;
       }

What is the problem and how can i fix them?
How can i use local method in this sample and reload new data into local(cache)?

3

There are 3 best solutions below

0
On

I'm not too sure what you are trying to achieve with a .Load method here but it seems like you want the following.

public override IList<City> GetAll(Func<City, bool> predicate)
{
    return _tEntities.Where<City>(predicate).ToList();
}
0
On

You are looking at the wrong problem. What you are most likely seeing is a result of the fact that when you do the first query, the local cache is empty. So it only returns the results from your query. But when you do the second, it's returning the results of your first query AND your second query.

This comes down to the fact that you are using a shared DbContext between all your methods. Local contains a cache of all records the context has retrieved, not just the most recent query.

The correct solution is to not use Local in this manner. Even better, don't use a shared context since this can lead to context cache bloat.

0
On
query.Where<City>(predicate);

This doesn't change query. The query.Load() on the next line ignores the predicate: you're calling query.Load() and not query.Where<City>(predicate).Load(). It's as if you had written

int i = 3;
i + 1;
Console.WriteLine(i); // still prints 3

In that example, C# does not really actually allow an addition to be used as a statement, but .Where(predicate) is a method call, and method calls can be used as such, even if they return values.

This is not your only issue (see the other answers), but my guess is that this issue is the one that leads to the unexpected results you're seeing.