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
|
var items = await q
|
||||||
.OrderBy(x => x.a.Kind).ThenBy(x => x.a.Name)
|
.OrderBy(x => x.a.Kind).ThenBy(x => x.a.Name)
|
||||||
.Skip(req.Skip).Take(req.Take)
|
.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);
|
.ToListAsync(ct);
|
||||||
|
|
||||||
var rows = items.Select(x =>
|
var rows = items.Select(x =>
|
||||||
|
|
@ -116,7 +125,7 @@ public record MoneyAccountInput(
|
||||||
x.cu.Id, x.cu.Code,
|
x.cu.Id, x.cu.Code,
|
||||||
x.a.OpeningBalance, x.a.OpeningDate, current,
|
x.a.OpeningBalance, x.a.OpeningDate, current,
|
||||||
x.a.IsActive, x.a.IsDefault,
|
x.a.IsActive, x.a.IsDefault,
|
||||||
Microsoft.EntityFrameworkCore.EF.Property<uint>(x.a, "xmin"));
|
x.Xmin);
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
return new PagedResult<MoneyAccountRow>
|
return new PagedResult<MoneyAccountRow>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,16 @@ public async Task Account_create_accepts_date_only_opening_date_from_ui()
|
||||||
isActive = true, isDefault = false,
|
isActive = true, isDefault = false,
|
||||||
});
|
});
|
||||||
resp.IsSuccessStatusCode.Should().BeTrue($"date-only openingDate должен приниматься: {(int)resp.StatusCode} {await resp.Content.ReadAsStringAsync()}");
|
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]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue