每个 .NET 开发人员解决常见问题时都应该了解的 5 个 EF Core 功能

科技   2024-11-28 16:52   上海  


Entity Framework Core (EF Core) 为希望以高效可靠的方式与数据库交互的 .NET 开发人员带来了翻天覆地的变化。通过将复杂的 SQL 查询转换为简单的 C# 代码,EF Core 消除了处理数据的许多麻烦。但问题是 — 许多开发人员没有充分利用 EF Core 提供的强大功能。今天,我将分享 EF Core 的 5 项功能,这些功能可以解决开发人员的实际问题并显著提高您的工作效率。

这些是我希望我在开始时就知道的功能,我敢打赌它们也会让你免于很多麻烦。

1. 全局查询过滤器:避免重复的过滤逻辑

问题:您是否厌倦了在每个查询中为“软删除”实体添加相同的筛选条件?

解决方案:使用 EF Core 中的全局查询筛选器在实体的所有查询中自动应用条件。此功能对于实施软删除、多租户或需要持续筛选的任何方案特别有用

public class AppDbContext : DbContext  
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.HasQueryFilter(p => !p.IsDeleted); // Automatically filter out deleted items
}
}

使用此方法时,EF Core 将始终从查询中排除已删除的产品。这样可以避免忘记在每个查询中添加过滤器的风险,并使您的代码更简洁。

关键字:EF Core 全局查询筛选器、EF Core 软删除、数据库筛选

2. Shadow Properties:跟踪审计数据而不会弄乱您的模型

问题:需要跟踪额外信息,例如上次修改项目的时间,但又不想使实体类混乱?

解决方案影子属性允许您存储元数据,而无需将其直接包含在 C# 类中。它们非常适合像 or 这样的审计数据,您可能在数据库中需要这些数据,但不想成为主域模型的一部分。LastModifiedCreatedBy

下面是一个示例:

public class AppDbContext : DbContext  
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property<DateTime>("LastModifiedDate"); // Keeps track of the last modification date
}
}

这些属性在类中不可见,这使模型保持整洁,但它们会被跟踪并保存在数据库中。Product

关键字:EF Core 影子属性、在 EF Core 中跟踪审核数据、实体框架核心审核跟踪

3. 已编译的查询:通过重用查询来提高查询性能

问题:您的应用程序速度越来越慢,因为它重复运行相同的查询,从而导致性能问题。

解决方案编译查询非常适合需要多次运行类似查询的场景。EF Core 通常会在每次使用时编译每个 LINQ 查询,这会增加开销。使用 Explicitly Compiled Queries,您可以重用查询的预编译版本以提高性能。

以下是创建编译查询的方法:

public static readonly Func<AppDbContext, int, Product> GetProductById =  
EF.CompileQuery((AppDbContext context, int id) =>
context.Products.FirstOrDefault(p => p.Id == id));

现在,您可以像这样使用它:

var product = GetProductById(context, 1); // This is efficient for repeated queries

通过使用编译的查询,您可以在重复执行相同类型的查询时显著提高应用程序的速度。

关键字:EF Core 编译的查询、优化 EF Core 查询性能、在 Entity Framework Core 中重用查询

4. 拦截器:集中式 SQL 命令日志记录和控制

问题:想要确切了解 EF Core 向数据库发送的 SQL 命令?或者,也许您需要在执行命令之前对其进行修改?

解决方案拦截器是强大的工具,可让您挂接到数据库命令的生命周期中。它们特别适用于记录、调试或修改命令以强制实施自定义规则。

下面是一个命令拦截器的简单示例,它记录所有已执行的 SQL 命令:

public class LoggingCommandInterceptor : DbCommandInterceptor  
{
public override InterceptionResult<int> NonQueryExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<int> result)
{
Console.WriteLine($"Executing SQL Command: {command.CommandText}"); // Log the SQL command
return base.NonQueryExecuting(command, eventData, result);
}
}

要注册此侦听器,请执行以下操作:

optionsBuilder.AddInterceptors(new LoggingCommandInterceptor());

使用 EF Core 侦听器是了解数据库级别发生的情况的好方法,这对于排查和优化数据库交互非常有用。

关键字:EF Core 侦听器、在 EF Core 中记录 SQL 命令、EF Core 调试

5. 价值转化:以您需要的方式存储数据

问题:您希望以特定格式将数据存储在数据库中,但在代码中使用数据的方式不同。例如,你有一个枚举,但你想把它作为一个字符串保存在数据库中以提高可读性。

解决方案价值转化允许您以所需的格式存储数据。无论是将枚举转换为字符串,还是管理不同类型的单位,值转换都可以弥合 C# 代码与数据在数据库中的表示方式之间的差距。

假设我们的类中有一个 for 的枚举。我们可以将此枚举存储为可读字符串,而不是将此枚举作为整数存储在数据库中。ProductCategoryProduct

public class Product  
{
public int Id { get; set; }
public ProductCategory Category { get; set; }
}

public enum ProductCategory
{
Electronics,
Clothing,
Grocery
}

public class AppDbContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(p => p.Category)
.HasConversion<string>(); // Store enum as string in the database
}
}

通过值转换,EF Core 可帮助您在干净的代码和可读、可维护的数据之间保持平衡。

关键字:EF Core 值转换、在 EF Core 中将枚举转换为字符串、实体框架数据格式

Entity Framework Core 不仅仅是一个数据库工具,它还是一个强大的 ORM,其功能使开发数据驱动的应用程序更轻松、更干净、更高效。无论是用于一致筛选的全局查询筛选器、用于审核跟踪的影子属性、用于提高性能的编译查询、用于命令日志记录的侦听器,还是用于灵活数据存储的值转换,EF Core 都是您的坚强后盾。

这 5 项 EF Core 功能可以解决开发人员面临的一些最常见问题,即提高性能、减少重复代码以及使数据更有意义。了解和应用这些功能不仅会使您成为更高效的 .NET 开发人员,还可以确保您的应用程序平稳运行并且更易于维护。

如果你喜欢我的文章,请给我一个赞!谢谢

架构师老卢
资深软件架构师, 分享编程、软件设计经验, 教授前沿技术, 分享技术资源(每天发布电子书),每天进步一点点...
 最新文章