如何在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
相关产品推荐
相关产品推荐

