Entity FrameworkでUPDLOCKを指定する方法

WITH (UPDLOCK)付きのViewを作成して、マッピングしたエンティティを検索すれば自動的にUpdateロックがかかります。具体的には

まずはWITH (UPDLOCK)付きのViewを作る

CREATE VIEW [dbo].[EmployeesWithLock]
AS
SELECT
EmployeeID, LastName, FirstName, Title, TitleOfCourtesy, BirthDate, HireDate, Address, 
City, Region, PostalCode, Country, HomePhone, Extension, Photo, Notes, ReportsTo, PhotoPath
FROM                     
dbo.Employees WITH (UPDLOCK)

次にViewを含んだedmxを作成し、Viewのエンティティを更新可能にする

Viewは既定では更新できないため、マッピングしたエンティティにPKを付けて、Viewを更新できるようにedmxファイルをxmlエディタで編集します。以下のような部分を

<EntitySet Name="EmployeesWithLock" EntityType="NorthwindModel.Store.EmployeesWithLock" 
  store:Type="Views" 
  store:Schema="dbo" 
  store:Name="EmployeesWithLock">
  <DefiningQuery>SELECT 
      [EmployeesWithLock].[EmployeeID] AS [EmployeeID], 
      [EmployeesWithLock].[LastName] AS [LastName], 
       ...略...
      [EmployeesWithLock].[PhotoPath] AS [PhotoPath]
      FROM [dbo].[EmployeesWithLock] AS [EmployeesWithLock]
   </DefiningQuery>
</EntitySet>

DefiningQueryを削除してstore:Schemaのstoreのプレフィックスを外してstore:Nameの属性を削除します。

<EntitySet Name="EmployeesWithLock" EntityType="NorthwindModel.Store.EmployeesWithLock" 
  store:Type="Views"
  Schema="dbo">
</EntitySet>

あとはEntity Frameworkで検索すればOK。

以下のEmployeesWithLockを検索したタイミングで更新予約のロックがかかります。

static void Main(string[] args)
{
    using (var scope = new TransactionScope())
    {
        using (var db = new NorthwindEntities())
        {
            var emp = db.EmployeesWithLock.Where(x => x.EmployeeID == 1).FirstOrDefault();
            emp.City = emp.City+"#";
            db.SaveChanges();
        }
        scope.Complete();
    }
}