使用 Entity Framework Core(EF Core)进行数据访问时,虽然其内置的 LINQ 查询功能已经相当强大,但在某些情况下,可能需要直接执行复杂的 SQL 语句来满足特定的查询需求。EF Core 提供了多种方式来执行自定义 SQL 查询,包括使用 Raw SQL。本文将以技术综述的形式,详细介绍如何在 EF Core 中实现自定义 SQL 查询与 Raw SQL,并通过具体的代码示例展示其实现过程。
首先,我们需要创建一个基于 EF Core 的项目。打开 Visual Studio,创建一个新的 .NET Core 控制台应用程序,并选择模板创建项目。接着,添加 EF Core 相关的 NuGet 包,如 Microsoft.EntityFrameworkCore.SqlServer
和 Microsoft.EntityFrameworkCore.SqlServer.Design
。
配置数据库上下文
在 Models
文件夹中,创建一个 BlogContext
类,用于定义数据库上下文。
using Microsoft.EntityFrameworkCore;
namespace YourProjectName.Models
{
public class BlogContext : DbContext
{
public BlogContext(DbContextOptions<BlogContext> options)
: base(options)
{
}
public DbSet<Blog> Blogs {
get; set; }
public DbSet<Post> Posts {
get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 配置实体关系
modelBuilder.Entity<Blog>()
.HasMany(b => b.Posts)
.WithOne(p => p.Blog)
.HasForeignKey(p => p.BlogId);
}
}
}
定义领域模型
在 Models
文件夹中,定义两个实体类 Blog
和 Post
。
namespace YourProjectName.Models
{
public class Blog
{
public int BlogId {
get; set; }
public string Url {
get; set; }
public DateTime CreatedAt {
get; set; }
public virtual ICollection<Post> Posts {
get; set; }
}
public class Post
{
public int PostId {
get; set; }
public string Title {
get; set; }
public string Content {
get; set; }
public int BlogId {
get; set; }
public virtual Blog Blog {
get; set; }
}
}
使用 Raw SQL 查询
在 EF Core 中,可以通过 FromSqlRaw
或 FromSqlInterpolated
方法来执行自定义的 SQL 查询。下面将展示如何使用这两种方法来查询数据。
使用 FromSqlRaw
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using YourProjectName.Models;
namespace YourProjectName
{
class Program
{
static void Main(string[] args)
{
var options = new DbContextOptionsBuilder<BlogContext>()
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFCoreCustomQueries;Trusted_Connection=True;")
.Options;
using (var context = new BlogContext(options))
{
// 添加一些测试数据
context.Blogs.AddRange(
new Blog {
Url = "http://example.com/blog1", CreatedAt = DateTime.Parse("2020-01-01"), Posts = new List<Post>
{
new Post {
Title = "First Post", Content = "Content of the first post." },
new Post {
Title = "Second Post", Content = "Content of the second post." }
}},
new Blog {
Url = "http://example.com/blog2", CreatedAt = DateTime.Parse("2021-01-01"), Posts = new List<Post>
{
new Post {
Title = "Third Post", Content = "Content of the third post." }
}}
);
context.SaveChanges();
// 使用 FromSqlRaw 执行自定义 SQL 查询
var customQueryResult = context.Blogs
.FromSqlRaw("SELECT * FROM Blogs WHERE CreatedAt > @0", DateTime.Parse("2020-01-01"))
.ToList();
foreach (var blog in customQueryResult)
{
Console.WriteLine($"Blog URL: {blog.Url}");
}
}
}
}
}
使用 FromSqlInterpolated
FromSqlInterpolated
方法允许使用字符串插值来构建 SQL 语句,同时自动处理参数绑定。
// 在 Main 方法中添加以下代码
var customQueryResultInterpolated = context.Blogs
.FromSqlInterpolated($@"
SELECT *
FROM Blogs
WHERE CreatedAt > {DateTime.Parse("2020-01-01")}")
.ToList();
foreach (var blog in customQueryResultInterpolated)
{
Console.WriteLine($"Blog URL: {blog.Url}");
}
使用 Raw SQL 更新和删除数据
除了查询外,还可以使用 Raw SQL 来执行更新和删除操作。
更新数据
// 在 Main 方法中添加以下代码
context.Database.ExecuteSqlRaw("UPDATE Blogs SET Url = 'http://newurl.com' WHERE BlogId = 1");
context.SaveChanges();
删除数据
// 在 Main 方法中添加以下代码
context.Database.ExecuteSqlRaw("DELETE FROM Blogs WHERE BlogId = 2");
context.SaveChanges();
复杂查询与动态 SQL
对于更复杂的查询场景,可以结合 LINQ 和 Raw SQL 来构建动态 SQL 语句。
// 在 Main 方法中添加以下代码
var startDate = DateTime.Parse("2020-01-01");
var endDate = DateTime.Parse("2021-01-01");
var complexQuery = context.Blogs
.FromSqlInterpolated($@"
SELECT b.*, COUNT(p.PostId) AS PostCount
FROM Blogs b
LEFT JOIN Posts p ON b.BlogId = p.BlogId
WHERE b.CreatedAt BETWEEN {startDate} AND {endDate}
GROUP BY b.BlogId, b.Url, b.CreatedAt")
.ToList();
foreach (var blog in complexQuery)
{
Console.WriteLine($"Blog URL: {blog.Url}, Post Count: {blog.PostCount}");
}
总结
通过上述步骤,我们展示了如何在 Entity Framework Core 中使用自定义 SQL 查询与 Raw SQL。从配置数据库上下文到定义领域模型,再到实现和使用 Raw SQL 查询,每个环节都体现了如何利用 EF Core 的强大功能来处理复杂的数据库操作。希望本文提供的示例代码和技术指南能够帮助你在实际项目中更好地应用这些技术,构建出高效且功能丰富的数据访问层。
自定义 SQL 查询和 Raw SQL 不仅能够简化复杂查询的需求,还能提高应用程序的灵活性和可维护性。结合 EF Core 的强大功能,我们可以构建出高度灵活且易于扩展的数据访问层,从而提高生产力并降低维护成本。