diff --git a/src/food-market.api/Controllers/Money/MoneyAccountsController.cs b/src/food-market.api/Controllers/Money/MoneyAccountsController.cs index 254539a..7ef936c 100644 --- a/src/food-market.api/Controllers/Money/MoneyAccountsController.cs +++ b/src/food-market.api/Controllers/Money/MoneyAccountsController.cs @@ -103,7 +103,16 @@ public record MoneyAccountInput( var items = await q .OrderBy(x => x.a.Kind).ThenBy(x => x.a.Name) .Skip(req.Skip).Take(req.Take) - .Select(x => new { x.a, x.cu, StoreName = x.st != null ? x.st.Name : null }) + // xmin проецируем ВНУТРИ запроса (через SQL) — иначе EF.Property на + // AsNoTracking-сущности в памяти кидает (shadow-свойство не хранится + // вне трекера). С пустым списком не всплывало (нет строк); с данными + // — 500 на каждой money-странице, использующей список счетов. + .Select(x => new + { + x.a, x.cu, + StoreName = x.st != null ? x.st.Name : null, + Xmin = Microsoft.EntityFrameworkCore.EF.Property(x.a, "xmin"), + }) .ToListAsync(ct); var rows = items.Select(x => @@ -116,7 +125,7 @@ public record MoneyAccountInput( x.cu.Id, x.cu.Code, x.a.OpeningBalance, x.a.OpeningDate, current, x.a.IsActive, x.a.IsDefault, - Microsoft.EntityFrameworkCore.EF.Property(x.a, "xmin")); + x.Xmin); }).ToList(); return new PagedResult diff --git a/tests/food-market.IntegrationTests/MoneyModuleTests.cs b/tests/food-market.IntegrationTests/MoneyModuleTests.cs index 11c2fb1..44268de 100644 --- a/tests/food-market.IntegrationTests/MoneyModuleTests.cs +++ b/tests/food-market.IntegrationTests/MoneyModuleTests.cs @@ -59,7 +59,16 @@ public async Task Account_create_accepts_date_only_opening_date_from_ui() isActive = true, isDefault = false, }); resp.IsSuccessStatusCode.Should().BeTrue($"date-only openingDate должен приниматься: {(int)resp.StatusCode} {await resp.Content.ReadAsStringAsync()}"); - (await resp.Content.ReadFromJsonAsync()).GetProperty("currentBalance").GetDecimal().Should().Be(50_000m); + var created = await resp.Content.ReadFromJsonAsync(); + created.GetProperty("currentBalance").GetDecimal().Should().Be(50_000m); + + // Регресс: список счетов С ДАННЫМИ не должен падать (xmin проецировался + // в памяти на AsNoTracking → 500; с пустым списком не всплывало). + using var list = await api.Http.GetAsync("/api/money/accounts?pageSize=50"); + list.IsSuccessStatusCode.Should().BeTrue($"список счетов с данными должен отдаваться: {(int)list.StatusCode}"); + var listed = await api.ListAsync("/api/money/accounts?pageSize=50"); + listed.Select(x => x.GetProperty("id").GetString()) + .Should().Contain(created.GetProperty("id").GetString()); } [Fact]