EF core 3.1 无法运行复杂的原始 SQL 查询

sqlserver

2个回答

写回答

段干净

2025-09-24 20:30

+ 关注

Database
Database

EF Core 3.1 提供了强大的 ORM 功能,使得我们可以轻松地与数据库进行交互。然而,在某些情况下,我们可能需要执行一些复杂的原始 SQL 查询,以满足特定的需求。但是,值得注意的是,在 EF Core 3.1 中,执行复杂的原始 SQL 查询有一些限制。本文将探讨这些限制,并提供一些解决方案。

在 EF Core 3.1 中,无法直接执行复杂的原始 SQL 查询。这是因为 EF Core 3.1 采用了参数化查询的方式,以提高查询的安全性和性能。参数化查询可以防止 SQL 注入攻击,并允许数据库缓存已编译的查询计划,从而提高性能。然而,参数化查询的特性可能会限制我们执行一些复杂的原始 SQL 查询。

解决方案1:使用 FromSqlRaw 方法

为了执行复杂的原始 SQL 查询,我们可以使用 EF Core 3.1 提供的 FromSqlRaw 方法。该方法允许我们将原始 SQL 查询嵌入到 LINQ 查询中,并将结果映射到实体类或匿名类型中。下面是一个简单的示例:

csharp

var query = context.Products.FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 10);

var products = query.ToList();

在上面的示例中,我们使用 FromSqlRaw 方法执行了一个简单的原始 SQL 查询,返回价格大于 10 的产品列表。

解决方案2:使用 ExecuteSqlRaw 方法

如果我们只需要执行原始 SQL 查询而不需要将结果映射到实体类或匿名类型中,可以使用 EF Core 3.1 提供的 ExecuteSqlRaw 方法。该方法可以执行任意的原始 SQL 查询,并返回受影响的行数。下面是一个示例:

csharp

var rowsAffected = context.Database.ExecuteSqlRaw("UPDATE Products SET Price = Price * {0}", 1.1);

在上面的示例中,我们使用 ExecuteSqlRaw 方法执行了一个原始 SQL 查询,将产品价格增加了 10%。

解决方案3:使用 FromSqlInterpolated 方法

从 EF Core 3.0 开始,我们还可以使用 FromSqlInterpolated 方法执行带有插值字符串的原始 SQL 查询。插值字符串允许我们在 SQL 查询中嵌入 C# 表达式,并将其转换为参数化查询。下面是一个示例:

csharp

var minPrice = 100;

var query = context.Products.FromSqlInterpolated($"SELECT * FROM Products WHERE Price > {minPrice}");

var products = query.ToList();

在上面的示例中,我们使用 FromSqlInterpolated 方法执行了一个原始 SQL 查询,并使用插值字符串嵌入了 C# 表达式。

在 EF Core 3.1 中,虽然无法直接执行复杂的原始 SQL 查询,但我们可以使用 FromSqlRaw、ExecuteSqlRaw 和 FromSqlInterpolated 方法来解决这个问题。这些方法允许我们执行任意的原始 SQL 查询,并满足特定的需求。

无论使用哪种解决方案,我们都应该注意安全性和性能。在执行原始 SQL 查询时,我们应该尽量避免使用字符串拼接,以防止 SQL 注入攻击。此外,我们还应该注意查询的性能,避免执行过多的原始 SQL 查询,以提高应用程序的响应速度。

参考代码:

csharp

public class Product

{

public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }

}

public class MyDbContext : DbContext

{

public DbSet<Product> Products { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

{

optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MyDatabase;");

}

}

public class Program

{

static void MAIn(string[] args)

{

using (var context = new MyDbContext())

{

// 使用 FromSqlRaw 方法执行原始 SQL 查询

var query = context.Products.FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 10);

var products = query.ToList();

// 使用 ExecuteSqlRaw 方法执行原始 SQL 查询

var rowsAffected = context.Database.ExecuteSqlRaw("UPDATE Products SET Price = Price * {0}", 1.1);

// 使用 FromSqlInterpolated 方法执行原始 SQL 查询

var minPrice = 100;

var interpolatedQuery = context.Products.FromSqlInterpolated($"SELECT * FROM Products WHERE Price > {minPrice}");

var interpolatedProducts = interpolatedQuery.ToList();

}

}

}

参考链接:

1. EF Core - Raw SQL Queries: https://docs.microsoft.com/en-us/ef/core/querying/raw-sql

举报有用(4分享收藏

Amlo

2025-09-24 22:50

+ 关注

在使用 EF Core 3.1 时,执行复杂的原始 SQL 查询可能会遇到一些限制或问题。EF Core 提供了 FromSqlRawFromSqlInterpolated 方法来直接执行 SQL 查询,但这些方法在处理复杂的查询时可能需要一些额外的注意和配置。

首先,确保你的 SQL 查询语法正确,并且适用于你的数据库提供程序(如 SQL Server、MySQL 等)。EF Core 3.1 对 SQL 查询的支持是基于所使用的数据库的,所以不同的数据库可能会有不同的特性。

其次,如果你的查询涉及到需要返回实体类型,那么你需要确保查询返回的列与实体类型中的属性一一对应。否则,EF Core 将无法正确映射结果。

此外,EF Core 3.1 在处理原始 SQL 查询时,对于某些复杂的查询,特别是涉及到性能优化的部分,可能不如直接使用 ADO.NET 来得灵活。在这种情况下,你可以考虑使用 ADO.NET 来执行查询,并手动处理返回的结果。

最后,确保你的查询中没有注入攻击的风险。使用参数化查询是避免 SQL 注入的有效方法。

如果你仍然遇到问题,建议查看 EF Core 的官方文档或相关的社区论坛,那里可能会有更多的解决方案和讨论。

举报有用(4分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号