You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Entity Framework Core 9中映射多语句表值函数?

EF Core 映射多语句表值函数(返回非实际存在的表)

问题背景

官方文档未覆盖多语句表值函数的配置场景,现需实现EF Core对这类函数的映射——函数返回的表并非数据库中实际存在的物理表。

测试用SQL多语句表值函数

CREATE FUNCTION [dbo].[fn_multi_statement_test]
(
    @p1 INT
)
RETURNS @OutputTable TABLE
(
    [Id] INT,
    [Name] NVARCHAR(50)
)
AS
BEGIN
    DECLARE @Apple AS TABLE
    (
        [Name] NVARCHAR(50)
    )

    INSERT INTO @Apple ([Name]) SELECT 'Apple'

    DECLARE @Pear AS TABLE
    (
        [Name] NVARCHAR(50)
    )

    INSERT INTO @Pear ([Name]) SELECT 'Pear'

    INSERT INTO @OutputTable ([Id], [Name]) SELECT @p1, [Name] FROM @Apple
    INSERT INTO @OutputTable ([Id], [Name]) SELECT @p1, [Name] FROM @Pear
RETURN
END;

现有EF配置(存在疑问)

// MultiStatementTest.cs
public class MultiStatementTest
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// Context.OnModelCreatingPartial.cs
public partial class Context
{
    public IQueryable<MultiStatementTest> fn_multi_statement_test(int p1)
    {
        return FromExpression(() => fn_multi_statement_test(p1));
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        // 疑问:此处不需要映射到实际表,该如何配置?
        // modelBuilder.Entity<MultiStatementTest>().ToTable(?);
        
        modelBuilder
        .HasDbFunction(typeof(Context).GetMethod(nameof(fn_multi_statement_test), new[] { typeof(int) }))
        .HasName("fn_multi_statement_test")
        .HasSchema("dbo");
    }
}

解决方案

核心思路:MultiStatementTest只是承载函数返回结果的DTO,并非数据库物理表,因此无需配置表映射,只需标记其为无键实体即可。

修改后的EF配置代码

// Context.OnModelCreatingPartial.cs
public partial class Context
{
    public IQueryable<MultiStatementTest> fn_multi_statement_test(int p1)
    {
        return FromExpression(() => fn_multi_statement_test(p1));
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        // 配置为无键实体,告知EF Core该类型不对应物理表
        modelBuilder.Entity<MultiStatementTest>().HasNoKey();

        // 保持数据库函数的映射配置不变
        modelBuilder
            .HasDbFunction(typeof(Context).GetMethod(nameof(fn_multi_statement_test), new[] { typeof(int) }))
            .HasName("fn_multi_statement_test")
            .HasSchema("dbo");
    }
}

配置说明

  1. HasNoKey():该方法告诉EF Core,MultiStatementTest类型没有主键,也不关联数据库中的任何物理表,仅用于承载查询结果(包括表值函数的返回值)。
  2. 移除ToTable():完全不需要配置表映射,因为该类型并非表实体。

使用示例

在业务代码中直接调用上下文的方法即可,EF Core会自动转换为对应的SQL函数调用:

using var context = new Context();
var functionResults = context.fn_multi_statement_test(123).ToList();

生成的SQL查询示例:

SELECT [m].[Id], [m].[Name]
FROM [dbo].[fn_multi_statement_test](123) AS [m]

内容的提问来源于stack exchange,提问作者User28487024

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:27:38