Tokens de simultaneidadeConcurrency Tokens

Se uma propriedade é configurada como um token de simultaneidade EF irá verificar se nenhum outro usuário modificou esse valor no banco de dados ao salvar alterações no registro.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 usa um padrão de simultaneidade otimista, que significa que ela será assumem que o valor tenha sido alterada e tentar salvar os dados, mas geram se encontra que o valor foi alterado.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.

Por exemplo, talvez você queira configurar LastName em Person um token de simultaneidade.For example we may want to configure LastName on Person to be a concurrency token. Isso significa que, se um usuário tenta salvar algumas alterações em um Person, mas outro usuário alterou o LastName , em seguida, uma exceção será lançada.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. Isso pode ser desejável para que seu aplicativo pode solicitar ao usuário para garantir que este registro ainda representa a mesma pessoa real antes de salvar suas alterações.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.

Observação

Esta página documenta como configurar tokens de simultaneidade.This page documents how to configure concurrency tokens. Consulte tratamento simultaneidade para obter exemplos de como usar a simultaneidade otimista em seu aplicativo.See Handling Concurrency for examples of how to use optimistic concurrency in your application.

Como os tokens de simultaneidade funcionam no EFHow concurrency tokens work in EF

Armazenamentos de dados podem impor tokens de simultaneidade, verificando se qualquer registro que está sendo atualizada ou excluída ainda tem o mesmo valor para o token de simultaneidade que foi atribuído quando o contexto originalmente carregou os dados do banco de dados.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.

Por exemplo, os bancos de dados relacionais fazer isso, incluindo o token de simultaneidade no WHERE cláusula de qualquer UPDATE ou DELETE comandos e verificando o número de linhas afetadas.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. Se o token de simultaneidade ainda corresponde a uma linha será atualizada.If the concurrency token still matches then one row will be updated. Se o valor no banco de dados foi alterada, nenhuma linha é atualizada.If the value in the database has changed, then no rows are updated.

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

ConvençõesConventions

Por convenção, as propriedades nunca são configuradas como tokens de simultaneidade.By convention, properties are never configured as concurrency tokens.

Anotações de dadosData Annotations

Você pode usar as anotações de dados para configurar uma propriedade como um token de simultaneidade.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; }
}

API fluenteFluent API

Você pode usar a API fluente para configurar uma propriedade como um token de simultaneidade.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; }
}

Versão de carimbo de hora/linhaTimestamp/row version

Um carimbo de hora é uma propriedade em que um novo valor é gerado pelo banco de dados sempre que uma linha é inserida ou atualizada.A timestamp is a property where a new value is generated by the database every time a row is inserted or updated. A propriedade também é tratada como um token de simultaneidade.The property is also treated as a concurrency token. Isso garante que você receberá uma exceção se ninguém tiver modificado uma linha que você está tentando atualizar desde consultada para os dados.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.

Como isso é obtido é até o provedor de banco de dados que está sendo usado.How this is achieved is up to the database provider being used. Para o SQL Server, carimbo de hora é geralmente usado em uma byte [] propriedade, que será de instalação como um ROWVERSION coluna no banco de dados.For SQL Server, timestamp is usually used on a byte[] property, which will be setup as a ROWVERSION column in the database.

ConvençõesConventions

Por convenção, as propriedades nunca são configuradas como os carimbos de hora.By convention, properties are never configured as timestamps.

Anotações de dadosData Annotations

Você pode usar as anotações de dados para configurar uma propriedade como um carimbo de hora.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; }
}

API fluenteFluent API

Você pode usar a API fluente para configurar uma propriedade como um carimbo de hora.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; }
}