I answered a Connect issue today that deals with a very common expectation for users of systems like Entity Framework and LINQ to SQL. The issue was something like this:
When I run a query, I expect entities that I have added to the context and that are still not saved but match the predicate of the query to show up in the results.
Reality is that Entity Framework queries are always server queries: all queries, LINQ or Entity SQL based, are translated to the database server’s native query language and then evaluated exclusively on the server.
1. Identity-based queries are resolved against the local identity map. For instance, the following query shall not hit the data store:
var c = context.Customers .Where(c => c.CustomerID == "ALFKI");
2. The outermost projection of the query is evaluated on the client. For instance, the following query will create a server query that projects CustomerID and will invoke a client-side WriteLineAndReturn method as code iterates through results:
var q = context.Customers .Select(c => WriteLineAndReturn(c.CustomerID));
In sum, Entity Framework does not include a client-side or hybrid query processor.
There are chances that you have seen unsaved modifications in entities included in the results of queries. This is due to the fact that for tracked queries (i.e. if the query’s MergeOption is set to a value different from NoTracking) Entity Framework performs “identity resolution”.
The process can be simply explained like this:
However, membership of an entity in the results of a given query is decided exclusively based on the state existing on the server. In this example, for instance, what will the query get?:
The answer is:
This behavior is by design and you need to be aware of it when writing your application.
Put in some other way, if the units of work in your application follow a pattern in which they query first, then make modifications to entities and finally save them, discrepancies between query results and the contents of the ObjectSateManager cannot be observed.
But as soon as queries are interleaved with modifications there is a chance that the server won’t contain an entity that exist in the state manager only and that that would match the predicate of the query. Those entities won’t be returned as part of the query.
Notice that the chances that this happens has to do with how long lived is the Unit of Work in your application (i.e. how much does it take from the initial query to the call to SaveChanges).
Hope this helps, Diego