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
This work's for me using SQLServer (no tested async methods):
First, create a DbCommandInterceptor (I called HintInterceptor.cs)
using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using System.Text.RegularExpressions;
public class HintInterceptor : DbCommandInterceptor
{
private static readonly Regex _tableAliasRegex = new Regex(@"(?FROM +(\[.*\]\.)?(\[.*\]) AS (\[.*\])(?! WITH \(*HINT*\)))", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
[ThreadStatic]
public static string HintValue;
private static string Replace(string input)
{
if (!String.IsNullOrWhiteSpace(HintValue))
{
if (!_tableAliasRegex.IsMatch(input))
{
throw new InvalidProgramException("Não foi possível identificar uma tabela para ser marcada para atualização(forupdate)!", new Exception(input));
}
input = _tableAliasRegex.Replace(input, "${tableAlias} WITH (*HINT*)");
input = input.Replace("*HINT*", HintValue);
}
HintValue = String.Empty;
return input;
}
public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext
So into Web.config register the your interceptor class
Now I create a static class called HintExtension
public static class HintExtension
{
public static IQueryable WithHint(this IQueryable set, string hint) where T : class
{
HintInterceptor.HintValue = hint;
return set;
}
public static IQueryable ForUpdate(this IQueryable set) where T : class
{
return set.WithHint("UPDLOCK");
}
}
That's All, I can use inside a database transaction like:
using(var trans = context.Database.BeginTransaction())
{
var query = context.mydbset.Where(a => a.name == "asd").ForUpdate();
// not locked yet
var mylist = query.ToList();
// now are locked for update
// update the props, call saveChanges() and finally call commit ( or rollback)
trans.Commit();
// now are unlocked
}
Sorry for my English, I hope my example will help.