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

如何让EF中表值函数的返回类型为无映射类型以避免冗余表?

问题描述

调用表值函数时,返回值要求为IQueryable<T>,示例代码如下:

public IQueryable<AlbumsByGenre> ufn_AlbumsByGenre_ITVF(int genreId)
    => FromExpression(() => ufn_AlbumsByGenre_ITVF(genreId));

对应的SQL表值函数返回的是多表关联的组合结果,并非数据库中已存在的实体表:

CREATE FUNCTION dbo.ufn_AlbumsByGenre_ITVF(@GenreId int)
RETURNS TABLE
AS
RETURN(  
    SELECT 
      ar.ArtistName,
      al.AlbumName,
      g.Genre
    FROM Genres g 
      INNER JOIN Albums al
        ON g.GenreId = al.GenreId 
      INNER JOIN Artists ar 
        ON al.ArtistId = ar.ArtistId
    WHERE g.GenreId = @GenreId
);

若为返回类型AlbumsByGenre创建实体类,EF会自动在数据库中生成冗余的AlbumsByGenre表,请问如何设置返回类型为无映射类型,避免生成这类多余表?

解决方案

当然可以,以下是几种可行的实现方式:

1. 用[NotMapped]标记实体类

直接在返回类型的类上添加[NotMapped]特性,明确告知EF该类无需映射到数据库表:

using System.ComponentModel.DataAnnotations.Schema;

[NotMapped]
public class AlbumsByGenre
{
    public string ArtistName { get; set; }
    public string AlbumName { get; set; }
    public string Genre { get; set; }
}

2. 在OnModelCreating中配置忽略映射

如果不想修改实体类代码,可在DbContext的OnModelCreating方法里显式忽略该类型的映射:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Ignore<AlbumsByGenre>();
}

3. 使用无键实体类型(EF Core 3.0+)

EF Core支持无键实体类型,专门用于映射视图、表值函数这类无主键的查询结果,不会生成数据库表,还能明确关联到目标函数:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<AlbumsByGenre>()
        .HasNoKey()
        .ToFunction("ufn_AlbumsByGenre_ITVF");
}

4. 使用C#记录类型(C# 9+)

若返回类型仅用于承载数据、无需修改属性值,可结合[NotMapped]使用记录类型,同样不会生成冗余表:

[NotMapped]
public record AlbumsByGenre(string ArtistName, string AlbumName, string Genre);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:03:50