From ba5766f9d5ff114276cbc1f4ade191aa0d38153c Mon Sep 17 00:00:00 2001
From: James Chapman <jchapman3000@gmail.com>
Date: Tue, 11 Mar 2025 23:32:27 +0000
Subject: [PATCH] Update to .NET 10 preview

---
 Dockerfile                                       |  6 +++---
 Groceries.Data/Groceries.Data.csproj             |  4 ++--
 Groceries/Groceries.csproj                       |  2 +-
 Groceries/HttpRequestExtensions.cs               |  6 +++---
 Groceries/Items/ItemsPage.razor                  | 15 ++++++---------
 Groceries/Stores/EditStorePage.razor             |  4 ++--
 Groceries/Stores/NewStorePage.razor              |  4 ++--
 Groceries/Transactions/TransactionItemForm.razor | 13 +++++--------
 8 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 8606932..cb513c9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
 # syntax=docker/dockerfile:1.7-labs
 
-FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build1
+FROM mcr.microsoft.com/dotnet/sdk:10.0-preview-alpine AS build1
 
 WORKDIR /src
 COPY ./.config ./
@@ -10,7 +10,7 @@ WORKDIR Groceries
 COPY ./Groceries/libman.json ./
 RUN dotnet libman restore
 
-FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build2
+FROM mcr.microsoft.com/dotnet/sdk:10.0-preview-alpine AS build2
 
 WORKDIR /src
 COPY ./Groceries.sln ./
@@ -23,7 +23,7 @@ COPY . ./
 COPY --from=build1 /src ./
 RUN dotnet publish --no-restore --output /out
 
-FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine-composite AS base
+FROM mcr.microsoft.com/dotnet/aspnet:10.0-preview-alpine-composite AS base
 WORKDIR /groceries
 
 COPY --from=build2 /out .
diff --git a/Groceries.Data/Groceries.Data.csproj b/Groceries.Data/Groceries.Data.csproj
index 8e87f7d..db25cdc 100644
--- a/Groceries.Data/Groceries.Data.csproj
+++ b/Groceries.Data/Groceries.Data.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
     <PropertyGroup>
-        <TargetFramework>net9.0</TargetFramework>
+        <TargetFramework>net10.0</TargetFramework>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
         <WarningsAsErrors>nullable</WarningsAsErrors>
@@ -12,7 +12,7 @@
         <PackageReference Include="DbUp-PostgreSQL" Version="6.0.3" />
         <PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
         <PackageReference Include="Humanizer.Core" Version="2.14.1" />
-        <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
+        <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0-preview.1" />
     </ItemGroup>
 
     <ItemGroup>
diff --git a/Groceries/Groceries.csproj b/Groceries/Groceries.csproj
index edbd095..356ad01 100644
--- a/Groceries/Groceries.csproj
+++ b/Groceries/Groceries.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
     <PropertyGroup>
-        <TargetFramework>net9.0</TargetFramework>
+        <TargetFramework>net10.0</TargetFramework>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
         <WarningsAsErrors>nullable</WarningsAsErrors>
diff --git a/Groceries/HttpRequestExtensions.cs b/Groceries/HttpRequestExtensions.cs
index 0c1b877..faf3d1a 100644
--- a/Groceries/HttpRequestExtensions.cs
+++ b/Groceries/HttpRequestExtensions.cs
@@ -32,10 +32,10 @@ public static class HttpRequestExtensions
         return origin.IsBaseOf(uri);
     }
 
-    public static Uri? GetRefererIfSameOrigin(this HttpRequest request)
+    public static Uri? GetReferrerIfSameOrigin(this HttpRequest request)
     {
-        var referer = request.GetTypedHeaders().Referer;
-        return referer != null && request.IsSameOrigin(referer) ? referer : null;
+        var referrer = request.GetTypedHeaders().Referer;
+        return referrer != null && request.IsSameOrigin(referrer) ? referrer : null;
     }
 
     public static bool IsTurboFrameRequest(this HttpRequest request, string frameId)
diff --git a/Groceries/Items/ItemsPage.razor b/Groceries/Items/ItemsPage.razor
index 938d0cd..540c843 100644
--- a/Groceries/Items/ItemsPage.razor
+++ b/Groceries/Items/ItemsPage.razor
@@ -65,19 +65,16 @@
         }
 
         items = itemsQuery
-            .GroupJoin(
+            .LeftJoin(
                 dbContext.ItemPurchases.Where(purchase => purchase.IsLastPurchase),
                 item => item.Id,
                 purchase => purchase.ItemId,
-                (item, purchases) => new { item, purchases })
-            .SelectMany(
-                group => group.purchases.DefaultIfEmpty(),
-                (group, lastPurchase) => new ItemModel
+                (item, lastPurchase) => new ItemModel
                 {
-                    Id = group.item.Id,
-                    Brand = group.item.Brand,
-                    Name = group.item.Name,
-                    HasBarcode = group.item.Barcodes.Count != 0,
+                    Id = item.Id,
+                    Brand = item.Brand,
+                    Name = item.Name,
+                    HasBarcode = item.Barcodes.Count > 0,
                     LastPurchasedAt = lastPurchase != null ? lastPurchase.CreatedAt : null,
                 })
             .OrderBy(item => item.Brand)
diff --git a/Groceries/Stores/EditStorePage.razor b/Groceries/Stores/EditStorePage.razor
index 90dfb8b..ccd442a 100644
--- a/Groceries/Stores/EditStorePage.razor
+++ b/Groceries/Stores/EditStorePage.razor
@@ -24,9 +24,9 @@
     protected override void OnInitialized()
     {
         var request = HttpContextAccessor.HttpContext!.Request;
-        if (request.GetRefererIfSameOrigin() is Uri referer && referer != request.GetUri())
+        if (request.GetReferrerIfSameOrigin() is Uri referrer && referrer != request.GetUri())
         {
-            returnUrl = referer.PathAndQuery;
+            returnUrl = referrer.PathAndQuery;
         }
     }
 }
diff --git a/Groceries/Stores/NewStorePage.razor b/Groceries/Stores/NewStorePage.razor
index d34ef34..1b19c08 100644
--- a/Groceries/Stores/NewStorePage.razor
+++ b/Groceries/Stores/NewStorePage.razor
@@ -19,9 +19,9 @@
     protected override void OnInitialized()
     {
         var request = HttpContextAccessor.HttpContext!.Request;
-        if (request.GetRefererIfSameOrigin() is Uri referer && referer != request.GetUri())
+        if (request.GetReferrerIfSameOrigin() is Uri referrer && referrer != request.GetUri())
         {
-            returnUrl = referer.PathAndQuery;
+            returnUrl = referrer.PathAndQuery;
         }
     }
 }
diff --git a/Groceries/Transactions/TransactionItemForm.razor b/Groceries/Transactions/TransactionItemForm.razor
index 31d47ea..27d14ed 100644
--- a/Groceries/Transactions/TransactionItemForm.razor
+++ b/Groceries/Transactions/TransactionItemForm.razor
@@ -97,17 +97,14 @@
         items = await dbContext.Items
             .OrderBy(item => item.Brand)
             .ThenBy(item => item.Name)
-            .GroupJoin(
+            .LeftJoin(
                 dbContext.ItemPurchases.Where(purchase => purchase.IsLastPurchase),
                 item => item.Id,
                 lastPurchase => lastPurchase.ItemId,
-                (item, purchases) => new { item, purchases })
-            .SelectMany(
-                group => group.purchases.DefaultIfEmpty(),
-                (group, lastPurchase) => new ItemModel(
-                    group.item.Id,
-                    group.item.Brand,
-                    group.item.Name,
+                (item, lastPurchase) => new ItemModel(
+                    item.Id,
+                    item.Brand,
+                    item.Name,
                     lastPurchase != null ? lastPurchase.Price : null,
                     lastPurchase != null ? lastPurchase.Quantity : null))
             .ToArrayAsync();