並行語彙基元Concurrency Tokens

如果屬性設定為並行語彙基元 EF 會檢查沒有其他使用者在儲存變更至該記錄時,已修改該資料庫中的值。If a property is configured as a concurrency token then EF will check that no other user has modified that value in the database when saving changes to that record. EF 使用開放式並行存取模式,這表示它會假設的值未經變更,然後再次嘗試儲存資料,但它找到的值變更時,會擲回。EF uses an optimistic concurrency pattern, meaning it will assume the value has not changed and try to save the data, but throw if it finds the value has been changed.

比方說,我們可能想設定LastNamePerson是並行語彙基元。For example we may want to configure LastName on Person to be a concurrency token. 這表示,如果某個使用者嘗試儲存的某些變更Person,但另一位使用者已變更LastName則會擲回例外狀況。This means that if one user tries to save some changes to a Person, but another user has changed the LastName then an exception will be thrown. 這可能是需要這樣做,使您的應用程式可以提示使用者,以確保此記錄仍代表相同的實際人員之前將其變更。This may be desirable so that your application can prompt the user to ensure this record still represents the same actual person before saving their changes.

注意

此頁面說明如何設定並行語彙基元。This page documents how to configure concurrency tokens. 請參閱處理並行如需如何在您的應用程式中使用開放式並行存取的範例。See Handling Concurrency for examples of how to use optimistic concurrency in your application.

並行語彙基元在 EF 中的運作方式How concurrency tokens work in EF

資料存放區可以檢查任何記錄正在更新或刪除仍有並行語彙基元內容原本從資料庫載入資料時所指定的相同值來強制執行並行語彙基元。Data stores can enforce concurrency tokens by checking that any record being updated or deleted still has the same value for the concurrency token that was assigned when the context originally loaded the data from the database.

例如,關聯式資料庫來達成此目的包括在並行語彙基元WHERE的任何子句UPDATEDELETE命令和檢查已受影響的資料列數目。For example, relational databases achieve this by including the concurrency token in the WHERE clause of any UPDATE or DELETE commands and checking the number of rows that were affected. 如果並行語彙基元仍符合,則會更新一個資料列。If the concurrency token still matches then one row will be updated. 如果資料庫中的值已變更,會不更新任何資料列。If the value in the database has changed, then no rows are updated.

UPDATE [Person] SET [FirstName] = @p1
WHERE [PersonId] = @p0 AND [LastName] = @p2;

慣例Conventions

依照慣例,屬性會永遠不會設定為並行語彙基元。By convention, properties are never configured as concurrency tokens.

資料註釋Data Annotations

您可以使用資料註解將屬性設定為並行語彙基元。You can use the Data Annotations to configure a property as a concurrency token.

public class Person
{
    public int PersonId { get; set; }

    [ConcurrencyCheck]
    public string LastName { get; set; }

    public string FirstName { get; set; }
}

關於 fluent 應用程式開發介面Fluent API

您可以使用 fluent 應用程式開發的應用程式開發介面,將屬性設定為並行語彙基元。You can use the Fluent API to configure a property as a concurrency token.

class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .Property(p => p.LastName)
            .IsConcurrencyToken();
    }
}

public class Person
{
    public int PersonId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

時間戳記/資料列版本Timestamp/row version

時間戳記是屬性,產生新的值是由資料庫每次插入或更新資料列。A timestamp is a property where a new value is generated by the database every time a row is inserted or updated. 屬性也會被視為並行語彙基元。The property is also treated as a concurrency token. 這可確保如果其他人已修改的資料列,您嘗試更新您查詢的資料後,就會收到例外狀況。This ensures you will get an exception if anyone else has modified a row that you are trying to update since you queried for the data.

如何達成這會決定所使用的資料庫提供者。How this is achieved is up to the database provider being used. SQL Server 的時間戳記通常用在byte []屬性,將會安裝為ROWVERSION資料庫中的資料行。For SQL Server, timestamp is usually used on a byte[] property, which will be setup as a ROWVERSION column in the database.

慣例Conventions

依照慣例,屬性會永遠不會設定為時間戳記。By convention, properties are never configured as timestamps.

資料註釋Data Annotations

您可以使用資料註解屬性設定為時間戳記。You can use Data Annotations to configure a property as a timestamp.

public class Blog
{
    public int BlogId { get; set; }

    public string Url { get; set; }
    
    [Timestamp]
    public byte[] Timestamp { get; set; }
}

關於 fluent 應用程式開發介面Fluent API

您可以使用 fluent 應用程式開發的應用程式開發介面的屬性設定為時間戳記。You can use the Fluent API to configure a property as a timestamp.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(p => p.Timestamp)
            .IsRowVersion();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public byte[] Timestamp { get; set; }
}