[WIP] Models/Entities: Remove EF proxies
All checks were successful
Test / Run tests (push) Successful in 2m11s

This commit is contained in:
2026-04-01 16:24:03 +02:00
parent bb1dd3e4e9
commit dd6f18117e
31 changed files with 433 additions and 252 deletions

View File

@@ -423,12 +423,7 @@ namespace Elwig.Windows {
using var ctx = new AppDbContext();
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await ViewModel.GetFilters(ctx);
var deliveries = await deliveryQuery
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
.Include(d => d.Parts).ThenInclude(p => p.Attribute)
.Include(d => d.Parts).ThenInclude(p => p.Cultivation)
.Include(d => d.Parts).ThenInclude(p => p.Variety)
.Include(d => d.Member.EmailAddresses)
.AsSplitQuery()
.ToListAsync();
deliveries.Reverse();
@@ -437,19 +432,22 @@ namespace Elwig.Windows {
.ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter))
.OrderByDescending(a => a.Value)
.ThenBy(a => a.Key.DateTime);
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
deliveries = dict
var threshold = dict.Max(a => a.Value) * 3 / 4;
deliveries = [.. dict
.Where(a => a.Value > threshold)
.Select(a => a.Key)
.ToList();
.Select(a => a.Key)];
}
deliveries.ForEach(d => { d.PartFilter = predicate; });
var filteredParts = await deliveryPartsQuery
.Include(p => p.PartModifiers).ThenInclude(p => p.Modifier)
.GroupBy(p => new { p.Year, p.DId })
.ToDictionaryAsync(g => (g.Key.Year, g.Key.DId), g => g.ToList());
deliveries.ForEach(d => { d.FilteredParts = filteredParts.GetValueOrDefault((d.Year, d.DId)) ?? []; });
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
await RefreshDeliveryParts();
var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList();
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
ViewModel.StatusMembers = $"{members.Count:N0}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
ViewModel.StatusDeliveries = $"{deliveries.Count:N0}";
@@ -486,7 +484,7 @@ namespace Elwig.Windows {
int year = 0;
Menu_Bki_SaveList.Items.Clear();
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).IgnoreAutoIncludes().ToListAsync()) {
if (s.Year > year) year = s.Year;
var i = new MenuItem {
Header = $"Saison {s.Year}",
@@ -503,7 +501,7 @@ namespace Elwig.Windows {
};
noAttr.Click += Menu_BulkAction_SetAttribute_Click;
Menu_BulkAction_SetAttribute.Items.Add(noAttr);
foreach (var attr in await ctx.WineAttributes.OrderBy(a => a.AttrId).ToListAsync()) {
foreach (var attr in await ctx.WineAttributes.OrderBy(a => a.AttrId).IgnoreAutoIncludes().ToListAsync()) {
var i = new MenuItem {
Header = attr.Name,
};
@@ -513,7 +511,7 @@ namespace Elwig.Windows {
Menu_BulkAction_AddModifier.Items.Clear();
Menu_BulkAction_RemoveModifier.Items.Clear();
foreach (var mod in await ctx.Modifiers.Where(m => m.Year == year).OrderBy(m => m.ModId).ToListAsync()) {
foreach (var mod in await ctx.Modifiers.Where(m => m.Year == year).OrderBy(m => m.ModId).IgnoreAutoIncludes().ToListAsync()) {
var i1 = new MenuItem {
Header = mod.Name,
};
@@ -551,7 +549,7 @@ namespace Elwig.Windows {
.OrderBy(m => m.Ordering)
.Include(m => m.Season.Currency)
.ToListAsync());
ControlUtils.RenewItemsSource(WineOriginInput, (await ctx.WineOrigins.ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId));
ControlUtils.RenewItemsSource(WineOriginInput, (await ctx.WineOrigins.Include(o => o.Parent).Include(o => o.Children).ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId));
var kgList = (await ctx.Katastralgemeinden
.Where(k => k.WbKg != null)
.Include(k => k.WbKg)
@@ -581,14 +579,16 @@ namespace Elwig.Windows {
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
.Where(m => m.Year == d.Year && (!IsCreating || m.IsActive))
.OrderBy(m => m.Ordering)
.Include(m => m.Season.Currency)
.ToListAsync());
ControlUtils.RenewItemsSource(DeliveryPartList, d.FilteredParts.OrderBy(p => p.DPNr).ToList(), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
ControlUtils.RenewItemsSource(DeliveryPartList, await ctx.DeliveryParts
.Where(p => p.Year == d.Year && p.DId == d.DId)
.OrderBy(p => p.DPNr)
.Include(p => p.PartModifiers)
.ToListAsync(), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
} else {
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
.Where(m => m.Year == ViewModel.FilterSeason && (!IsCreating || m.IsActive))
.OrderBy(m => m.Ordering)
.Include(m => m.Season.Currency)
.ToListAsync());
DeliveryPartList.ItemsSource = null;
}
@@ -596,16 +596,17 @@ namespace Elwig.Windows {
private void RefreshInputs(bool validate = false) {
ClearInputStates();
if (DeliveryPartList.SelectedItem is DeliveryPart p) {
FillInputs(p);
} else if (DeliveryList.SelectedItem is Delivery d) {
if (DeliveryList.SelectedItem is Delivery d) {
FillInputs(d);
if (DeliveryPartList.SelectedItem is DeliveryPart p) {
FillInputs(p);
}
} else {
ClearOriginalValues();
ClearDefaultValues();
ClearInputs(validate);
ClearInputStates();
}
}
GC.Collect();
}
@@ -617,7 +618,6 @@ namespace Elwig.Windows {
}
private void FillInputs(DeliveryPart p) {
FillInputs(p.Delivery);
ClearOriginalValues();
ClearDefaultValues();
ViewModel.FillInputs(p);
@@ -852,9 +852,10 @@ namespace Elwig.Windows {
await EnsureContextRenewed();
if (p?.Delivery != null) {
try {
using var ctx = new AppDbContext();
using var doc = new DeliveryNote((await ctx.Deliveries.FindAsync(p.Year, p.DId))!, ctx);
await doc.Generate();
using var doc = await DeliveryNote.Initialize(p.Year, p.DId);
using (var ctx = new AppDbContext()) {
await doc.Generate(ctx);
}
if (App.Config.Debug) {
doc.Show();
} else {

View File

@@ -155,7 +155,7 @@ namespace Elwig.Windows {
}
protected override async Task OnRenewContext(AppDbContext ctx) {
var season = await ctx.Seasons.FindAsync(Year);
var season = await ctx.Seasons.Include(s => s.PaymentVariants).SingleAsync(s => s.Year == Year);
var l = new List<string> {
MemberDataSheet.Name
};
@@ -758,7 +758,7 @@ namespace Elwig.Windows {
if (doc.Type == DocType.Custom) {
return [new GeneratedDoc((string)doc.Details!)];
} else if (doc.Type == DocType.MemberDataSheet) {
return [new GeneratedDoc(new MemberDataSheet(m, ctx) { Date = postalDate })];
return [new GeneratedDoc(new MemberDataSheet(m) { Date = postalDate })];
} else if (doc.Type == DocType.DeliveryConfirmation) {
var year = (int)doc.Details!;
DeliveryConfirmationDeliveryData data;
@@ -769,21 +769,14 @@ namespace Elwig.Windows {
} else {
return [];
}
return [new GeneratedDoc(new DeliveryConfirmation(ctx, year, m, data) { Date = postalDate })];
return [new GeneratedDoc(new DeliveryConfirmation(year, m, data) { Date = postalDate })];
} else if (doc.Type == DocType.CreditNote) {
var details = ((int, int))doc.Details!;
var year = details.Item1;
var avnr = details.Item2;
var data = cnData[(year, avnr)];
try {
return [new GeneratedDoc(new CreditNote(
ctx, data.Item2[m.MgNr], data.Item1[m.MgNr],
data.Item3.ConsiderContractPenalties,
data.Item3.ConsiderTotalPenalty,
data.Item3.ConsiderAutoBusinessShares,
data.Item3.ConsiderCustomModifiers,
ctx.GetMemberUnderDelivery(year, m.MgNr).GetAwaiter().GetResult()
) { Date = postalDate })];
return [new GeneratedDoc(new CreditNote(data.Item2[m.MgNr], data.Item3, data.Item1[m.MgNr]) { Date = postalDate })];
} catch (Exception) {
return [];
}
@@ -827,7 +820,7 @@ namespace Elwig.Windows {
var emailRecipients = email.Select(d => d.Key.MgNr).ToHashSet();
foreach (var item1 in email.Select((e, i) => new { Index = i, e.Key, e.Value })) {
foreach (var item2 in item1.Value.Select((d, i) => new { Index = i, Doc = d })) {
await item2.Doc.Generate(CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
await item2.Doc.Generate(ctx, CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
ProgressBar.Value = offset + v * (item2.Index + 1) / item1.Value.Count / totalNum + 100.0 * item1.Index / totalNum;
})));
}
@@ -861,7 +854,7 @@ namespace Elwig.Windows {
if (printDocs.Count > 0) {
var print = Document.Merge(printDocs);
await print.Generate(CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
await print.Generate(ctx, CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
ProgressBar.Value = offset + v * printNum / totalNum;
})));
PrintDocument = print;

View File

@@ -189,7 +189,7 @@ namespace Elwig.Windows {
var font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets");
MenuItem? temp = null;
var seasons = await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync();
var seasons = await ctx.Seasons.Include(s => s.PaymentVariants).OrderByDescending(s => s.Year).ToListAsync();
Menu_DeliveryConfirmation.Items.Clear();
foreach (var s in seasons) {
var i = new MenuItem {
@@ -328,6 +328,7 @@ namespace Elwig.Windows {
}
private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) {
if (!IsInitialized) return;
await RefreshList();
}
@@ -498,7 +499,9 @@ namespace Elwig.Windows {
try {
await Task.Run(async () => {
using var doc = new Letterhead(m);
await doc.Generate();
using (var ctx = new AppDbContext()) {
await doc.Generate(ctx);
}
if (!App.Config.Debug) {
await doc.Print();
} else {