Delen via


Wat is er nieuw in EF Core 10?

EF Core 10 (EF10) is de volgende release na EF Core 9 en is gepland voor release in november 2025.

EF10 is beschikbaar als preview-versie. Zie releaseopmerkingen voor .NET 10 voor informatie over de nieuwste preview. Dit artikel wordt bijgewerkt naarmate er nieuwe preview-versies beschikbaar worden gesteld.

Aanbeveling

U kunt de voorbeelden uitvoeren en fouten opsporen door de voorbeeldcode te downloaden van GitHub. Elke sectie hieronder bevat koppelingen naar de broncode die specifiek is voor die sectie.

EF10 vereist dat de .NET 10 SDK wordt gebouwd en dat de .NET 10-runtime moet worden uitgevoerd. EF10 wordt niet uitgevoerd op eerdere .NET-versies en wordt niet uitgevoerd op .NET Framework.

Azure Cosmos DB voor NoSQL

Ondersteuning voor zoeken in volledige tekst

Azure Cosmos DB biedt nu ondersteuning voor zoeken in volledige tekst. Het maakt efficiënte en effectieve zoekopdrachten in tekst mogelijk, evenals het evalueren van de relevantie van documenten voor een bepaalde zoekquery. Het kan worden gebruikt in combinatie met vectorzoekopdrachten om de nauwkeurigheid van reacties in sommige AI-scenario's te verbeteren. EF Core 10 voegt ondersteuning toe voor deze functie, zodat de database kan worden gemodelleerd met eigenschappen met zoeken in volledige tekst en met behulp van zoekfuncties in volledige tekst in query's die gericht zijn op Azure Cosmos DB.

Hier volgt een eenvoudige configuratie van een EF-model voor het inschakelen van zoeken in volledige tekst op een van de eigenschappen:

public class Blog
{
    ...

    public string Contents { get; set; }
}

public class BloggingContext
{
    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>(b =>
        {
            b.Property(x => x.Contents).EnableFullTextSearch();
            b.HasIndex(x => x.Contents).IsFullTextIndex();
        });
    }
}

Zodra het model is geconfigureerd, kunnen we zoekbewerkingen in volledige tekst gebruiken in query's met behulp van methoden in EF.Functions:

var cosmosBlogs = await context.Blogs.Where(x => EF.Functions.FullTextContains(x.Contents, "cosmos")).ToListAsync();

De volgende bewerkingen in volledige tekst worden momenteel ondersteund: FullTextContains, FullTextContainsAll, FullTextContainsAny, . FullTextScore

Zie de documenten voor meer informatie over zoeken in volledige tekst in Cosmos.

EF Core biedt nu ondersteuning RRF voor de functie (Wederzijdse Rank Fusion), die vector-overeenkomsten en zoeken in volledige tekst combineert (hybride zoekopdrachten). Hier volgt een voorbeeldquery met behulp van hybride zoekopdrachten:

float[] myVector = /* generate vector data from text, image, etc. */
var hybrid = await context.Blogs.OrderBy(x => EF.Functions.Rrf(
        EF.Functions.FullTextScore(x.Contents, "database"), 
        EF.Functions.VectorDistance(x.Vector, myVector)))
    .Take(10)
    .ToListAsync();

Zie de documenten voor meer informatie over hybride zoeken in Cosmos.

Vector overeenkomsten zoeken verlaat de preview-fase

In EF9 hebben we experimentele ondersteuning toegevoegd voor vector-overeenkomsten zoeken. In EF Core 10 is ondersteuning voor vector-overeenkomsten zoeken niet meer experimenteel. We hebben ook enkele verbeteringen aangebracht in de functie:

  • EF Core kan nu containers genereren met vectoreigenschappen die zijn gedefinieerd op referentie-entiteiten in eigendom. Containers met vectoreigenschappen die ontworpen zijn voor eigendomcollecties moeten nog steeds op andere manieren worden gemaakt. Ze kunnen echter worden gebruikt in query's.
  • De naam van api's voor het bouwen van modellen is gewijzigd. Een vectoreigenschap kan nu worden geconfigureerd met behulp van de IsVectorProperty methode en vectorindex kan worden geconfigureerd met behulp van de IsVectorIndex methode.

Zie de documenten voor meer informatie over Cosmos Vector Search.

Verbeterde ervaring bij het ontwikkelen van het model

In eerdere versies van EF Core was het ontwikkelen van het model bij het gebruik van Azure Cosmos DB heel pijnlijk. Bij het toevoegen van een nieuwe vereiste eigenschap aan de entiteit zou EF die entiteit niet meer kunnen materialiseren. De reden was dat EF een waarde verwachtte voor de nieuwe eigenschap (omdat deze vereist was), maar het document dat vóór de wijziging werd gemaakt, bevatte deze waarden niet. De tijdelijke oplossing was om de eigenschap eerst als optioneel te markeren, handmatig standaardwaarden voor de eigenschap toe te voegen en pas vervolgens te wijzigen in vereist.

In EF 10 hebben we deze ervaring verbeterd. EF materialiseert nu een standaardwaarde voor een vereiste eigenschap, als er geen gegevens aanwezig zijn in het document, in plaats van te gooien.

LINQ en SQL vertaling

Ondersteuning voor de .NET 10-operators LeftJoin en RightJoin

LEFT JOIN is een algemene en nuttige bewerking bij het werken met EF Core. In eerdere versies was het implementeren van LEFT JOIN in LINQ behoorlijk ingewikkeld, waarvoor SelectMany, GroupJoin- en DefaultIfEmpty-bewerkingen in een specifieke configuratie nodig waren.

.NET 10 voegt eersteklas LINQ-ondersteuning toe voor LeftJoin methode, waardoor deze query's veel eenvoudiger te schrijven zijn. EF Core herkent de nieuwe methode, zodat deze kan worden gebruikt in EF LINQ-query's in plaats van de oude constructie:

var query = context.Students
    .LeftJoin(
        context.Departments,
        student => student.DepartmentID,
        department => department.ID,
        (student, department) => new 
        { 
            student.FirstName,
            student.LastName,
            Department = department.Name ?? "[NONE]"
        });

Notitie

EF 10 ondersteunt ook de analoge RightJoin-operator, die alle gegevens uit de tweede verzameling en alleen de overeenkomende gegevens uit de eerste verzameling bewaart. EF 10 vertaalt dit naar de RIGHT JOIN bewerking in de database.

Zie #12793 en #35367 voor meer informatie.

Overige verbeteringen aan queries

  • Vertaal DateOnly.ToDateTime(timeOnly) (#35194, bijgedragen door @mseada94).
  • Optimaliseer meerdere opeenvolgende LIMITs (#35384, bijgedragen door @ranma42).
  • Optimaliseer het gebruik van Count bewerkingen op ICollection<T> (#35381, bijgedragen door @ChrisJollyAU).
  • Optimaliseren MIN/MAX over DISTINCT (#34699, bijgedragen door @ranma42).
  • Datum-/tijdfuncties vertalen met behulp van DatePart.Microsecond en DatePart.Nanosecond argumenten (#34861).
  • Vereenvoudig parameternamen (bijvoorbeeld van @__city_0 naar city) (#35200).
  • Vertalen COALESCE als ISNULL op SQL Server, voor de meeste gevallen (#34171, bijgedragen door @ranma42).
  • Ondersteuning voor sommige tekenreeksfuncties die char als argumenten nemen (#34999, bijgedragen door @ChrisJollyAU).
  • Ondersteuning MAX/MIN/ORDER BY van het gebruik van decimal op SQLite (#35606, bijgedragen door @ranma42).
  • Ondersteuning voor het projecteren van verschillende typen navigaties (maar hetzelfde type) via voorwaardelijke bewerking (#34589, bijgedragen door @ranma42).

ExecuteUpdateAsync accepteert nu een gewone lambda zonder expressie

De ExecuteUpdateAsync kan worden gebruikt om willekeurige updatebewerkingen in de database uit te drukken. In eerdere versies zijn de wijzigingen die moeten worden uitgevoerd op de databaserijen opgegeven via een parameter voor de expressiestructuur; dit maakte het vrij moeilijk om deze wijzigingen dynamisch te bouwen. Stel dat we de weergaven van een blog willen bijwerken, maar voorwaardelijk ook de naam ervan. Omdat het argument setters een expressiestructuur was, moet code zoals het volgende worden geschreven:

// Base setters - update the Views only
Expression<Func<SetPropertyCalls<Blog>, SetPropertyCalls<Blog>>> setters =
    s => s.SetProperty(b => b.Views, 8);

// Conditionally add SetProperty(b => b.Name, "foo") to setters, based on the value of nameChanged
if (nameChanged)
{
    var blogParameter = Expression.Parameter(typeof(Blog), "b");

    setters = Expression.Lambda<Func<SetPropertyCalls<Blog>, SetPropertyCalls<Blog>>>(
        Expression.Call(
            instance: setters.Body,
            methodName: nameof(SetPropertyCalls<Blog>.SetProperty),
            typeArguments: [typeof(string)],
            arguments:
            [
                Expression.Lambda<Func<Blog, string>>(Expression.Property(blogParameter, nameof(Blog.Name)), blogParameter),
                Expression.Constant("foo")
            ]),
        setters.Parameters);
}

await context.Blogs.ExecuteUpdateAsync(setters);

Het handmatig maken van expressiestructuren is ingewikkeld en foutgevoelig en maakt dit veelvoorkomende scenario veel moeilijker dan het zou moeten zijn. Vanaf EF 10 kunt u nu het volgende schrijven:

await context.Blogs.ExecuteUpdateAsync(s =>
{
    s.SetProperty(b => b.Views, 8);
    if (nameChanged)
    {
        s.SetProperty(b => b.Name, "foo");
    }
});

Dankzij @aradalvand voor het voorstellen en pushen van deze wijziging (in #32018).

Aangepaste standaardbeperkingsnamen

In eerdere versies van EF Core, wanneer u een standaardwaarde voor een eigenschap hebt opgegeven, zou EF Core de database altijd automatisch een beperkingsnaam laten genereren. U kunt nu expliciet de naam opgeven voor standaardwaardebeperkingen voor SQL Server, zodat u meer controle hebt over uw databaseschema.

U kunt nu een beperkingsnaam opgeven bij het definiëren van standaardwaarden in uw modelconfiguratie:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.IsActive)
        .HasDefaultValue(true, "DF_Blog_IsActive");

    modelBuilder.Entity<Post>()
        .Property(p => b.CreatedDate)
        .HasDefaultValueSql("GETDATE()", "DF_Post_CreatedDate");
}

U kunt ook aanroepen UseNamedDefaultConstraints om automatische naamgeving van alle standaardbeperkingen in te schakelen. Als u bestaande migraties hebt, wordt de naam van elke standaardbeperking in uw model gewijzigd bij de volgende migratie die u toevoegt.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.UseNamedDefaultConstraints();
}

Andere verbeteringen

  • Sql Server-scaffolding compatibel maken met Azure Data Explorer (#34832, bijgedragen door @barnuri).
  • Koppel de DatabaseRoot aan het exemplaar van de gescopeerde opties en niet aan de singleton-opties (#34477, bijgedragen door @koenigst).
  • Inline-constanten uit de log verwijderen als gevoelige logging is uitgeschakeld (#35724).
  • Verbeter LoadExtension om correct te werken met dotnet run en lib* benoemde bibliotheken (#35617, bijgedragen door @krwq).
  • Wijzigingen in AsyncLocal-gebruik voor betere luie laadprestaties (#35835, bijgedragen door @henriquewr).