.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 实现强类型调用:
- 在你的 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));
- 调用时直接使用强类型方法:
Depos = db.FStatusDepo(uzivatelId).ToList(); Zonas = db.FStatusZona(uzivatelId).ToList(); Nakladacs = db.FStatusNakladac(uzivatelId).ToList();
这种方式无需手写SQL,更符合EF Core的强类型风格,同时自动处理参数化。
内容的提问来源于stack exchange,提问作者Vojtěch Dohnal
相关产品推荐
相关产品推荐

