Entity Framework Core提供了DbSet.FromSql()
为底层数据库执行原始SQL查询并将结果作为实体对象的方法。
以下示例演示如何对MS SQL Server数据库执行原始SQL查询。
var context = new SchoolContext();
var students = context.Students
.FromSql("Select * from Students where Name = 'Bill'").ToList();
在上面的示例中,该FromSql()
方法在Students
实体set(DbSet<Student>
)之后使用,因此指定的SQL查询必须从Students
表中返回将在Student
实体中转换的记录。实体框架核心将对数据库执行指定的查询,即Select * from Students where Name = 'Bill'
在上面的示例中。
查询参数化
FromSql
方法允许在C#中使用字符串插值语法进行参数化查询,如下所示。
string name = "Bill";
var context = new SchoolContext();
var students = context.Students
.FromSql($"Select * from Students where Name = '{name}'")
.ToList();
下面的代码也是一样的有效。
string name = "Bill";
var context = new SchoolContext();
var students = context.Students
.FromSql("Select * from Students where Name = '{0}'", name)
.ToList();
上面的示例将对SQL Server数据库执行以下SQL查询:
exec sp_executesql N'Select * from Students where Name = ''@p0''
',N'@p0 nvarchar(4000)',@p0=N'Bill'
go
查询后使用LINQ来操作
您还可以在使用FromSql
方法进行原始查询后使用LINQ运算符。
string name = "Bill";
var context = new SchoolContext();
var students = context.Students
.FromSql("Select * from Students where Name = '{0}'", name)
.OrderBy(s => s.StudentId)
.ToList();
在上面的示例中,EF Core通过组合FromSql
方法和OrderBy
运算符来执行以下查询。
exec sp_executesql N'SELECT [s].[StudentId], [s].[Name]
FROM (
Select * from Students where Name = ''@p0''
) AS [s]
ORDER BY [s].[StudentId]',N'@p0 nvarchar(4000)',@p0=N'Bill'
go
FromSql限制
- SQL查询必须返回与类型相同类型的实体
DbSet<T>
。例如,Course
如果FromSql
在之后使用,则指定的查询不能返回实体Students
。 - SQL查询必须返回表的所有列。例如
context.Students.FromSql("Select StudentId, LastName from Students).ToList()
会抛出异常。 - SQL查询不能包含JOIN查询以获取相关数据。使用Include方法在
FromSql()
方法之后加载相关实体。