fix(money): список счетов 500 на непустых данных (EF.Property xmin в памяти)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
MoneyAccountsController.List проецировал xmin через EF.Property ПОСЛЕ ToListAsync на AsNoTracking-сущности → InvalidOperationException (shadow- свойство вне трекера). С пустым списком не всплывало (нет строк), с данными — 500, и ломались ВСЕ money-страницы, дёргающие useMoneyAccounts (счета/смены/ платежи) — поймал menu-walk на stage. Переносим xmin в server-side Select. Регресс закрыт: date-only тест теперь ещё и GET-ит список с данными. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
174cb563bf
commit
4a064de96b
|
|
@ -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<uint>(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<uint>(x.a, "xmin"));
|
||||
x.Xmin);
|
||||
}).ToList();
|
||||
|
||||
return new PagedResult<MoneyAccountRow>
|
||||
|
|
|
|||
|
|
@ -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<JsonElement>()).GetProperty("currentBalance").GetDecimal().Should().Be(50_000m);
|
||||
var created = await resp.Content.ReadFromJsonAsync<JsonElement>();
|
||||
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]
|
||||
|
|
|
|||
Loading…
Reference in a new issue