Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Троелсен Эндрю, "Язык программирования C#9 и платформа .NET5" бесплатно, без регистрации.
context2.Entry(updatedCar).State = EntityState.Modified;В любом случае для сохранения значений все равно должен вызываться метод
SaveChanges()В представленном далее тесте читается неотслеживаемая запись, из нее создается новый экземпляр класса
CarColorUpdate()DbSet<T>Update()ModifiedSaveChanges()[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] = @p0WHERE [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',@p2=0x000000000000862DПроверка параллелизма
Проверка параллелизма подробно обсуждалась в предыдущей главе. Вспомните, что когда внутри сущности определено свойство
TimeStampWHERETimeStampUPDATE [dbo].[Inventory] SET [PetName] = @p0WHERE [Id] = @p1 AND <b>[TimeStamp] = @p2</b>;В следующем тесте демонстрируется пример создания исключения, связанного с параллелизмом, его перехвата и применения
Entries[Fact]public void ShouldThrowConcurrencyException(){ ExecuteInATransaction(RunTheTest); void RunTheTest() { var car = Context.Cars.First(); // Обновить базу данных за пределами контекста. Context.Database.ExecuteSqlInterpolated( $"Update dbo.Inventory set Color='Pink' where Id = {car.Id}"); car.Color = "Yellow"; var ex = Assert.Throws<CustomConcurrencyException>( () => 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] = @p0WHERE [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',