1

I've a Web.API working fine, until I modify something directly in the db, and the API returns the old value because it's not refreshed.

Example:

public class MyRepository {
    private static MyContext dataContext = new MyContext();
    public static List<Invite> GetAllInvitesByUser(string UserID) {
        ...
        IEnumerable<TInvite> results = 
            from i in dataContext.Invites
            where ...
            select i;

It returns a JSON:

{
    "invite": 
    {
        "idInvite": 374,
        "message": "hi there",
        "type": 0,
        ...

If I go the database, and update one field:

update tinvite set type = 1 where idInvite = 374

How can I make the API return type=1 without restarting the IIS?

UPDATE

My context looks like this:

public MyContext() :
        base("MyEntities")
{
    Configuration.ProxyCreationEnabled = false;
    Configuration.LazyLoadingEnabled = false;
}

When I check in real time the database queries with SQL Server Profiler, I see that EF makes the right query, in my case:

exec sp_executesql N'SELECT 
[Extent1].[idInvite] AS [idInvite], 
[Extent1].[message] AS [message], 
[Extent1].[type] AS [type], 
...
FROM [dbo].[TInvite] AS [Extent1]
WHERE ... 

which should return type = 1, but the dataContext.Invites object already has the old value for type (0)...

Why is it making this query if it's ignoring its result and using the context values??

nano
  • 2,511
  • 4
  • 25
  • 42
  • 1
    I don't think that you can. This is due to the identity map that EF keeps.in memory. I've tried looking and can't see a way to do it – Derek Van Cuyk Sep 30 '15 at 16:42
  • 1
    How are you constructing your DbContext instance when running this query? You aren't using a single global or `static` reference to the DbContext, are you? – danludwig Sep 30 '15 at 17:17
  • 1
    I am. :S And I've updated the question with more details. Thanks. – nano Sep 30 '15 at 17:23
  • 2
    Never, ever ever ever, create single shared static DbContext instance. You want one instance of it for each of your scopes (scope usually meaning an entire use case, for web purposes, this would be one HTTP request from beginning to end). Get rid of the `static MyDbContext` and instead create *and dispose* of it after each SaveChanges(Async) call. After that, I bet you will stop seeing this behavior. For queries, you can still create a new instance and invoke `.AsNoTracking()` on your entities to read the data back out. – danludwig Sep 30 '15 at 21:05
  • 1
    for your question in the UPDATE. It cannot know if the entity already exists until it fetches data from the database. So in the phase of materializing the result,it will know some entities already exist and pick them up (to include in the result) instead of the new ones. If you find some entities based on the keys (using `Find` method), then it will search the existing entities first (via keys) before actually running a query against database (in case the entities don't exist). – Hopeless Oct 01 '15 at 01:25

1 Answers1

1

If you don't want to store your entities in local context storage, you can use AsNoTracking() extension method:

context.Invites.AsNoTracking().Where(...);
Andrei
  • 42,814
  • 35
  • 154
  • 218