当前位置: 首页 > news >正文

EFCore与EF6:ORM技术深度解析

前言

ORM 是 Object Relational Mapping 的缩写,译为“对象关系映射”,是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。它解决了对象和关系型数据库之间的数据交互问题,ORM的作用是在关系型数据库和业务实体对象之间作一个映射,这样我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

为什么使用EF

在软件开发中,选择EF(Entity Framework) 通常是因为它作为微软推出的 ORM(对象关系映射)框架,能有效简化数据访问层的开发,提升开发效率并降低维护成本。以下从多个维度详细说明选择 EF 的原因:

1. 简化数据访问代码,提高开发效率

  • 告别手写 SQL:EF 通过将数据库表映射为 C#/VB.NET中的实体类,让开发者可以用面向对象的方式(如dbContext.Users.Where(u => u.Age > 18))操作数据,而非直接编写 SQL 语句,减少了重复的 CRUD(增删改查)代码。

  • 自动生成 SQL:EF 会根据开发者编写的 LINQ 查询或 Lambda 表达式,自动转换为对应的 SQL 语句,避免了手动写 SQL 可能出现的语法错误或性能问题(尤其对 SQL 不熟悉的开发者)。

2. 强大的 ORM 功能,支持多种数据库

  • 跨数据库兼容性:EF 支持 SQL Server、MySQL、PostgreSQL、Oracle 等多种主流数据库,只需更换配置(如连接字符串),即可实现数据库的切换,降低了对特定数据库的依赖。

  • 丰富的映射关系:支持一对一、一对多、多对多等复杂的表关系映射,开发者无需手动处理外键关联,只需通过实体类的属性(如public List<Order> Orders { get; set; })定义关系,EF 会自动维护关联逻辑。

3. 灵活的开发模式,适应不同场景

  • 数据库优先(Database First):如果数据库已存在,EF 可通过逆向工程自动生成实体类和数据上下文,快速适配现有数据库。

  • 模型优先(Model First):开发者可先设计实体模型(通过可视化设计器或代码),再由 EF 自动生成数据库表结构,适合从 0 开始的项目。

  • 代码优先(Code First):直接通过代码定义实体类和关系,EF 根据代码自动创建或更新数据库(通过迁移功能),是目前最流行的模式,尤其适合敏捷开发和 DDD(领域驱动设计)。

4. 内置迁移功能,轻松管理数据库版本

  • EF 的迁移(Migrations) 功能可跟踪实体类的变更,并生成对应的 SQL 脚本用于更新数据库,避免了手动修改表结构可能导致的数据丢失或不一致。

  • 支持版本回滚,可随时将数据库恢复到之前的状态,方便团队协作和环境部署(如开发、测试、生产环境的数据库同步)。

5. 与.NET 生态深度集成,降低学习成本

  • 作为微软官方框架,EF 与.NET Core/.NET 5+、ASP.NET Core 等技术无缝集成,无需额外配置即可使用,且文档丰富、社区活跃。

  • 开发者可直接使用 LINQ(.NET 中的查询语言)操作数据,无需学习新的查询语法,对熟悉.NET 的开发者非常友好。

6. 性能可优化,满足大多数业务需求

  • 虽然 EF 的自动生成 SQL 可能在极端场景下不如手写 SQL 高效,但通过延迟加载(按需加载关联数据)、贪婪加载Include方法预加载)、显式加载等功能,可有效优化查询性能。

  • 支持原生 SQL 注入(FromSqlRaw),对于复杂查询,可直接编写 SQL 并与 EF 结合使用,兼顾灵活性和效率。

7. 成熟稳定,适合企业级应用

  • 经过多年迭代,EF 已非常成熟(最新版本为 EF Core 8),广泛应用于企业级项目,能应对高并发、大数据量等场景。

  • 支持事务管理、缓存机制(如二级缓存)、异步操作(async/await)等企业级特性,满足生产环境需求。

总结

选择 EF 的核心原因是平衡了开发效率、灵活性和稳定性。对于大多数.NET 项目,尤其是需要快速迭代、跨数据库支持或团队中 SQL 经验参差不齐的情况,EF 能显著减少开发工作量,让开发者更专注于业务逻辑而非数据访问细节。当然,在对性能有极致要求(如高频交易系统)或 SQL 逻辑极其复杂的场景,也可结合手写 SQL 使用,EF 的灵活性使其能兼容这种混合模式。

EF/EF Core

比较 EF Core 和 EF6

Entity Framework Core (EF Core) 是适用于 .NET 的新式对象数据库映射器。 它支持 LINQ 查询、更改跟踪、更新和架构迁移。

Entity Framework 6 (EF6) 是专为 .NET Framework 设计的对象关系映射器,但支持 .NET Core。 EF6 是一款受支持的稳定产品,但已经不再对其进行积极开发。

EF6

安装

打开NuGet管理器,搜索EntityFramework​并安装即可

创建模型

创建模型有两种方案

  • 使用 Code First:开发者编写代码来指定模型。 EF 基于实体类和开发者提供的其他模型配置,在运行时生成模型和映射。

  • 使用 EF 设计器:开发者使用 EF 设计器进行绘制以指定模型。 生成的模型以 XML 格式存储在具有 EDMX 扩展名的文件中。 应用程序域对象通常从概念模型中自动生成。使用EF设计器比较简单,只需要点点点就可以了,这里就贴一个微软官方的文档链接吧

这两种方案都可用于定位现有数据库或创建新数据库。其实就是自己编写实体类和自动生成实体类的区别罢了,重点说自己编写实体类。

  1. 根据数据表的关系创建实体类,这些数据表可以存在也可以不存在,如果不存在,在执行查询时会自动创建数据库、数据表、建立关联,如下创建了两个实体类

    // 一个实体类对应一个数据表,类名应该和表名相同
    public class Blog
    {public int BlogId { get; set; }public string Name { get; set; }
    ​// 一个ICollection<T>类型的属性,表示一个一对多的关联关系,这个表示Post表中有一个外键关联着当前这张表的主键public virtual List<Post> Posts { get; set; }
    }
    ​
    public class Post
    {public int PostId { get; set; }public string Title { get; set; }public string Content { get; set; }
    ​// 外键列,使用表名+Id的格式表示该列存储的是另一个表的主键public int BlogId { get; set; }// 存储外键对象的属性,关联的表中对应的数据将会存储到该属性中public virtual Blog Blog { get; set; }
    }
  2. 创建DbContext​​类的派生类,所有对数据库的操作都是使用这个类的实例来实现的

    public class BloggingContext : DbContext
    {// 调用基类的构造,并传递数据库连接字符串// 也可以指定一个连接字符串的名字,如:Abc,就需要在App.Config中配置对应的连接字符串,如下public DB() : base("连接字符串"){// 为操作日志设置方法,每个操作都会调用这个方法并输出日志Database.Log = Console.WriteLine;}// 每一张表对应着一个DbSet<T>类型的属性,用于操作数据库public DbSet<Blog> Blogs { get; set; }public DbSet<Post> Posts { get; set; }
    }
// App.Config
<connectionStrings><add connectionString="Server=.,1433;Uid=sa;Pwd=laoguo66.;Database=abcdefg" name="Abc" providerName="System.Data.SqlClient"/>
</connectionStrings>
```
  1. 接下来就可以进行数据库的读取和写入了

    如果你现在还没有这个数据库,需要它帮你创建,那么至少需要进行一次数据库操作之后才会生效

    using (DB dB = new DB())
    {// 使用LINQ语句执行数据库的查询操作IQueryable<Blog> Blogs = from b in dB.Blogs select b;// 注意:只有当迭代IQueryable时或者调用ToList、ToArray语句时,才会真正的执行查询操作Blog[] a = Blogs.ToArray();
    }
  2. 不出意外的话,如果你没有这个数据库,那么你现在就有了。如果你已经有了,应该是可以查询到数据库的。

数据库迁移

现在可以对模型进行一些更改,当我们进行这些更改时,还需要更新数据库架构。

为此,我们将使用一项称为 Code First 迁移(简称迁移)的功能。

借助迁移功能,我们可以拥有一组有序的步骤,这些步骤介绍如何升级(和降级)数据库架构。 每个步骤(称为迁移)都包含一些描述要应用的更改的代码。

  1. 打开包管理器控制台,步骤:“工具”->“库包管理器”->“包管理器控制台”

  2. 在包管理器控制台中运行 Enable-Migrations​​​ 命令

    • 该命令将会把 Migrations 文件夹添加到项目中,其中包含两项:

      • Configuration.cs - 此文件包含 Migrations 用于迁移 BloggingContext 的设置。 你可以在此处指定种子数据、为其他数据库注册提供程序、更改将在其中生成迁移的命名空间等。

      • <timestamp>_InitialCreate.cs - 这是你的第一次迁移,它代表已应用于数据库的更改,将其从空数据库变为包含 Blogs 和 Posts 表的数据库。

  3. 现在可以对模型执行一系列的更改,比如向实体类中添加一个属性、删除一个属性等一系列的操作

  4. 在包管理器控制台中运行 Add-Migration AddUrl​​​ 命令。 Add-Migration 命令检查自上次迁移以来的更改,并使用找到的任何更改为新的迁移搭建基架。 我们可以为迁移指定一个名称;在本例中,我们将迁移称为“AddUrl”。你应该在实际的开发中为实体的更改添加更加合适的名字。

  5. 在包管理器控制台中运行 Update-Database​​​ 命令。 此命令将对数据库应用迁移。

自动迁移

自动迁移让你可以使用 Code First 迁移,而无需在项目中针对你进行的每个更改创建代码文件。 并非所有更改都可以自动进行应用 - 例如,列重命名需要使用基于代码的迁移。

可以交错执行自动迁移和基于代码的迁移,但在团队开发场景中不建议这样做。 如果你是使用源代码控制的开发人员团队的一员,则应使用纯自动迁移或纯基于代码的迁移。 鉴于自动迁移的局限性,我们建议在团队环境中使用基于代码的迁移

可以通过在包管理器控制台中运行 Enable-Migrations –EnableAutomaticMigrations​ 命令来开启自动迁移。

开启自动迁移之后,我们对实体修改之后只需要执行Update-Database​命令,就可以将实体的更改同步到数据库了,但如果你的修改可能会导致数据库数据丢失,如删除列,则会出现一个错误,需要运行 Add-Migration AddUrl​ 命令添加一个迁移操作后再执行Update-DataBase

数据注解

可以为实体类添加注解向 EF 提供有关这些类和它们映射到的数据库的更多信息

  • Key​ EF默认查找类中名为“Id”的属性,或类名和“Id”的组合,例如“BlogId”。 此属性将映射到数据库中的主键列。使用Key​注解设置某个属性为主键

  • NotMapped​该特性指定某个属性不在数据库中进行映射

  • ConcurrencyCheck​可以标记一个或多个属性,以便在用户编辑或删除实体时,将该属性用于数据库中的并发检查。当进行更新或者删除时,不仅仅会根据主键来定位行进行操作,还会根据更新的列进行筛选,如果在操作中有其他客户端修改了数据库的该数据,这个更新将会失败

  • Table["表名"]​更改某个类要映射到数据库的表名

  • Column("列名", [TypeName="类型"])​更改某个属性映射到数据表的列名,也可以指定数据的类型

  • [Index]​设置某个列为索引列,将会在数据库上为其创建索引

  • [Index("IdIndex")]​默认情况下,索引将命名为 IX_<属性名称>。 也可以为索引指定一个名称。

  • [Index(IsUnique = true)]​默认情况下,索引是非唯一的,但可以使用 IsUnique​ 命名参数来指定索引应该是唯一的。

  • [Index(Order=N)]​创建多列索引时,需要为索引中的列指定顺序

  • [ForeignKey("外键列名")]​ 例如现在有如下两张表,Post将会按照约定去关联Blog表中的BlogId主键,但是Blog中没有这个列,EF会为我们自动在数据库中创建一个Blog_ABC的列来进行外键关联,这明显不是我们想要的。

    可以使用ForeignKey​特性解决这个问题,如下代码中的第16行

    • public class Blog
      {[Key]public int ABC { get; set; }public string Name { get; set; }public string Url { get; set; }public virtual List<Post> Posts { get; set; }
      }public class Post
      {public int PostId { get; set; }public string Title { get; set; }public string Content { get; set; }public int BlobId { get; set; }[ForeignKey("BlobId")]public virtual Blog Blog { get; set; }
      }
基于现有数据库创建实体类

如果你已经创建好数据库了,只需要点点点就可以创建数据库对应的实体类了

  • “项目”->“添加新项...”

  • 从左侧菜单中选择“数据”,然后选择“ADO.NET 实体数据模型”

  • 输入名称并单击“确定”

  • 此操作将启动实体数据模型向导

  • 选择“数据库中的 Code First”并单击“下一步”

如果数据库发生了变换怎么办?

只能手动根据数据库的更改来更新实体类

使用设计器
  • “项目”->“添加新项...”

  • 从左侧菜单中选择“数据”,然后选择“ADO.NET 实体数据模型”

  • 输入名称并单击“确定”

  • 此操作将启动实体数据模型向导

  • 选择“来自数据库的EF设计器”或者“空EF设计器模型”并单击“下一步”

  • 后面就是图形化操作,点点点就行了

查询数据

使用实体框架查询数据的各种方法,包括 LINQ 和 Find 方法

using (var context = new BloggingContext())
{// 查询Blogs中所有名字为B开头的数据var blogs = from b in context.Blogswhere b.Name.StartsWith("B")select b;
​// 查询Blogs中名字为ADO.NET Blog的第一条数据var blog = context.Blogs.Where(b => b.Name == "ADO.NET Blog").FirstOrDefault();、// 如果需要根据主键查询数据,使用Find即可var b = db.books.Find(22); 
}
修改实体

修改实体直接操作对应的对象即可,操作完成之后调用SaveChanges​方法将操作同步到数据库

  • DbSet.Add

  • DbSet.AddRange

  • DbSet.Remove

  • DbSet.RemoveRange

using (var context = new BloggingContext())
{Blogs blog = new Blogs(){ Name = "Test" }context.Blogs.Add(new Blogs(){ Name = "Test" });context.SaveChanges();Console.WriteLine("新增的id列:" + blog.Id);
}

EFCore

EFCore 6.0入门看这篇就够了 - Mamba24⁸ - 博客园

Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。

EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:

  • 使 .NET 开发人员能够使用 .NET 对象处理数据库。

  • 无需再像通常那样编写大部分数据访问代码。

安装
  1. EFCore核心包的安装:在efcore中搜索并安装Microsoft.EntityFrameworkCore.SqlServer​,因为我这里连接的是sqlServer数据库,如果是其他数据库则安装其他的包。数据库提供程序。

  2. 工具安装:执行项目中与 EF Core 相关的任务,例如创建和应用数据库迁移,或基于现有数据库创建 EF Core 模型,在nuGet中搜索并安装Microsoft.EntityFrameworkCore.Tools

  3. 第二个步骤安装的工具需要在程序包管理器控制台才能使用,打开的步骤为:工具 => NuGet程序包管理器 => 程序包管理器控制台

  4. 运行 Get-Help about_EntityFrameworkCore​命令来验证安装是否成功,如果出现如下的提示,则说明安装完成

                         _/\__---==/    \\___  ___   |.    \|\| __|| __|  |  )   \\\| _| | _|   \_/ |  //|\\|___||_|       /   \\\/\\
  5. 工具包相关的命令详见EF Core 工具参考(包管理器控制台)- EF Core | Microsoft Learn

数据库和DB类的创建
数据库优先

如果你已经有数据库了,或者更喜欢在数据库管理工具中创建数据表和表关系时,可以使用这种方式

程序包管理器控制台中执行Scaffold-DbContext​命令来生成所需要的DbContext和Model类,如下

Scaffold-DbContext -Connection "Server=.,1433;Uid=sa;Pwd=laoguo66.;Database=BookManager;TrustServerCertificate=true" -Provider "Microsoft.EntityFrameworkCore.SqlServer" -OutputDir "DB" 

更多参数点击这里查看

不出意外的话,你应该可以得到和该数据库相关的DbContext类和实体类,接下来就可以进行数据库操作了

代码优先

代码优先也就是手动创建数据库相关的DbContext类和实体类,然后根据这些类创建数据库

  1. 创建相关类,并指定各个表的关系

    using Microsoft.EntityFrameworkCore;
    using System;
    using System.Collections.Generic;
    ​
    // 数据库上下文类
    public class BloggingContext : DbContext
    {// 每一个数据表使用一个 DbSet<T> 类型的属性表示public DbSet<Blog> Blogs { get; set; }public DbSet<Post> Posts { get; set; }
    ​protected override void OnConfiguring(DbContextOptionsBuilder options)=> options.UseSqlServer("你的数据库链接字符串");
    }
    ​
    // Blog表的实体类
    public class Blog
    {public int BlogId { get; set; }public string Url { get; set; }
    ​// 当某个表被其他表关联时,一般是一对多,需要在主键实体类中创建 List<外键表> 类型的属性存储他们public List<Post> Posts { get; } = new();
    }
    // Post表的实体类
    public class Post
    {public int PostId { get; set; }public string Title { get; set; }public string Content { get; set; }
    ​// 指定当前列外键列,主键为Blog表的BlogId列public int BlogId { get; set; }// 用于存储外键实例public Blog Blog { get; set; }
    }
  2. 在“包管理器控制台(PMC)”中,运行以下命令,根据类生成数据库,相关命令的作用已经在自动迁移章节说过了,功能是相同的

    Add-Migration​ 的作用 等价​Enable-Migrations

    Add-Migration InitialCreate
    Update-Database 
DbContext 配置和初始化

通过重写DbContext类的OnConfiguring方法来对上下文进行配置,比如指定数据库和数据库连接字符串

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{optionsBuilder// 配置日志输出函数和输出级别.LogTo((v) => Debug.WriteLine(v), LogLevel.Information)// 指定连接字符串.UseSqlServer("Server=.,1433;Uid=sa;Pwd=*****;Database=BookManager;TrustServerCertificate=true");
}
数据库系统配置示例NuGet 程序包
SQL Server 或 Azure SQL.UseSqlServer(connectionString)Microsoft.EntityFrameworkCore.SqlServer
Azure Cosmos DB.UseCosmos(connectionString, databaseName)Microsoft.EntityFrameworkCore.Cosmos
SQLite.UseSqlite(connectionString)Microsoft.EntityFrameworkCore.Sqlite
EF Core 内存中数据库.UseInMemoryDatabase(databaseName)Microsoft.EntityFrameworkCore.InMemory
PostgreSQL*.UseNpgsql(connectionString)Npgsql.EntityFrameworkCore.PostgreSQL
MySQL/MariaDB*.UseMySql(connectionString)Pomelo.EntityFrameworkCore.MySql
Oracle*.UseOracle(connectionString)Oracle.EntityFrameworkCore

更多DbContext配置详见

数据注解
  • [NotMapped]​ 如果不希望在模型中包含某一类型,可以用于类和属性

  • [Table("blogs")]​ 如果实体类名和表名不同的情况,使用指定数据库名称

  • [Column("blog_id")]​ 实体类的属性名和列名不通时,使用它指定列名

  • [Column(TypeName = "varchar(200)")]​ 显式的指定数据库列的类型

  • [MaxLength(500)]​ 最大长度仅适用于数组数据类型,如 string​ 和 byte[]

  • [Required]​ 指定列为必须的属性

  • [Comment("The URL of the blog")]​ 为数据列设置备注(注释)

  • [Column(Order = 0)]​指定列的顺序

  • [Key]​ 标志某个属性为主键,一般不用,因为他会自动将Id或者XxxId的列设置为主键

EF(Entity Framework) Core和EF(Entity Framework)6区别对比

Entity Framework (EF) Core 和 Entity Framework 6 (EF6) 是 Microsoft 提供的两种流行的数据访问技术,它们用于在 .NET 应用程序中对数据库进行操作。尽管它们的目标相同,但这两个版本在架构、性能、支持平台和功能上有明显的区别。以下是一些主要的区别对比:

参考文档:EF(Entity Framework) Core和EF(Entity Framework)6区别对比-CJavaPy

支持的平台:

EF6:原始设计为 .NET Framework 的一部分,仅支持 Windows 平台。 EF Core:作为 .NET Core 的一部分被重新设计和构建,支持跨平台,包括 Windows、Linux 和 macOS。它也支持在 .NET Framework 和 .NET 5/6 上运行。 性能:

EF Core:在许多方面进行了优化,比 EF6 提供更好的性能。例如,它在查询优化、内存使用和批量更新操作方面进行了改进。 EF6:尽管在其生命周期中进行了多次优化,但在性能方面通常不及 EF Core。 模型配置:

EF6:主要使用 DbContext 和 OnModelCreating 方法中的 Fluent API 或者属性(Attribute)来配置模型。 EF Core:扩展了 Fluent API,提供了更多的配置选项,并且对数据注解(Data Annotations)的支持也更加丰富。 迁移和数据库支持:

EF Core:支持自动和代码优先的迁移方式。它支持更多类型的数据库,包括非关系数据库。 EF6:支持自动迁移和代码优先迁移,但主要限于 SQL Server 和一些其他关系数据库。 查询能力:

EF Core:引入了更多的 LINQ 查询操作和函数,提高了查询的灵活性和表达能力。 EF6:虽然支持复杂的 LINQ 查询,但在某些复杂情况下可能面临性能问题。 更新和社区支持:

EF Core:作为 .NET Core 的一部分,持续获得更新和改进,社区活跃。 EF6:虽然仍然获得维护更新,但主要集中在修复重要问题上,新功能的添加较少。 API和功能:

EF Core:不是 EF6 的直接升级,缺少一些 EF6 中存在的特性(如 EDMX 文件支持、设计时工具支持),但引入了一些新功能,如全局查询过滤器、简化的事务 API 等。 EF6:具有成熟的功能和广泛的 API 支持,适用于依赖这些特性的现有应用程序。

数据库操作

其他操作和EF6基本相同,此处略

FreeSql

官方文档

LinqToSql

官方文档


文章转载自:

http://ECrZ3Pbo.qywfw.cn
http://22sfj1ON.qywfw.cn
http://TMKJSUe0.qywfw.cn
http://QgsTKBhM.qywfw.cn
http://eQlSYC0i.qywfw.cn
http://yx3KAabR.qywfw.cn
http://r1uHsJ6N.qywfw.cn
http://owyTYxVD.qywfw.cn
http://ICMvOsap.qywfw.cn
http://YhKlCar3.qywfw.cn
http://AZK0bxj5.qywfw.cn
http://6lCJ1idr.qywfw.cn
http://IzzE8hjk.qywfw.cn
http://Hmb4dWwc.qywfw.cn
http://AIkeqerZ.qywfw.cn
http://tPZwkO1v.qywfw.cn
http://s72yXFUn.qywfw.cn
http://rHZSltsw.qywfw.cn
http://ZO4Us5Ao.qywfw.cn
http://Nxy5BuV8.qywfw.cn
http://qRl5Ozmv.qywfw.cn
http://OiFiWbjp.qywfw.cn
http://eG1DOooX.qywfw.cn
http://pIUF5tYP.qywfw.cn
http://udUvTXLj.qywfw.cn
http://zB7OH47v.qywfw.cn
http://oJf3LUvR.qywfw.cn
http://opcsBKh0.qywfw.cn
http://ENodwYLf.qywfw.cn
http://A4m725Je.qywfw.cn
http://www.dtcms.com/a/373629.html

相关文章:

  • 【开题答辩全过程】以 线上“三味书屋”学习平台设计与实现为例,包含答辩的问题和答案
  • iframe引入界面有el-date-picker日期框,点击出现闪退问题处理
  • BP-Adaboost模型
  • 使用redis的发布/订阅(Pub/Sub), 实现消息队列
  • 鸿蒙:更改状态栏、导航栏颜色
  • [数据结构——lesson4.双向链表]
  • 集成学习:从理论到实践的全面解析
  • 机器学习-集成学习
  • 集成学习简介
  • JDK 17、OpenJDK 17、Oracle JDK 17 的说明
  • VM中CentOS 7密码重置
  • 科技信息差(9.8)
  • MATLAB的数值计算(三)曲线拟合与插值
  • 城市脉搏中的“绿色卫士”:当智能科技邂逅城市清洁
  • linux播放视频出现需要MPEG-4 AAC解码器,H.265(Main Profile)解码器,但是没有安装
  • ARM工作模式、汇编学习
  • 【入门级-算法-6、排序算法:选择排序】
  • React state在setInterval里未获取最新值的问题
  • Linux 物理机如何区分 SSD 与 HDD ——以 DELL PERC H730 Mini 为例
  • AP和stage模式差异
  • 支持生成一维条形码Extend .NET
  • 企业级固态硬盘——U.2接口技术
  • 【Android虚拟摄像头】七、安卓15系统实现虚拟摄像头
  • FxSound:提升音频体验,让音乐更动听
  • Don‘t Sleep:保持电脑唤醒,确保任务不间断
  • android/java中,配置更改导致activity销毁重建的解决方法
  • C++day8作业
  • 【CI/CD】GitHub Actions 快速入门
  • 如何在安卓手机/平板上找到下载文件?
  • Claude Code Windows 原生版安装指南