0

Is doing

context.Single(x => x.Id == id);

exactly the same as

context.Find(new[] { id });

in the entity framework?

avid
  • 559
  • 5
  • 17

1 Answers1

3

No. Find checks first if the object is already loaded into the context. If yes it just returns this object. If no it queries the entity from the database. Single always queries the object from the database. If it is already in the context it gets updated with the values from the DB. (Edit: The last sentence is wrong, see comments!)

Also Find returns null if the object is neither in the context nor in the database. Single throws an exception if it isn't found in the database.

You mean: context.SomeEntitySet.Find(id) and context.SomeEntitySet.Single(x => x.Id == id), I guess.

Slauma
  • 167,754
  • 56
  • 385
  • 407
  • Are you sure that `Single` will update values of loaded object? I expect it doesn't. – Ladislav Mrnka Jul 19 '11 at 19:13
  • @Ladislav: Just tested, it's wrong what I wrote, indeed, thanks for correction! I don't know where I had this idea from. But how does it work then actually? If a query result is returned EF checks if an object with same key is already in the context, and if yes the queried object is thrown away? – Slauma Jul 19 '11 at 19:41
  • 1
    Exactly. It first checks if the entity with the same key is present in identity map and if yes it returns that instance - queried record is never materialized. That is principle of [identity map](http://stackoverflow.com/questions/3653009/entity-framework-and-connection-pooling/3653392#3653392) - essential part of ORM tools. But that is just default behavior. You can force EF to override data in existing instance (at least in ObjectContext API you can). – Ladislav Mrnka Jul 19 '11 at 19:49
  • Thanks for the answer. Just to make this clear, both Find and Single will return entities from the context if they are present, meaning that it will not query the database? – avid Jul 20 '11 at 10:40
  • @avid: No, `Single` *always* runs a database query, no matter if the object is already in the context or not. *After* the query has been executed EF checks by Entity Key if the returned result is in the context. If yes, it throws the result away and the method actually returns the object in the context. It sounds stupid in this simple example but this is how it works.I think the reason is basically that the lambda expression in Single is not analyzed by EF as an expression which only queries for the primary key. Imagine the expression would be `x => x.Name != "ABC"`. (continue...) – Slauma Jul 20 '11 at 10:56
  • There is no way to find out up front if the result is already in the context or not. Therefore a DB query is necessary. – Slauma Jul 20 '11 at 10:56