首页 > 解决方案 > EF Core 5 - 使用 SQL 更新实体不起作用

问题描述

我有一个使用 EF Core 5 和SQL Server 进行生产/开发SQLLite 进行集成测试的应用程序。

在 SQL Server 中一切正常,但在我的测试中使用 SQLLite,我的实体没有更新。

让我们来一些代码和解释。

模型建造师

这是我的实体的模型构建器配置:

 modelBuilder.Entity<Order>(order =>
        {
            order.ToTable("Orders");
            order.HasKey(s => s.Id);
            order.Property(i => i.ConcurrencyStamp).IsRowVersion();
            order.Property(i => i.ShippingExcludingTaxes).HasColumnType("decimal(10,2)");
            order.Property(i => i.ShippingIncludingTaxes).HasColumnType("decimal(10,2)");

            order.HasMany(s => s.OrderItems).WithOne()
                .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field);
            order.Metadata.FindNavigation(nameof(Order.OrderItems)).SetPropertyAccessMode(PropertyAccessMode.Field);

            order.HasOne<Payment>(p => p.Payment)
              .WithOne()
              .HasForeignKey<Order>(p => p.PaymentId);

            order.HasOne<Address>(s => s.ShippingAddress)
              .WithOne()
              .HasForeignKey<Order>(p => p.ShippingAddressId);

            order.OwnsOne(lc => lc.Contact);

        });

我已经读到 RowVersion 不像在 SQLServer 中那样工作,这里我使用由 Guid 生成的字符串,这里是在每个 savechanges (经典和异步)中更新它的代码:

 private void UpdateLastUpdate()
    {
        var entries = ChangeTracker
              .Entries()
              .Where(e => e.Entity is Entity && (
                      e.State == EntityState.Added
                      || e.State == EntityState.Modified));

        foreach (var entityEntry in entries)
        {
            ((Entity)entityEntry.Entity).LastUpdate = DateTime.Now;
            ((Entity)entityEntry.Entity).ConcurrencyStamp = Guid.NewGuid().ToString();
        }

    }

领域类和测试方法

这是我要更新的实体

public class Order : Entity, IAggregateRoot
    {
        public string UserId { get; set; }

        public decimal ShippingIncludingTaxes { get; set; }
        public decimal ShippingExcludingTaxes { get; set; }

        public OrderState State { get; set; }

        public string PaymentId { get; set; }
        public Payment Payment{ get; set; }

        private readonly List<OrderItem> _orderItems = new List<OrderItem>();
        public IReadOnlyCollection<OrderItem> OrderItems => _orderItems;

        public string ShippingAddressId { get; set; }
        public Address ShippingAddress { get; set; }

        public OrderContact Contact { get; set; }

        public ICollection<OrderHistory> OrderHistories { get; set; }

        public decimal TotalIncludingTaxes => _orderItems.Sum(s => s.TotalIncludingTaxes) + ShippingIncludingTaxes;

//some other stuff
}

以及我在测试中更新的属性

//method is in Order.cs
     public void SetInProgress(OrderHistory history)
        {
            State = OrderState.InProgress;
            OrderHistories = OrderHistories ?? new List<OrderHistory>();
            OrderHistories.Add(history);

        }

测试和断言

所以我运行了我的集成测试,一切正常,我看到我的 DBContext 接受了我的更改。但是在进行断言时,实体在测试之前是相同的

    public class OrderControllerTest : IClassFixture<IntegrationTestFixture>
    {
        private readonly IntegrationTestFixture _fixture;

        public OrderControllerTest(IntegrationTestFixture fixture)
        {
            _fixture = fixture;
            Init().GetAwaiter().GetResult();
        }

        private IRepository<OrderHistory, UserContext> _orderHistoryRepository;
        private IRepository<Nursery, PlantContext> _nurseryRepository;
        private IRepository<Order, UserContext> _orderRepository;

        private Nursery nursery;
        private async Task Init()
        {
            _orderHistoryRepository = _fixture.Services.GetService<IRepository<OrderHistory, UserContext>>();
            _nurseryRepository = _fixture.Services.GetService<IRepository<Nursery, PlantContext>>();
            _orderRepository = _fixture.Services.GetService<IRepository<Order, UserContext>>();

            nursery =  await _nurseryRepository.FindAsync(a => a.LegalNumber == NurseryService.LEPAGE_LEGALNUMBER);
        }

        [Fact]
        [Trait("Category", "Integration")]
        public async Task OrderController_SendOrders_ShouldBeOkWithOrders()
        {
            await _orderRepository.AddAsync(OrderGenerator.GenerateOrder(OrderState.Validated, nursery.Id));

            var result = await _fixture.GetAsync("api/order/send");

            result.IsSuccessStatusCode.Should().BeTrue();

            var histories = await _orderHistoryRepository.FilterAsync(s => true);
            var orders = await _orderRepository.FilterAsync(s => true);

            histories.Should().NotBeEmpty();
            orders.All(all => all.State == OrderState.InProgress).Should().BeTrue();

        }
}

在这里,当我测试我的订单是否具有 InProgress 状态时,结果为 false,因为 State 已验证(状态自创建以来未更改)。

如果有人有想法?如果由于 Guid 行版本而发生错误,是否存在任何配置以使我的测试正常工作?

标签: c#entity-frameworkunit-testingentity-framework-coreintegration-testing

解决方案


推荐阅读