EF Core 10 中的新增功能

EF Core 10(EF10)是 EF Core 9 之后的下一个版本,计划在 2025 年 11 月发布。

EF10 以预览版的形式提供。 请参阅 .NET 10 发行说明 获取有关最新预览版的信息。 本文将在提供新的预览版时更新。

提示

可通过从 GitHub 下载示例代码来运行和调试示例。 下面的每个部分都链接到特定于该部分的源代码。

EF10 需要 .NET 10 SDK 才能生成,并且需要运行 .NET 10 运行时。 EF10 不会在早期 .NET 版本上运行,也不会在 .NET Framework 上运行。

提示

更新了每个预览版的新增功能文档。 已将所有示例设置为使用 EF10 日常版本,与最新预览版相比,这通常需要额外几周时间来完成工作。 强烈建议在测试新功能时使用日常版本,以便不会针对过时位执行测试。

LINQ 和 SQL 翻译

其他查询改进

  • DateOnly.ToDateTime(timeOnly) 的翻译(#35194,由 @mseada94贡献)。
  • 针对多个连续 LIMIT 的优化 (#35384),由 @ranma42 贡献。
  • 针对在 ICollection<T> 上使用 Count 操作的优化 (#35381),由 @ChrisJollyAU 贡献。

ExecuteUpdateAsync 现接受常规的非表达式 lambda

ExecuteUpdateAsync 可用于表示数据库中的任意更新操作。 在以前的版本中,通过表达式树参数提供对数据库行执行的更改;这使得动态生成这些更改非常困难。 例如,假设我们要更新博客的浏览量,但根据条件还需要更新其名称。 由于 setters 参数是表达式树,因此需要编写以下代码:

// 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);

手动创建表达式树非常复杂且容易出错,并且使此常见方案比应该的要困难得多。 从 EF 10 开始,现在可以改为编写以下代码:

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

感谢 @aradalvand 提出并推动此次更改(在 #32018)。