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

如何在Entity Framework Core中用未注册自定义模型执行原生SQL查询?

在Entity Framework Core中用自定义模型接收原生SQL查询结果

当然可以实现!EF Core其实提供了几种灵活的方式来完成你想要的操作——用未在DbContext中定义为DbSet的自定义模型接收原生SQL查询的结果,下面分版本和场景给你详细说明:

1. EF Core 7.0+:直接使用SqlQuery(最接近EF6的方式)

EF Core 7.0引入了Database.SqlQuery<T>方法,和你熟悉的EF6用法几乎完全一致,不需要额外配置自定义模型,直接就能用它来返回自定义模型列表:

首先定义你的自定义模型:

public class MyModel
{
    public int OrderID { get; set; }
    public string CustomerName { get; set; }
}

然后执行查询:

List<MyModel> data = context.Database.SqlQuery<MyModel>(@"
    SELECT Orders.OrderID, Customers.CustomerName 
    FROM Orders 
    INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
").ToList();

如果需要带参数(必须优先用参数化查询避免SQL注入),可以这样写:

var customerIdParam = new SqlParameter("@CustomerId", 123);

var data = context.Database.SqlQuery<MyModel>(@"
    SELECT Orders.OrderID, Customers.CustomerName 
    FROM Orders 
    INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID
    WHERE Customers.CustomerID = @CustomerId;",
    customerIdParam
).ToList();

2. EF Core 3.0~6.x:使用无键实体 + FromSqlRaw/FromSqlInterpolated

在EF Core 7.0之前,你需要先把自定义模型配置为无键实体,然后通过Set<T>来调用原生SQL查询:

第一步:配置无键实体

在你的DbContext的OnModelCreating方法中,添加对自定义模型的配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 将MyModel配置为无键实体,只能用于查询
    modelBuilder.Entity<MyModel>().HasNoKey();
}

第二步:执行查询

用FromSqlRaw执行原生SQL(适合静态SQL或手动参数化):

var data = context.Set<MyModel>()
    .FromSqlRaw(@"
        SELECT Orders.OrderID, Customers.CustomerName 
        FROM Orders 
        INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
    ")
    .ToList();

如果需要动态参数,推荐用FromSqlInterpolated(它会自动处理参数化,避免SQL注入):

int targetCustomerId = 123;

var data = context.Set<MyModel>()
    .FromSqlInterpolated($@"
        SELECT Orders.OrderID, Customers.CustomerName 
        FROM Orders 
        INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID
        WHERE Customers.CustomerID = {targetCustomerId};
    ")
    .ToList();

关键注意事项

  • 列名匹配:SQL查询返回的列名必须和自定义模型的属性名一致,或者可以通过SQL别名来映射(比如SELECT Orders.OrderID AS OrderNumber ...,对应模型的public int OrderNumber { get; set; })。
  • 无键实体限制:用HasNoKey配置的模型只能用于查询,不能执行增删改操作。
  • SQL注入防护:永远不要直接拼接用户输入到SQL语句中,优先使用参数化查询(FromSqlInterpolated或带SqlParameter的SqlQuery/FromSqlRaw)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:23:29