I use AddOrUpdate in this situation. However, I believe it does query the database first in order to decide to issue an insert or update.
context.MyEntities.AddOrUpdate(e => e.Id, entity);
Update:
I ran through my debug log files. First it runs:
SELECT TOP (2) ... WHERE 1 = [Extent1].[Id]
Then it runs either:
INSERT [dbo].[TestTable](...) VALUES (...)
SELECT [Id]
FROM [dbo].[TestTable]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
OR:
UPDATE [dbo].[TestTable]
SET ...
WHERE ([Id] = @2)
Update 2:
Here’s an interesting extension method the uses MERGE:
https://gist.github.com/ondravondra/4001192