如何让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
相关产品推荐
相关产品推荐

