Die Release-to-Manufacturing-Version (RTM) für .NET 10.0 erschien am 11.11.2025 im Rahmen der .NET Conf 2025 (Abb. 1). Zeitgleich hat Visual Studio 2026 (alias Version 18.0) das Stadium „Stable Version“ erreicht. Mit Visual Studio 2022 kann man .NET-10.0-Anwendungen nicht kompilieren. Zukünftig wird es jedes Jahr zusammen mit dem .NET-Release auch eine neue Hauptversionsnummer von Visual Studio geben.
.NET 10.0 ist eine Long-Term-Support-Version, die ab November 2025 36 Monate unterstützt wird. .NET 8.0 und .NET 9.0 haben noch Support bis November 2026, nachdem Microsoft den Support für die Standard-Term-Support-Versionen auf 24 Monate erhöht hat. Die nächste Version, .NET 11.0, wird im November 2026 erscheinen – dann zusammen mit Visual Studio 2027.

Abb. 1: Scott Hanselman dankt in der Keynote der .NET Conf 2025 allen Community-Mitgliedern, die Beiträge zu .NET 10.0 geleistet haben – darunter auch einigen BASTA!-Sprechern
Entity Framework Core: JSON-Spalten
Seit Entity Framework Core 10.0 Release Candidate 1 wird der Spaltentyp JSON unterstützt. Dieser steht in Microsoft SQL Server 2025 (erschienen am 18.11.2025 [1]) sowie in Azure SQL zur Verfügung.
JSON-Spalten kamen in EF Core zwar schon früher zum Einsatz, etwa um einfache Wertlisten wie List<int> in einer einzelnen Spalte abzulegen (eine Ausnahme bildet PostgreSQL, das solche Datentypen von Haus aus unterstützt) oder um sogenannte Owned Types zu speichern. Bislang wurde dafür jedoch eine nvarchar(max)-Spalte genutzt, kombiniert mit der SQL-Funktion OPENJSON().
Mit den neuen SQL-Server-Versionen greift EF Core nun auf den nativen JSON-Datentyp zurück – vorausgesetzt, die verwendete SQL-Server-Instanz beherrscht diesen auch. Zusätzlich muss EF Core darüber informiert werden, dass JSON-Spalten verfügbar sind. Bei Azure SQL geschieht das, indem statt UseSqlServer() nun UseSqlAzure() verwendet wird.
Beim lokalen Microsoft SQL Server muss man den Kompatibilitätslevel auf 170 (Standard ist 150) setzen (Abb. 2 und 3):
builder.UseSqlServer(connstring, x => x.UseCompatibilityLevel (170));

Abb. 2: Datentypmapping mit SQL Server 2025 bei EF Core im Kompatibilitätslevel 150

Abb. 3: Datentypmapping mit SQL Server 2025 bei EF Core im Kompatibilitätslevel 170
Entity Framework Core: Erweiterungen bei komplexen Typen
Mit Entity Framework Core 8.0 hat Microsoft die Complex Types als modernere und flexiblere Alternative zu den Owned Types eingeführt und in Version 9.0 weiter ausgebaut. Allerdings standen für Complex Types bislang keine JSON-Abbildungen zur Verfügung. Stattdessen wurde jede Property eines Complex Types stets in eine eigene Spalte der Tabelle des übergeordneten Entitätstyps projiziert.
Seit Entity Framework Core 10.0 (ab Release Candidate 1) unterstützen Complex Types nun auch ein JSON-Mapping und können zudem optional sein. Für optionale Complex Types gibt es jedoch eine Einschränkung: Sie müssen mindestens eine verpflichtende Property enthalten. EF Core benötigt dieses Pflichtfeld, um erkennen zu können, ob der Complex Type tatsächlich null ist oder lediglich leere Werte besitzt (Listing 1).
Fehlt das Pflicht-Property, führt das zu folgender Fehlermeldung: „’ShippingAddress’ is mapped to columns by flattening the contained properties into its container’s table; this mapping requires at least one required property – to allow distinguishing between ‘null’ and empty values – but the complex type contains only optional properties. Configure the property with a shadow discriminator by adding a call to ‘HasDiscriminator()’ on the complex property configuration, or map this complex property to a JSON column instead.“
public abstract class Company
{
[Key]
public int CompanyID { get; set; } // Primary Key
[StringLength(50)]
public string Name { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public Address BillingAddress { get; set; } // 1:1
public Address? ShippingAddress { get; set; }
[Required]
public CompanyDescription Description { get; set; } = new(); // 1:1
public List<Management> ManagementSet { get; set; } = new(); // 1:N
}
public record struct Address // record struct für Complex Type
{
public Address()
{
}
//public int AddressID { get; set; } //--> PK bei Complex Types nicht notwendig
public bool AdressExists { get; set; } = true; // bei Optional Complex Type ohne weitere Pflichtfelder (neu in v10.0)
[StringLength(50)]
public string City { get; set; }
[StringLength(50)]
public string Street { get; set; }
[StringLength(10)]
public string Postcode { get; set; }
[StringLength(50)]
public string Country { get; set; }
}
Ein Beispiel für einen Complex Type mit JSON-Mapping könnte so aussehen:
modelBuilder.Entity<Company>(x =>
{
x.ComplexProperty(p => p.Address, p=>p.ToJson()); // 1:1-Mapping. NEU: p=>p.ToJson()
}
Geplant war auch, ein 1:N-Mapping in Complex Types zu ermöglichen. Zwar beschwert sich Entity Framework Core nicht mehr über eine Zeile wie x.ComplexProperty(p => p.ManagementSet, p => p.ToJson()); und es wird auch eine JSON-Spalte ManagementSet in der Tabelle angelegt. Die enthält dann aber nicht die Daten, sondern nur die Eigenschaft Capacity (Abb. 4). Daher funktionieren auch Abfragen über diese Spalte nicht.

Abb. 4: Falsche Persistierung der Menge im komplexen Typ
Entity Framework Core: Vektoren
Microsoft SQL Server 2025 führt einen neuen Spaltentyp vector ein, der speziell für die Speicherung von Vektordaten im Kontext von Ähnlichkeitssuchen und KI-Szenarien entwickelt wurde. In Azure SQL steht dieser Datentyp bereits seit 2024 als Vorschau zur Verfügung und gilt seit Juni 2025 offiziell als produktionsbereit.
Ein Vektor besitzt eine feste Dimension, also eine Anzahl an Elementen. Jedes dieser Elemente wird entweder als 2-Byte- oder 4-Byte-Gleitkommazahl abgelegt. Die Nutzung des kompakten 2-Byte-Formats muss zuvor separat aktiviert werden. Innerhalb des SQL Servers werden Vektoren in einem speziell optimierten Binärformat gespeichert und über entsprechende Datenbanktreiber – etwa Microsoft.Data.SqlClient ab Version 6.1 – effizient übertragen.
In T-SQL und im SQL Server Management Studio (ab Version 21) werden die Vektordaten als JSON-Array visualisiert, z. B.:
DECLARE @v VECTOR(10) = '[0.1, 2, 3.5, 4, 5, 6, 7, 8, 9.9, 10]'; SELECT @v;
Ältere Versionen der Datenbanktreiber übertragen Vektordaten noch im nvarchar(max)-Format und somit als JSON-Struktur. Für Vektoren stehen keinerlei Vergleichsoperatoren oder arithmetische Operationen zur Verfügung – also weder Gleichheits- noch Größenvergleiche noch Rechenoperationen wie Addition, Subtraktion, Multiplikation oder Division. Auch Verkettungen oder zusammengesetzte Zuweisungsoperatoren werden nicht unterstützt. Zudem lassen sich Vektorspalten nicht in speicheroptimierten Tabellen einsetzen.
Mit SQL Server 2025 steht für Vektordaten die Funktion VECTOR_DISTANCE() bereit, über die sich der Abstand zwischen zwei Vektoren berechnen lässt. Dabei können drei verschiedene Distanzverfahren verwendet werden (Abb. 5):
- “cosine”: 0 bis 2 (0 = identisch, 1 = orthogonal, 2 = entgegengesetzt)
- “euclidean”: 0 bis unendlich (0 = identisch)
- “dot”: -1 bis +1 bei normierten Vektoren, -unendlich bis +unendlich bei nicht normierten Vektoren

Abb. 5: Vektordistanzberechnung
Die Funktion VECTOR_SEARCH(), mit der sich der jeweils nächste Nachbar finden lässt, befindet sich weiterhin im Preview-Status.
Seit Entity Framework Core 10.0 Release Candidate 1 können Entwickler:innen Vektorspalten direkt nutzen. Beim Reverse- wie auch beim Forward-Engineering werden diese SQL-Server-Spalten dem .NET-Typ Microsoft.Data.SqlTypes.SqlVector<float> zugeordnet. Dieser stammt aus dem NuGet-Paket Microsoft.Data.SqlClient (ab Version 6.1).
Zusätzlich stellt EF Core eine neue Methode EF.Functions.VectorDistance() bereit, welche die SQL-Server-Funktion VECTOR_DISTANCE() in LINQ-Ausdrücken repräsentiert (Listing 2). Vor EF Core 10.0 war hierfür ein separates NuGet-Paket namens EFCore.SqlServer.VectorSearch erforderlich. Die SQL-Funktion VECTOR_SEARCH() kann jedoch weiterhin nicht direkt in LINQ-Abfragen verwendet werden.
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.Data.SqlTypes;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
namespace EFC_MappingScenarios.Vectors;
public class Texte
{
public int ID { get; set; }
public string Text { get; set; }
[Column(TypeName = "vector(384)")]
public Microsoft.Data.SqlTypes.SqlVector<float> Embedding { get; set; }
}
class Context : DbContext
{
public DbSet<Texte> TexteSet { get; set; }
bool logActive = false;
void Log(string message)
{
if (logActive) CUI.PrintAlternatingColor(message);
}
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
builder.EnableSensitiveDataLogging(true).EnableDetailedErrors();
string connstring = Settings.ConnectionStringSQL2025 + @$";Database=EFC_MappingScenarios_" + nameof(EFC_MappingScenarios.Vectors);
builder.UseSqlServer(connstring, x => x.UseNetTopologySuite().UseCompatibilityLevel(170)).LogTo(Log, new[] { RelationalEventId.CommandExecuted }); // WICHTIG für JSON-Spalten: 170
}
}
class Client
{
// https://www.bundesregierung.de/breg-de/bundesregierung/bundeskabinett?utm_source=chatgpt.com
static OrderedDictionary<string, string> Bundesregierung2025 = new() {
{ "Friedrich Merz", "Bundeskanzler" }, { "Lars Klingbeil", "Bundesminister der Finanzen" }, { "Alexander Dobrindt", "Bundesminister des Innern" }, { "Dr. Johann Wadephul", "Bundesminister des Auswärtigen" }, { "Boris Pistorius", "Bundesminister der Verteidigung" }, { "Katherina Reiche", "Bundesministerin für Wirtschaft und Energie" }, { "Dorothee Bär", "Bundesministerin für Forschung, Technologie und Raumfahrt" }, { "Dr. Stefanie Hubig", "Bundesministerin der Justiz und für Verbraucherschutz" }, { "Karin Prien", "Bundesministerin für Bildung, Familie, Senioren, Frauen und Jugend" }, { "Bärbel Bas", "Bundesministerin für Arbeit und Soziales" }, { "Dr. Karsten Wildberger", "Bundesminister für Digitales und Staatsmodernisierung" }, { "Patrick Schnieder", "Bundesminister für Verkehr" }, { "Carsten Schneider", "Bundesminister für Umwelt, Klimaschutz, Naturschutz und nukleare Sicherheit" }, { "Nina Warken", "Bundesministerin für Gesundheit" }, { "Alois Rainer", "Bundesminister für Landwirtschaft, Ernährung und Heimat" }, { "Reem Alabali-Radovan", "Bundesministerin für wirtschaftliche Zusammenarbeit und Entwicklung" }, { "Verena Hubertz", "Bundesministerin für Wohnen, Stadtentwicklung und Bauwesen" }, { "Thorsten Frei", "Bundesminister für besondere Aufgaben / Chef des Bundeskanzleramtes" }
};
public static void Run()
{
CUI.Demo(nameof(EFC_MappingScenarios.Vectors));
using (var ctx = new Context())
{
CUI.Yellow("Model: " + ctx.Model.GetType().FullName);
Util.RecreateDB(ctx);
#region ---------------------- Vektor-Daten anlegen
CUI.Head(ctx.Database.ProviderName + ": Erstelle Datensätze mit Vektor-Spalte (Lokale Vektorisierung dauert etwas...)");
foreach (var person in Bundesregierung2025)
{
CUI.BusyIndicator();
var dt = new Texte();
ctx.TexteSet.Add(dt);
dt.Text = person.Key + " ist " + person.Value;
var values = EmbeddingsUtil.Get("passage:" + dt.Text);
dt.Embedding = new SqlVector<float>(values);
Console.WriteLine(dt.Text + " -> " + dt.Embedding.Length);
}
var c2 = ctx.SaveChanges();
Console.WriteLine($"{c2} Datensätze gespeichert");
#endregion
#region ---------------------- Vektor-Daten abfragen
CUI.Head(ctx.Database.ProviderName + ": Vektorsuche");
Suche("Dr. Karsten Wildberger");// exakte Suche
Suche("Karsten");// nur Vorname
Suche("Carsten Wilberger");// absichtlich falsch geschrieben, damit es nicht exakt passt
Suche("Kriegsminister");
Suche("Kassenwart");
Suche("Unfug");
Suche("Der beliebteste Politiker im Kabinett");
Suche("Der unbeliebteste Politiker im Kabinett");
#endregion
CUI.PanelGreen("=== DONE");
}
}
// https://learn.microsoft.com/en-us/sql/t-sql/functions/vector-distance-transact-sql?view=sql-server-ver17
// cosine - Cosine distance 0 bis 2 (0 = identisch, 1 = orthogonal, 2 = entgegengesetzt)
// euclidean - Euclidean distance 0 bis unendlich (0 = identisch)
// dot - (Negative)Dot product (-1 bis +1 bei normierten Vektoren, -unendlich bis +unendlich bei nicht normierten Vektoren)
private static void Suche(string suchBegriff, string distanzVerfahren = "cosine")
{
using var ctx = new Context();
CUI.Yellow("Suche ähnlichste Einträge zu: " + suchBegriff);
var sqlVector = new SqlVector<float>(EmbeddingsUtil.Get(suchBegriff));
var result = ctx.TexteSet
.OrderBy(b => EF.Functions.VectorDistance(distanzVerfahren, b.Embedding, sqlVector))
.Take(5)
.Select(b => new { Object = b, Distance = EF.Functions.VectorDistance(distanzVerfahren, b.Embedding, sqlVector) })
.ToList();
foreach (var b in result)
{
CUI.Green(b.Object.ID + ": " + b.Object.Text + " -> Distanz: " + Math.Round(b.Distance, 2));
}
}
}
Im Beispiel sind die Mitglieder des Bundeskabinetts (Stand November 2025) in einer Tabelle gespeichert, wobei Name und Zuständigkeit in einer Textspalte erfasst sind. Darauf basierend werden verschiedene Ähnlichkeitssuchen über EF.Functions.VectorDistance() ausgeführt.
Die in Abbildung 6 gezeigten Ergebnisse wurden mit dem Embedding-Modell Multilingual-E5-small erzeugt, das 384 Dimensionen besitzt. Das von Microsoft-Mitarbeitenden entwickelte Modell ist Open Source, lokal einsetzbar und benötigt keine Cloud. Da E5 Texte vieler Sprachen in einen gemeinsamen semantischen Vektorraum überführt, funktionieren Ähnlichkeitsvergleiche auch über Sprachgrenzen hinweg. Zu Begriffen wie „Kassenwart“ oder „Kriegsminister“ liefert das Modell korrekt die Finanz- bzw. Verteidigungsminister. Welche Mitglieder der Regierung besonders beliebt oder unbeliebt sind, kann das Embedding-Modell hingegen naturgemäß nicht beurteilen.

Abb. 6: Ausgabe des obigen Listings
Entity Framework Core: Optionen für Parametermengen
Ein Performancethema in Entity Framework Core, bei dem Microsoft seit Jahren verschiedene Strategien ausprobiert, ist die Übergabe von Parametermengen von .NET an das Datenbankmanagementsystem, z. B. eine Liste von Orten, zu denen passende Datensätze gesucht werden:
List<string> destinations = new List<string> { "Berlin", "New York", "Paris" };
var flights = ctx.Flights
.Where(f => destinations.Contains(f.Destination))
.Take(5).ToList();
In den Entity-Framework-Core-Versionen 1.0 bis 7.0 wurden die Werte aus der Menge destinations einzeln als statische Werte übergeben:
SELECT TOP(@p) [f].[FlightNo], [f].[Airline], [f].[Departure], [f].[Destination], [f].[FlightDate], [f].[FreeSeats], [f].[Memo], [f].[NonSmokingFlight], [f].[Pilot_PersonID], [f].[Seats], [f].[Timestamp] FROM [Operation].[Flight] AS [f] WHERE [f].[NonSmokingFlight] = CAST(1 AS bit) AND [f].[FlightDate] > GETDATE() AND [f].[FreeSeats] > CAST(0 AS smallint) AND [f].[Destination] IN (N'Berlin', N'New York', N'Paris')
Das sorgte aber im Datenbankmanagementsystem für viele verschiedene Ausführungspläne. Seit Version 8.0 übergibt Entity Framework Core die Liste als ein JSON-Array, das im SQL-Befehl mit OPENJSON() gespalten wird (Listing 3). Das erschwerte dem Datenbankmanagementsystem die Optimierung der Ausführungspläne, weil die Anzahl der Parameter nicht mehr bekannt war.
SELECT TOP(@p) [f].[FlightNo], [f].[Airline], [f].[Departure], [f].[Destination], [f].[FlightDate], [f].[FreeSeats], [f].[Memo], [f].[NonSmokingFlight], [f].[Pilot_PersonID], [f].[Seats], [f].[Timestamp] FROM [Operation].[Flight] AS [f] WHERE [f].[NonSmokingFlight] = CAST(1 AS bit) AND [f].[FlightDate] > GETDATE() AND [f].[FreeSeats] > CAST(0 AS smallint) AND [f].[Destination] IN ( SELECT [d].[value] FROM OPENJSON(@destinations) WITH ([value] nvarchar(30) '$') AS [d] )
Seit Entity Framework Core 9.0 besteht die Möglichkeit, über EF.Constant() oder den globalen Aufruf TranslateParameterizedCollectionsToConstants() in der OnConfiguring()-Methode der Kontextklasse wieder auf das frühere Übersetzungsverhalten zurückzuschalten:
var flights1 = ctx.Flights .Where(f => EF.Constant(destinations).Contains(f.Destination)) .Take(5).ToList();
Beim geänderten Standard konnten Entwickler:innen dann im Einzelfall mit EF.Parameter() das JSON-Array übergeben. In der aktuellen Version 10.0 des OR-Mappers hat Microsoft abermals einen neuen Standard implementiert, nämlich die Einzelübergabe der Werte jeweils als eigene Parameter. Diesen SQL-Befehl erzeugt Entity Framework Core im vorangegangenen Beispiel mit drei Städten:
SELECT TOP(@p) [f].[FlightNo], [f].[Airline], [f].[Departure], [f].[Destination], [f].[FlightDate], [f].[FreeSeats], [f].[Memo], [f].[NonSmokingFlight], [f].[Pilot_PersonID], [f].[Seats], [f].[Timestamp] FROM [Operation].[Flight] AS [f] WHERE [f].[NonSmokingFlight] = CAST(1 AS bit) AND [f].[FlightDate] > GETDATE() AND [f].[FreeSeats] > CAST(0 AS smallint) AND [f].[Destination] IN (@destinations1, @destinations2, @destinations3)
Im ausführlichen Test stellt man fest, dass EF Core nicht immer genau die gleiche Anzahl Parameter erzeugt, wie es Werte gibt. Stattdessen rundet Entity Framework Core zur Vermeidung des Anlegens von zu vielen Ausführungsplänen ab sechs Parametern auf 10er-Blöcke auf, d. h. für sechs Werte werden zehn Parameter erzeugt, wobei die letzten Parameter immer den gleichen Wert erhalten (Listing 4).
[Parameters=[@p='5', @destinations1='Berlin' (Size = 30), @destinations2='New York' (Size = 30), @destinations3='Paris' (Size = 30), @destinations4='Rome' (Size = 30), @destinations5='Munich' (Size = 30), @destinations6='London' (Size = 30), @destinations7='London' (Size = 30), @destinations8='London' (Size = 30), @destinations9='London' (Size = 30), @destinations10='London' (Size = 30)], CommandType='Text', CommandTimeout='300'] SELECT TOP(@p) [f].[FlightNo], [f].[Airline], [f].[Departure], [f].[Destination], [f].[FlightDate], [f].[FreeSeats], [f].[Memo], [f].[NonSmokingFlight], [f].[Pilot_PersonID], [f].[Seats], [f].[Timestamp] FROM [Operation].[Flight] AS [f] WHERE [f].[NonSmokingFlight] = CAST(1 AS bit) AND [f].[FlightDate] > GETDATE() AND [f].[FreeSeats] >= CAST(20 AS smallint) AND [f].[FreeSeats] <= CAST(200 AS smallint) AND [f].[Destination] IN (@destinations1, @destinations2, @destinations3, @destinations4, @destinations5, @destinations6, @destinations7, @destinations8, @destinations9, @destinations10)
Entwickler:innen können bei Bedarf weiterhin das bisherige Verhalten über EF.Constant() bzw. EF.Parameter() erzwingen. Welche Variante sinnvoll ist, hängt auch davon ab, wie stark sich die Anzahl der Werte zur Laufzeit verändert.
Auf globaler Ebene lässt sich das Standardverhalten über UseParameterizedCollectionMode(ParameterTranslationMode.Constant) in OnModelCreating() in der Kontextklasse anpassen. Als zulässige Einstellwerte stehen Constant, Parameter und MultipleParameters zur Verfügung. Die erst mit EF Core 9.0 eingeführte Methode TranslateParameterizedCollectionsToConstants() existiert zwar weiterhin, ist jedoch inzwischen mit [Obsolete] gekennzeichnet.
Entity Framework Core: Analyzer warnt vor möglicher SQL Injection
Der OR-Mapper liefert seit Release Candidate 2 einen Code-Analyzer mit, der Entwickler:innen warnt, wenn man beim Aufruf von FromSqlRaw(), SqlQueryRaw<T>() oder ExecuteSqlRaw() eine Zeichenkette mit Pluszeichen oder String-Interpolation zusammensetzt. Die Warnung lautet: „Method inserts concatenated strings directly into the SQL, without any protection against SQL injection. Consider using ‘FromSql’ instead, which protects against SQL injection, or make sure that the value is sanitized and suppress the warning.“
Der Analyzer erkennt die Zeichenkettenzusammensetzung, wenn sie direkt im Parameter des Methodenaufrufs stattfindet, nicht aber, wenn eine zuvor zusammengesetzte Zeichenkette übergeben wird (Abb. 7).

Abb. 7: Der Analyzer erkennt einige (siehe grüne Schlangenlinien), aber leider nicht alle diese gefährlichen SQL-Injektionen
Verbesserungen bei ASP.NET Core
ASP.NET Core führte in .NET 10.0 Release Candidate 1 neue Metriken für ASP.NET Core Identity zur Überwachung der Benutzerverwaltung ein, z. B. aspnetcore.identity.user.create.duration, aspnetcore.identity.sign_in.sign_ins und aspnetcore.identity.sign_in.two_factor_clients_forgotten.
Zur Validierung von Instanzen von Klassen und Records in Blazor, die Microsoft schon in der Preview-Phase von .NET 10.0 verbessert hatte, gibt es seit Release Candidate 1 drei weitere Neuerungen:
- Validierungsannotationen können auch für Typen und nicht nur wie bisher für Properties definiert werden.
- Mit der neuen Annotation [SkipValidation] können Entwickler:innen Typen und Properties von der Validierung ausschließen.
- Ebenso werden alle mit [JsonIgnore] annotierten Properties nicht mehr validiert.
Der Persistent Component State in Blazor, den es seit .NET 10.0 Preview 6 gibt, funktioniert nun auch beim Einsatz der Enhanced Navigation beim statischen Server-side Rendering.
Verbesserungen bei MAUI
Mit der Einstellung SafeAreaEdges=”None” können .NET-MAUI-Fenster nun auch auf Android und iOS in den ansonsten geschützten Navigationsbereichen oben und unten rendern. Alternative Werte sind “Container” (schützt vor Systembars und Notch), “SoftInput” (schützt nur vor der Tastatur) und “All” (kombiniert “Container” und “SoftInput”) (Abb. 8).

Abb. 8: Safe Area Edges auf iOS. Quelle: Microsoft .NET Conf 2025
Auch bei .NET MAUI gibt es neue Metriken für die Überwachung der Layoutperformance:
- maui.layout.measure_count
- maui.layout.measure_duration
- maui.layout.arrange_count
- maui.layout.arrange_duration
Das Steuerelement <HybridWebView> bietet nun die Ereignisse WebViewInitializing() und WebViewInitialized() zur Anpassung der Initialisierung. Vergleichbare Ereignisse gab es zuvor im Steuerelement <BlazorWebView> (BlazorWebViewInitializing() und BlazorWebViewInitialized()). Das Steuerelement <RefreshView> besitzt nun auch die Eigenschaft IsRefreshEnabled zusätzlich zu IsEnabled.
Seit Preview 7 gibt es den Source Generator für XAML in .NET MAUI. Um diesen Source Generator zu aktivieren, schreibt man seit Release Candidate 2 in die Projektdatei:
<PropertyGroup> <MauiXamlInflator>SourceGen</MauiXamlInflator> </PropertyGroup>
Auch unter Windows kann man nun die Mikrofonberechtigungen abfragen: Permissions.RequestAsync<Permissions.Microphone>()
Verbesserungen bei Windows Forms
Das Windows-Forms-Teams schreibt in seinen Release Notes, dass der in .NET 9.0 eingeführte Dark Mode (Abb. 9) nun nicht mehr den Status „experimentell“ besitzt [2].

Abb. 9: Einige Windows-Forms-Steuerelemente im Dark Mode
Fazit
Es ist Zeit, ein Fazit über die Neuerungen aus allen vier Beiträgen zu .NET 10.0 zu ziehen. Das soll in Form von Listen der High- und Lowlights geschehen. Meine zehn persönlichen Highlights in .NET 10.0 sind:
- Extensions in C#: Damit können Entwickler:innen bestehende, kompilierte Klassen um Instanzmethoden, statische Methoden, Instanz-Properties, statische Properties und Operatoren erweitern
- Semi-Auto Properties in C# mit dem Schlüsselwort field (sind nun offiziell unterstützt)
- C#-Scripting mit File-based Apps im .NET SDK
- Neue LINQ-Operatoren LeftJoin()und RightJoin()in LINQ und EF Core
- Nutzung der SQL-Server-Spaltentypen JSON und VECTOR in EF Core
- JSON-Patch nach RFC 6902 mit NuGet-Paket Microsoft.AspNetCore.JsonPatch.SystemTextJson
- Persistierung von Circuits in Blazor Server und einfachere Festlegung des Persistent Component State via Annotation
- Anpassbarkeit des Verbindungsproblemdialogs bei Blazor Server
- Das NuGet-Paket Microsoft.AspNetCore.OpenApi berücksichtigt XML-Codekommentare bei der Erstellung von OAS-Dokumenten; diese verwenden nun OAS-Version 3.1 und optional YAML statt JSON
- In Windows Forms können Entwickler:innen nun Screenshots von einzelnen Windows-Forms-Fenstern mit einem Screenshotwerkzeug verhindern
Ich sehe auch Enttäuschungen in .NET 10.0:
- Auch wenn Microsoft in .NET 10.0 Verbesserungen gemacht haben will: Das Hot Reloading in Blazor-Anwendungen ist immer noch eine große Enttäuschung, weil es oft abstürzt und man sich fragen muss, ob man mit oder ohne Hot Reloading produktiver coden kann.
- Auch der Blazor-Editor hat in der aktuellen Entwicklungsumgebung Visual Studio 2026 noch viele Macken: Immer wieder sieht man die berüchtigten gelben Balken in der Entwicklungsumgebung, die anzeigen, dass ein Editorfeature gerade abgestürzt ist.
- Die in EF Core 9.0 eingeführte, aber nicht für die Praxis brauchbare Unterstützung des NativeAOT-Compilers, wurde in Version 10.0 nicht einen Deut verbessert.
- Der NativeAOT-Compiler funktioniert auch immer noch nicht für Windows Forms und WPF sowie ASP.NET Core MVC, Razor Pages sowie Blazor auf dem Server (weder für static noch interactive Server-side Rendering).
- Blazor WebAssembly kann immer noch kein vollständiges Multi-Threading, siehe [3] und [4].
- Es gibt weiterhin keinen WYSIWYG-Designer für Blazor. Das sei als Schwäche erwähnt, auch wenn Microsoft schon klargestellt hat, dass es einen solchen Designer nicht liefern wird und viele Entwickler:innen einen solchen Designer nicht vermissen. Es gibt aber genug Menschen, die sich einen Designer wünschen.
- Microsoft unterstützt .NET MAUI immer noch nicht auf dem Linux-Desktop. Aber es gibt eine neue Perspektive: Das an WPF angelehnte, XAML-basierte Open-Source-GUI-Framework Avalonia hat am 11.11.2025 angekündigt, dass man an einer Brücke zwischen .NET MAUI und dem Avalonia-Kern arbeitet, der auf Skia-Rendering basiert [5]. Damit kann .NET MAUI in Zukunft auch auf dem Linux-Desktop und auch im Webbrowser laufen.
Links & Literatur
[1] https://learn.microsoft.com/de-de/sql/sql-server/what-s-new-in-sql-server-2025?view=sql-server-ver17
[2] https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/rc1/winforms.md
[3] https://github.com/dotnet/runtime/issues/68162
[4] https://github.com/dotnet/aspnetcore/issues/54365
[5] https://avaloniaui.net/blog/net-maui-is-coming-to-linux-and-the-browser-powered-by-avalonia
Author
🔍 Frequently Asked Questions (FAQ)
1. Was ist neu in der RTM-Version von .NET 10.0?
Die RTM-Version von .NET 10.0 wurde am 11.11.2025 veröffentlicht und bringt zahlreiche Verbesserungen, insbesondere im Bereich Entity Framework Core. Sie markiert den Beginn des Long-Term Supports für drei Jahre.
2. Wie unterstützt Entity Framework Core 10.0 JSON-Spalten?
EF Core 10.0 nutzt den nativen JSON-Datentyp in SQL Server 2025 und Azure SQL, wenn der Kompatibilitätslevel 170 aktiviert ist. JSON-Mapping erfordert eine entsprechende Konfiguration im EF Core-Code.
3. Welche Neuerungen gibt es bei komplexen Typen in EF Core 10.0?
Komplexe Typen können ab EF Core 10.0 in JSON-Spalten gemappt werden und optional sein. Voraussetzung ist, dass mindestens eine verpflichtende Property vorhanden ist, um zwischen null und leer zu unterscheiden.
4. Was ist der neue Vektor-Datentyp in SQL Server 2025?
Der Vektor-Datentyp speichert numerische Arrays für KI- und Ähnlichkeitssuchen effizient. Er wird durch EF Core 10.0 vollständig unterstützt und mit SqlVector
5. Welche Änderungen gibt es bei Parametermengen in EF Core 10.0?
Ab EF Core 10.0 wird standardmäßig wieder die Übergabe einzelner Parameterwerte genutzt. Ab sechs Werten wird auf 10er-Blöcke aufgerundet, um Ausführungspläne effizienter zu halten.
6. Welche Sicherheitsfunktionen bringt EF Core 10.0?
Ein Code-Analyzer warnt bei potenziellen SQL-Injections, wenn SQL-Strings dynamisch mit FromSqlRaw() oder ähnlichen Methoden zusammengesetzt werden.
7. Welche Neuerungen gibt es in ASP.NET Core mit .NET 10.0?
Neue Metriken zur Überwachung von ASP.NET Core Identity sowie zusätzliche Validierungsoptionen in Blazor wurden eingeführt, z. B. [SkipValidation] und erweiterte Nutzung von [JsonIgnore].
8. Was ist neu in .NET MAUI in Version 10.0?
MAUI unterstützt jetzt Safe-Area-Einstellungen auf Android/iOS sowie neue Metriken für Layout-Performance. Der XAML-Source-Generator ist standardmäßig über



