As far as I've understood it, there is no option in EF (and EF Core) to explicitly lock resources which I'm querying, but I'll need this functionality quite often and don't really feel like falling back to writing select statements every time I'll need it.
Since I only need it for postgres and according to the spec FOR UPDATE
is the last item in the query, the easiest I thought about implementing it was to get the select statement as described here: In Linq to Entities can you convert an IQueryable into a string of SQL? and append FOR UPDATE
and directly execute it. However this will either give me a query with parameter placeholders or not a prepared query meaning that caching for execution plan won't really work on postgres, so in either way it's a no go.
Linq to SQL had the method DataContext.GetCommand
but there doesn't seem to be anything equivalent in EF and specially EF Core. I also had a look at EntityFramework.Extended and their batch updates / deletes but since they have to transform the select statement into a different statement they need to deal with far more complexity than me and so I hope for a simpler solution.
Update:
In case it wasn't clear from the description, I want to create an extension method like this:
public static IList<T> ForUpdate (this IQueryable<T> me)
{
// this line is obviously what is missing for me :)
var theUnderlyingCommand = me.GetTheUnderlyingDbCommandOrSimilar();
theUnderlyingCommand.Text += "FOR UPDATE";
return me.ToList();
}
This way, other developers can use EF via Linq as with all other procedures and instead of running .ToList()
they'd run .ForUpdate()
. (For Update executes the query on purpose to make the implementation easier, and also because FOR UPDATE
is the last option supported by postgres, afterwards there shouldn't be anything else anymore)