Reputation: 3168
I have the following code in my application
using (ApplicationDbContext ctx = new ApplicationDbContext())
{
Instance i = ctx.Instance.FirstOrDefault(s => s.Id == id);
i.Views++;
ctx.SaveChanges();
}
Is there a more Efficient way to achieve this? or is EF smart enough to realize whats going on and generate a simple update statement rather than running a select then update?
Any help would be great or guidance on how this should work.
Upvotes: 2
Views: 62
Reputation: 4117
No, EF is not smart enough to do both things in one run.
I tried it out with a simple model and watched what happens in the profiler.
In an example like yours EF will first get the record with a SELECT
and then run exec sp_executesql
with the desired UPDATE
.
Unfortunately I am pretty sure you cannot get EF to do this in a more intelligent way.
Even if you shorten your code to be:
Instance i = ctx.Instance.First(s => s.Id == id).Views++;
ctx.SaveChanges();
It will still do it in a separate SELECT
and UPDATE
.
I think that is just the price you pay for not accessing the database with SQL
directly.
As pointed out by Sriram Sakthivel and also in other questions you can use the EntityFramework.Extended (also available via nuget) to do it in one run, you do not need SaveChanges()
any more then.
Just add the package to the project and
using EntityFramework.Extensions;
to the file where you want to use it, then you can do your update in one run like this:
ctx.Instance.Update(i => i.Id == id, i => new Instance() { Views= i.Views + 1 });
In the raw SQL that is then sent to your DBMS it will look something like this:
UPDATE [dbo].[Instance] SET
[Views] = [Views] + 1
FROM [dbo].[Instance] AS j0 INNER JOIN (
SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Instance] AS [Extent1]
WHERE 1 = [Extent1].[Id]
) AS j1 ON (j0.[Id] = j1.[Id])
Not entirely beautiful but still better than two seperate statements, heh :)?
Upvotes: 2