You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Entity Framework Core 2.1中执行SQL查询?

在EF Core 2.1中执行非DbSet的原生SQL查询

你提到的问题确实是EF Core和EF6的一个关键区别——EF6的Database.SqlQuery可以直接执行返回任意类型的原生SQL,但EF Core 2.1的FromSql仅绑定到DbSet<T>。下面给你几种可行的解决方案:

方案1:创建一个“虚拟”DbSet映射结果类型

如果你的查询返回的是简单类型(比如string)或者自定义的结果模型,可以在DbContext中定义一个对应的DbSet<T>,即使这个类型没有对应的数据库表。

比如,先定义一个包装类来接收查询结果:

public class TitleResult
{
    public string Title { get; set; }
}

然后在你的DbContext里添加这个DbSet:

public DbSet<TitleResult> TitleResults { get; set; }

接下来就可以用FromSql执行查询了,注意要确保查询的列名和类的属性名匹配:

var titles = context.TitleResults.FromSql("SELECT a.title AS Title FROM a JOIN b ON b.Id = a.aId WHERE b.Status = 10").ToList();

方案2:直接使用ADO.NET原生操作

如果你不想额外定义DbSet,可以直接通过DbContext的数据库连接来执行原始SQL,这和传统的ADO.NET操作类似:

var results = new List<string>();

using (var command = context.Database.GetDbConnection().CreateCommand())
{
    command.CommandText = "SELECT a.title FROM a JOIN b ON b.Id = a.aId WHERE b.Status = 10";
    
    // 确保连接打开(如果还没打开的话)
    if (command.Connection.State != System.Data.ConnectionState.Open)
    {
        command.Connection.Open();
    }

    using (var reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            // 读取第一列的值(对应title)
            results.Add(reader.GetString(0));
        }
    }
}

return results;

这种方法的好处是完全灵活,不需要依赖EF Core的实体映射,但需要手动处理数据读取和连接管理。

注意事项(针对EF Core 2.1)

  • EF Core 3.0及以后版本支持无键实体类型(通过[Keyless]特性或HasNoKey()配置),可以更优雅地处理这类无表的查询结果,但2.1版本还没有这个功能,所以上面两种是最适合你的方案。
  • 使用FromSql时,确保SQL语句的列名和实体类的属性名一致,否则需要用AS关键字重命名列。

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

火山引擎 最新活动