Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 469 470 471 472 473 474 475 476 477 ... 642

context2.Entry(updatedCar).State = EntityState.Modified;

В любом случае для сохранения значений все равно должен вызываться метод SaveChanges().

В представленном далее тесте читается неотслеживаемая запись, из нее создается новый экземпляр класса Car и изменяется одно его свойство (Color). Затем в зависимости от того, с какой строки кода вы уберете комментарий, либо устанавливается состояние, либо использует метод Update() на DbSet<T>. Метод Update() также изменяет состояние на Modified. Затем в тесте вызывается метод SaveChanges(). Все дополнительные контексты нужны для обеспечения точности теста и отсутствия пересечения между контекстами:

[Fact]

public void ShouldUpdateACarUsingState()

{

  ExecuteInASharedTransaction(RunTheTest);

  void RunTheTest(IDbContextTransaction trans)

  {

    var car = Context.Cars.AsNoTracking().First(c => c.Id == 1);

    Assert.Equal("Black", car.Color);

    var updatedCar = new Car

    {

      Color = "White", //Original is Black

      Id = car.Id,

      MakeId = car.MakeId,

      PetName = car.PetName,

      TimeStamp = car.TimeStamp

      IsDrivable = car.IsDrivable

    };

    var context2 = TestHelpers.GetSecondContext(Context, trans);

    // Либо вызвать Update(), либо модифицировать состояние.

    context2.Entry(updatedCar).State = EntityState.Modified;

    // context2.Cars.Update(updatedCar);

    context2.SaveChanges();

    var context3 =

      TestHelpers.GetSecondContext(Context, trans);

    var car2 = context3.Cars.First(c => c.Id == 1);

    Assert.Equal("White", car2.Color);

  }

}

Ниже показан выполняющийся оператор SQL:

exec sp_executesql N'SET NOCOUNT ON;

UPDATE [dbo].[Inventory] SET [Color] = @p0

WHERE [Id] = @p1 AND [TimeStamp] = @p2;

SELECT [TimeStamp]

FROM [dbo].[Inventory]

WHERE @@ROWCOUNT = 1 AND [Id] = @p1;

',N'@p1 int,@p0 nvarchar(50),@p2 varbinary(8)',@p1=1,@p0=N'White',

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

@p2=0x000000000000862D

Проверка параллелизма

Проверка параллелизма подробно обсуждалась в предыдущей главе. Вспомните, что когда внутри сущности определено свойство TimeStamp, то значение этого свойства используется в конструкции WHERE при сохранении изменений (обновлений или удалений) в базе данных. Вместо поиска только первичного ключа к запросу добавляется поиск значения TimeStamp, например:

UPDATE [dbo].[Inventory] SET [PetName] = @p0

WHERE [Id] = @p1 AND <b>[TimeStamp] = @p2</b>;

В следующем тесте демонстрируется пример создания исключения, связанного с параллелизмом, его перехвата и применения Entries для получения исходных значений, текущих значений и значений, которые в настоящий момент хранятся в базе данных. Получение текущих значений требует еще одного обращения к базе данных:

[Fact]

public void ShouldThrowConcurrencyException()

{

  ExecuteInATransaction(RunTheTest);

  void RunTheTest()

  {

    var car = Context.Cars.First();

    // Обновить базу данных за пределами контекста.

    Context.Database.ExecuteSqlInterpolated(

      $&quot;Update dbo.Inventory set Color='Pink' where Id = {car.Id}&quot;);

    car.Color = &quot;Yellow&quot;;

    var ex = Assert.Throws&lt;CustomConcurrencyException&gt;(

      () =&gt; Context.SaveChanges());

    var entry = ((DbUpdateConcurrencyException) ex.InnerException)?.Entries[0];

    PropertyValues originalProps = entry.OriginalValues;

    PropertyValues currentProps = entry.CurrentValues;

    // Требует еще одного обращения к базе данных.

    PropertyValues databaseProps = entry.GetDatabaseValues();

  }

}

Ниже показаны выполняемые операторы SQL. Первым из них является оператор UPDATE, а вторым — обращение для получения значений базы данных:

exec sp_executesql N'SET NOCOUNT ON;

UPDATE [dbo].[Inventory] SET [Color] = @p0

WHERE [Id] = @p1 AND [TimeStamp] = @p2;

SELECT [TimeStamp]

FROM [dbo].[Inventory]

WHERE @@ROWCOUNT = 1 AND [Id] = @p1;'

,N'@p1 int,@p0 nvarchar(50),@p2 varbinary(8)',@p1=1,@p0=N'Yellow',

1 ... 469 470 471 472 473 474 475 476 477 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий