从Dapper迁移至EF Core:基于FromSql()的简易POCO临时查询问询
很高兴听到你打算从Dapper迁回EF Core!针对你提到的这种执行临时SQL并将结果映射到简易POCO(比如你写的SimpleStringDTO)的场景,EF Core现在有几种非常方便的实现方式,我给你逐一说明:
方法1:用
FromSqlRaw/FromSqlInterpolated临时映射 EF Core 3.0及以上版本支持直接对任意POCO执行原生SQL查询,完全不需要提前在DbContext里注册对应的DbSet。你可以这样写:
// 带参数的原生SQL写法(推荐,防止注入) var sql = "SELECT TargetColumn AS Result FROM YourTable WHERE Filter = @filterParam"; var queryResult = await context.Set<SimpleStringDTO>() .FromSqlRaw(sql, new SqlParameter("@filterParam", "yourFilterValue")) .ToListAsync();
如果想用更简洁的插值字符串,EF Core会自动帮你转换成参数化查询(同样安全):
var filterValue = "yourFilterValue"; var queryResult = await context.Set<SimpleStringDTO>() .FromSqlInterpolated($"SELECT TargetColumn AS Result FROM YourTable WHERE Filter = {filterValue}") .ToListAsync();
小提示:只要你的POCO属性名(比如Result)和SQL返回的列名(或者别名)完全匹配,就能自动完成映射,不需要额外配置。
方法2:EF Core 7.0+专属的
SqlQuery方法 如果你用的是EF Core 7.0或更高版本,官方新增了SqlQuery方法,专门用来处理这种无实体的临时查询,写法更清爽:
var filterParam = new SqlParameter("@filterParam", "yourFilterValue"); var queryResult = await context.SqlQuery<SimpleStringDTO>( "SELECT TargetColumn AS Result FROM YourTable WHERE Filter = @filterParam", filterParam) .ToListAsync();
这个方法不需要借助Set<T>,直接在DbContext实例上调用,对临时查询来说更直观。
方法3:单值场景简化写法
如果你的SQL只返回单个字符串结果(比如SELECT TOP 1 Column FROM ...),甚至不需要创建SimpleStringDTO,直接用ExecuteScalarAsync获取值:
var filterParam = new SqlParameter("@filterParam", "yourFilterValue"); var singleResult = await context.Database.ExecuteScalarAsync<string>( "SELECT TOP 1 TargetColumn FROM YourTable WHERE Filter = @filterParam", filterParam);
额外注意事项
- 确保POCO的属性类型和SQL返回的列类型兼容,比如字符串对应数据库的
VARCHAR/NVARCHAR,避免映射失败。 - 要是你需要映射多字段的复杂结果,只需要创建对应的POCO类,保证属性名和返回列名一致,上面的方法同样适用。
- 如果你会频繁用到某个POCO做查询,也可以在
DbContext里注册public DbSet<SimpleStringDTO> StringResults { get; set; },但临时查询的话完全没必要这么做,用上面的临时映射方法更灵活。
内容的提问来源于stack exchange,提问作者Damien Sawyer
相关产品推荐
相关产品推荐

