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

.NET Core 2.1迁移至.NET7:EF Core DbQuery替代方案咨询

EF Core 7 替代 DbQuery/Query 的迁移方案

EF Core 3.0 起就弃用了 DbQuery<T> 和 modelBuilder.Query<T>,EF Core 7 中完全移除了这些 API,需要改用 无键实体(Keyless Entity) 配合 DbSet<T> 来处理视图、表值函数这类无主键的数据源。以下是针对你代码的具体修改步骤:

1. 替换 DbQuery 为 DbSet

将所有 DbQuery<T> 类型的属性替换为 DbSet<T>:

public DbSet<KonfiguraceZona> QZona { get; set; }
public DbSet<KonfiguraceUzivatel> QKonfiguraceUzivatel { get; set; }
public DbSet<KonfiguraceDepo> QKonfiguraceDepo { get; set; }

public DbSet<StatusDepo> FStatusDepo { get; set; }
public DbSet<StatusNakladac> FStatusNakladac { get; set; }
public DbSet<StatusZona> FStatusZona { get; set; }

2. 配置无键实体与视图映射

在 OnModelCreating 中,将 modelBuilder.Query<T>() 替换为 modelBuilder.Entity<T>().HasNoKey(),并保留视图映射:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 视图映射:标记为无键实体,绑定到对应视图
    modelBuilder.Entity<KonfiguraceZona>()
        .HasNoKey()
        .ToView("QZona");

    modelBuilder.Entity<KonfiguraceUzivatel>()
        .HasNoKey()
        .ToView("QKonfiguraceUzivatel");

    modelBuilder.Entity<KonfiguraceDepo>()
        .HasNoKey()
        .ToView("QKonfiguraceDepo");

    // 无绑定数据源的无键实体(原 Query<T> 无配置场景)
    modelBuilder.Entity<AktivniRelaceUzivatele>()
        .HasNoKey();

    // ... 其他配置
}

3. 处理表值函数调用

针对你用 FromSql 调用的表值函数,有两种推荐方案:

方案一:兼容原有写法(使用 FromSqlRaw)

EF Core 7 中 FromSql 已被标记为过时,推荐使用 FromSqlRaw(参数化查询)或 FromSqlInterpolated(字符串插值自动参数化),确保SQL注入安全:

// 使用 FromSqlRaw 传递参数
Depos = db.FStatusDepo.FromSqlRaw("SELECT * FROM [dbo].[FStatusDepo] ({0})", uzivatelId).ToList();
Zonas = db.FStatusZona.FromSqlRaw("SELECT * FROM [dbo].[FStatusZona] ({0})", uzivatelId).ToList();
Nakladacs = db.FStatusNakladac.FromSqlRaw("SELECT * FROM [dbo].[FStatusNakladac] ({0})", uzivatelId).ToList();

// 或者使用 FromSqlInterpolated(更简洁,自动参数化)
Depos = db.FStatusDepo.FromSqlInterpolated($"SELECT * FROM [dbo].[FStatusDepo] ({uzivatelId})").ToList();

方案二:映射表值函数(更优雅的强类型调用)

EF Core 7 支持直接映射数据库表值函数,通过定义 DbFunction 实现强类型调用:

  1. 在你的 DbContext 中定义函数:
[DbFunction("FStatusDepo", Schema = "dbo")]
public IQueryable<StatusDepo> FStatusDepo(int uzivatelId)
    => FromExpression(() => FStatusDepo(uzivatelId));

[DbFunction("FStatusNakladac", Schema = "dbo")]
public IQueryable<StatusNakladac> FStatusNakladac(int uzivatelId)
    => FromExpression(() => FStatusNakladac(uzivatelId));

[DbFunction("FStatusZona", Schema = "dbo")]
public IQueryable<StatusZona> FStatusZona(int uzivatelId)
    => FromExpression(() => FStatusZona(uzivatelId));
  1. 调用时直接使用强类型方法:
Depos = db.FStatusDepo(uzivatelId).ToList();
Zonas = db.FStatusZona(uzivatelId).ToList();
Nakladacs = db.FStatusNakladac(uzivatelId).ToList();

这种方式无需手写SQL,更符合EF Core的强类型风格,同时自动处理参数化。


内容的提问来源于stack exchange,提问作者Vojtěch Dohnal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:32:44