Entity Framework教程-安装和配置 Entity Framework (Installation & configuration Entity Framework)
更新记录
转载请注明出处:
2022年10月11日 发布。
2022年10月10日 从笔记迁移到博客。
Entity Framework Core安装介绍
需要的包说明#
EF Core 不是.NET Core 和 .NET framework的一部分.
一般通过NuGet依赖管理工具进行安装
通常需要安装以下类型包:
EF Core Framework 框架本身,必须需要
EF Core DB provider 数据库提供器,必须需要
EF Core tools 工具,非必须需要
EF Core Design tools 设计工具,非必须需要
EF Core Database Providers(数据库提供器)#
Entity Framework Core 使用数据库提供器(provider) 来操作不同的具体数据库
只需要安装具体的NuGet包即可安装数据库提供器:
SQL Server Microsoft.EntityFrameworkCore.SqlServer //SQL Server 2008 or later
PostgreSQL Npgsql.EntityFrameworkCore.PostgreSQL
MySQL,MariaDB Pomelo.EntityFrameworkCore.MySql
SQLite Microsoft.EntityFrameworkCore.SQLite //SQLite 3.7 or later
SQL Compact EntityFrameworkCore.SqlServerCompact40
In-memory Microsoft.EntityFrameworkCore.InMemory //EFCore内存数据库(仅用于测试)
官方文档:https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli
使用命令添加Entity Framework Core的NuGet包#
Entity Framework Core包作用解释#
下面使用SQL Server做示例:
Microsoft.EntityFrameworkCore //基本的EF功能
Microsoft.EntityFrameworkCore.SqlServer //SQLServer的DB适配器
Microsoft.EntityFrameworkCore.Tools //EF工具,安装后可以使用EF命令
Microsoft.EntityFrameworkCore.SqlServer.Design //EF设计时使用的包
注意:最好保持包的版本相同,必要时使用-Version配置项
注意:如果需要移除包可以使用Uninstall-Package或dotnet remove package命令
注意:如果数据库是MySQL或其他提供器,提供器替换成其他提供器即可
安装EF Core包-使用dotnet命令#
添加Entity Framework Core框架本身
dotnet add package 'Microsoft.EntityFrameworkcore'
添加EF工具
dotnet add package 'Microsoft.EntityFrameworkcore.Tools'
添加EF Core数据提供器(Install EF Core DB Provider)
dotnet add package 'Microsoft.EntityFrameworkcore.SqlServer'
添加设计时使用的包
dotnet add package 'Microsoft.EntityFrameworkcore.SqlServer.Design'
安装EF Core包-使用Visual Studio包管理工具#
在VS中Tools ➤ NuGet Package Manager ➤ Package Manager Console
添加Entity Framework Core框架本身
Install-Package 'Microsoft.EntityFrameworkcore'
添加EF工具
Install-Package 'Microsoft.EntityFrameworkcore.Tools'
添加EF Core数据提供器(Install EF Core DB Provider)
Install-Package 'Microsoft.EntityFrameworkcore.SqlServer'
添加设计时使用的包
Install-Package 'Microsoft.EntityFrameworkcore.SqlServer.Design'
具体数据库连接配置
EF Core配置连接SQL Server#
安装NuGet包#
Microsoft.EntityFrameworkCore.SqlServer //SQLServer的DB适配器
Microsoft.EntityFrameworkCore.Tools //EF工具,安装后可以使用EF命令
Microsoft.EntityFrameworkCore.SqlServer.Design //EF设计时使用的包
对ASP.NET Core支持#
配置连接字符串#
打开appsettings.json文件
加入ConnectionStrings和Connection字符串
"ConnectionStrings": {
"connection": "Server=127.0.0.1;Database=TestDb;User Id =sa;Password=pass"
}
实例:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"connection": "Server=127.0.0.1;Database=TestDb;User Id =sa;Password=pass"
}
}
配置上下文对象#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.SqlServer;
using PandaTest.Models;
namespace PandaTest.Repository
{
public class ApplicationDbContext: DbContext
{
public ApplicationDbContext():base()
{
}
public ApplicationDbContext(DbContextOptions dbContextOptions):base(dbContextOptions)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("Custom");
}
public DbSet<Person> Person { get; set; }
}
}
配置服务
//ApplicationDbContext
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("connection")));
EF Core配置连接SQLite#
安装包#
dotnet add package 'Microsoft.EntityFrameworkcore.Tools'
dotnet add package 'Microsoft.EntityFrameworkCore.Sqlite'
dotnet add package 'Microsoft.EntityFrameworkCore.Sqlite.Design'
官方地址
https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Sqlite/
配置数据库上下文#
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connectionString = @"Data Source=PandaCMS.db;";
optionsBuilder.UseSqlite(connectionString);
}
对ASP.NET Core支持#
appsettings.json中添加:
"ConnectionStrings": {
"DefaultConnection": "DataSource=app.db;Cache=Shared"
},
Startup.cs中添加:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
EF Core配置连接MySQL#
安装包#
dotnet add package 'Microsoft.EntityFrameworkcore.Tools'
dotnet add package 'Pomelo.EntityFrameworkCore.MySql'
dotnet add package 'Pomelo.EntityFrameworkCore.MySql.Design'
Pomelo.EntityFrameworkCore.MySql官方地址
https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql
配置数据库上下文#
对ASP.NET Core支持#
MySQL与EntityFrameworkCore类型对应关系
Data Type | Maximum Length | .NET Type |
---|---|---|
CHAR | 255 | string |
BINARY | 255 | byte[] |
VARCHAR, VARBINARY | 65,535 | string, byte[] |
TINYBLOB, TINYTEXT | 255 | byte[] |
BLOB, TEXT | 65,535 | byte[] |
MEDIUMBLOB, MEDIUMTEXT | 16,777,215 | byte[] |
LONGBLOB, LONGTEXT | 4,294,967,295 | byte[] |
ENUM | 65,535 | string |
SET | 65,535 | string |
EF Core配置连接PostgreSQL#
项目添加以下三个包:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Npgsql.EntityFrameworkCore.PostgreSQL
dotnet CLI命令:
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
在ConfigureServices中注册服务:
services.AddDbContext<CommandContext>(options=>options.UseNpgsql(
Configuration.GetConnectionString("连接配置名称")
));
EF Core配置连接基于内存的数据库(Configuring in-memory databases)#
添加包到项目中(NuGet packages as project references)#
dotnet add package 'Microsoft.EntityFrameworkcore'
dotnet add package 'Microsoft.EntityFrameworkcore.Tools'
dotnet add package 'Microsoft.EntityFrameworkCore.InMemory'
dotnet add package 'Microsoft.EntityFrameworkCore.Design'
定义上下文(Defining DbContext)#
创建Models文件夹
定义TodoDbContext类
using Microsoft.EntityFrameworkCore;
namespace ToDo.MVC.Models
{
public class TodoDbContext: DbContext
{
public TodoDbContext(DbContextOptions<TodoDbContext> options)
: base(options) { }
public DbSet<Todo> Todos { get; set; }
}
}
注入上下文到服务中#
打开Startup.cs的Startup类在ConfigureServices()方法
public void ConfigureServices(IServiceCollection services)
{
//注入上下文到服务中
services.AddDbContext<TodoDbContext>(options => options.seInMemoryDatabase(“Todos”));
services.AddControllersWithViews();
}
使用上下文访问数据库#
Entity Framework安装(Install Entity Framework)
使用Visual Studio添加Entity Framework包#
管理项目的NuGet包#
搜索安装Entity Framework包即可#
引入命名空间#
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
创建实体对象和数据库上下文对象#
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace PandaNamespace
{
/// <summary>
/// 书类
/// </summary>
public class Book
{
[Key]
public int Code { get; set; }
public string Title { get; set; }
public string Author { get; set; }
}
/// <summary>
/// 人类
/// </summary>
public class Person
{
[Key]
public int Code { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
}
public class BookContext:DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Person> Persons { get; set; }
}
public class PandaClass
{
public static void Main()
{
Console.WriteLine("Begin");
using (BookContext db = new BookContext())
{
//新建书实例
Book newBook = new Book
{
Author = "Panda",
Code = 666,
Title = "What the Fun"
};
Console.WriteLine("newBook");
//添加书到数据库
db.Books.Add(newBook);
Console.WriteLine("Add");
//保存到数据库
db.SaveChanges();
//查询数据
var result = from item in db.Books
orderby item.Code
select item;
Console.WriteLine(result.Count());
//输出查询结果
foreach (var item in result)
{
Console.WriteLine($"Code:{item.Code} TItle:{item.Title} Author {item.Author}");
}
}
Console.WriteLine("End");
Console.ReadKey();
}
}
}
查询数据表的数据条数#
using System;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
using(PandaDatabaseEntities pandaDatabaseEntities = new PandaDatabaseEntities())
{
//获得表数据的总数
Console.WriteLine(pandaDatabaseEntities.PandaProduct.Count());
}
Console.ReadKey();
}
}
}
删除表中的数据#
using(PandaModel pandaModel = new PandaModel())
{
OrderDetail orderDetail = pandaModel.OrderDetail.First();
pandaModel.OrderDetail.Remove(orderDetail);
int affectRows = pandaModel.SaveChanges();
Console.WriteLine("Success! {0}",affectRows);
}
修改表中的数据#
using(PandaModel pandaModel = new PandaModel())
{
Product product = pandaModel.Product.First();
product.ProductName = "马来剑";
pandaModel.SaveChanges();
}
获得操作后影响数据的条数#
using(PandaModel pandaModel = new PandaModel())
{
Product product = pandaModel.Product.First();
product.ProductName = "马来剑";
int affectRows = pandaModel.SaveChanges();
Console.WriteLine("Success! {0}",affectRows);
}
与 ASP.NET Core 集成
配置数据库上下文对象服务#
builder.Services.AddDbContext<CalculationContext>(opts => {
opts.UseSqlServer(builder.Configuration.GetConnectionString("PandaConnection"));
});
配置EF Core的日志级别#
"Location": {
"CityName": "Buffalo"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.EntityFrameworkCore": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"CacheConnection": "Server=(localdb)\\MSSQLLocalDB;Database=CacheDb",
"CalcConnection": "Server=(localdb)\\MSSQLLocalDB;Database=CalcDb"
}
}
开启日志记录敏感数据(Enabling Sensitive Data Logging)#
services.AddDbContext<CalculationContext>(opts => {
opts.UseSqlServer(builder.Configuration.GetConnectionString("PandaConnection"));
opts.EnableSensitiveDataLogging(true);
});
使用Entity Framework Core
代码优先开发-使用Entity Framework Core#
说明#
安装好Entity Framework之后再进行以下配置
配置数据库连接信息#
设置appsettings.json文件
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"AppDb": "Data Source=127.0.0.1;Database=Northwind;User Id=sa;Password=pass"
}
}
引入命名空间#
在Model类文件中引入
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
说明:
DataAnnotations包含一组验证数据的特性
DataAnnotations.Schema包含将实体类映射到数据库表的特性
建立Model#
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace ConsoleApp10.Models
{
class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
}
创建DbContext上下文(Create a DBContext)#
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.SqlServer;
namespace ConsoleApp2.Models
{
class AppDbContext : DbContext
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="options">数据库上下文配置</param>
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//数据库连接配置
optionsBuilder.UseSqlServer("Server=127.0.0.1;User Id=sa;Pwd=pass;Database=Panda");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//通常放Fluent API
}
//具体的DbSet<Entity>
public DbSet<Product> Products { get; set; }
}
}
.NET 应用程序 配置数据库连接的示例#
https://www.connectionstrings.com/
Sqlite配置实例#
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string path = System.IO.Path.Combine(System.Environment.CurrentDirectory, "Northwind.db");
optionsBuilder.UseSqlite($"Filename={path}");
}
在ASP.NET Core MVC项目中添加Entity Framework Core上下文#
在Startup.cs文件中设置ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<AppDbContext>(
options => options.UseSqlServer
(this.Configuration.GetConnectionString("AppDb")));
}
进行查询(Querying EF Core models)#
数据库优先开发-使用Entity Framework Core#
从数据库生成Model和Context#
使用PowerShell#
在Visual Studio中进入【工具】
进入【NuGet包管理器】,进入【程序包管理控制台】
输入
Scaffold-DbContext 连接数据库的字符串 数据库提供器类型
实例:
Scaffold-DbContext 'Data Source = 192.168.1.198; Database = Noind; User Id = sa; Password = pass' Microsoft.EntityFrameworkCore.SqlServer
即可自动生成对应的模型(Model) 和 上下文(Context)
还可以指定数据库的架构Schema,使用-Schema参数设置
Scaffold-DbContext 连接数据库的字符串 数据库提供器类型 -Schema '架构名'
实例:
Scaffold-DbContext 'Data Source = 192.168.1.198; Database = PandaDb; User Id = sa; Password =pass' Microsoft.EntityFrameworkCore.SqlServer -Schema dbo
默认情况下,生成的模型使用Fluent API进行设置模型的约束
使用-DataAnnotations参数可以指定使用注解来设置默认的约束
Scaffold-DbContext 连接数据库的字符串 数据库提供器类型 -DataAnnotations
实例:
Scaffold-DbContext 'Data Source = 192.168.1.198; Database = PandaDb; User Id = sa; Password = pass' Microsoft.EntityFrameworkCore.SqlServer -DataAnnotations
使用ef tools#
使用ef dbcontext scaffold命令创建基于已有数据库的model
dotnet ef dbcontext scaffold [-Connection] [-Provider] [-OutputDir] [-Context] [-Schemas>] [-Tables>][-DataAnnotations] [-Force] [-Project] [-StartupProject] [<CommonParameters>]
实例
dotnet ef dbcontext scaffold "Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models
注意:一旦使用数据库生成了model,记得使用migrations命令创建迁移,这样可以保持数据库与model保持同步
使用appsetting.json文件设置和读取数据库连接字符串#
定义appsettings.json配置文件#
可以不用定义配置文件,直接使用上面硬编码的方式定义数据库连接字符串
也可以定义appsettings.json配置文件,将数据库连接字符串写入到其中
使用配置文件的好处是:日后部署方便,修改维护方便
在Visual Studio中添加appsettings.json并设置复制到复制到输出目录
在appsettings.json配置文件中写入数据库连接字符串:
{
"ConnectionStrings": {
"PandaDb": "Data Source = 192.168.1.198; Database = PandaDb; User Id = sa; Password = pass"
}
}
安装配置文件扩展包#
Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.FileExtensions
Install-Package Microsoft.Extensions.Configuration.Json
包作用说明:
Configuration用于设置配置信息
Configuration.FileExtensions用于扩展设置信息,用于读取配置文件信息
Configuration.Json用于扩展配置信息可以处理Json
将appsetting.json配置文件中的数据读入到配置对象中#
using System;
using Microsoft.Extensions.Configuration;
using System.IO;
namespace ConsoleApp1
{
class Program
{
/// <summary>
/// 保存配置文件信息的私有字段
/// </summary>
private static IConfigurationRoot _configuration;
static void Main(string[] args)
{
BuildConfiguration();
//wait
Console.ReadKey();
}
/// <summary>
/// 将配置信息对象与配置文件关联
/// </summary>
private static void BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
_configuration = builder.Build();
}
}
}
通过配置对象读取appsetting.json文件中的配置信息#
using System;
using Microsoft.Extensions.Configuration;
using System.IO;
using Microsoft.EntityFrameworkCore;
namespace ConsoleApp1
{
class Program
{
/// <summary>
/// 保存配置文件信息的私有字段
/// </summary>
private static IConfigurationRoot _configuration;
/// <summary>
/// 数据库选项生成器
/// </summary>
private static DbContextOptionsBuilder<PandaDbContext> _optionsBuilder;
static void Main(string[] args)
{
BuildConfiguration();
BuildOptions();
//wait
Console.ReadKey();
}
/// <summary>
/// 将配置信息对象与配置文件关联
/// </summary>
private static void BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
_configuration = builder.Build();
}
/// <summary>
/// 构建选项生成器
/// </summary>
private static void BuildOptions()
{
_optionsBuilder = new DbContextOptionsBuilder<PandaDbContext>();
//将配置选项读入
_optionsBuilder.UseSqlServer(_configuration.GetConnectionString("PandaDb"));
}
}
}
实际测试读取数据#
using System;
using Microsoft.Extensions.Configuration;
using System.IO;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
/// <summary>
/// 保存配置文件信息的私有字段
/// </summary>
private static IConfigurationRoot _configuration;
/// <summary>
/// 数据库选项生成器
/// </summary>
private static DbContextOptionsBuilder<PandaDbContext> _optionsBuilder;
static void Main(string[] args)
{
BuildConfiguration();
BuildOptions();
TestGetData();
//wait
Console.ReadKey();
}
/// <summary>
/// 将配置信息对象与配置文件关联
/// </summary>
private static void BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
_configuration = builder.Build();
}
/// <summary>
/// 构建选项生成器
/// </summary>
private static void BuildOptions()
{
_optionsBuilder = new DbContextOptionsBuilder<PandaDbContext>();
//将配置选项读入
_optionsBuilder.UseSqlServer(_configuration.GetConnectionString("PandaDb"));
}
private static void TestGetData()
{
using(PandaDbContext pandaDbContext = new PandaDbContext(_optionsBuilder.Options))
{
var result = pandaDbContext.User.Take(20).Select(u=>u);
foreach (var item in result)
{
Console.WriteLine($"Id:{item.Id} Name:{item.UserName} Age:{item.Age}");
}
}
}
}
}
使用Entity Framework
模型优先开发-使用Entity Framework#
如果现在没有任何数据库,可以使用空EF设计器模型,进行开发EF
添加EF到项目中:
选择【ADO.NET实体数据模型】
选择【空EF设计器模型】
编辑实体模型
完成了数据库模型的建立后,就要生成数据库文件,点击【生成数据库】
配置生成的实体框架版本
等待配置完成后,将获得系统生成的SQL文件
将SQL导入到数据库中
使用EF添加数据到数据库中
using(Model1Container model1 = new Model1Container() )
{
//添加数据到数据库中
PandaTable pandaTable = new PandaTable()
{
Name = "Panda666",
Code = "999"
};
model1.PandaTableSet.Add(pandaTable);
//保存修改
model1.SaveChanges();
}
模型优先开发-已有数据库-使用Entity Framework#
添加EF到项目中:
选择【ADO.NET实体数据模型】
选择【来自数据库的EF设计器】
配置数据库连接
选择实体框架的版本
选择需要导入的表和视图
代码优先开发-使用Entity Framework#
添加EF到项目中:
选择【ADO.NET实体数据模型】
将生成一个默认的上下文文件
配置数据库,(注意:系统默认数据库是设置的LocalDb)
可以根据需要进行修改或者添加数据库连接配置
添加一个测试的Model类
在上下文中进行添加对应的DbSet
进行添加和查询数据
using (PandaModel db = new PandaModel())
{
//添加数据到数据库中
PandaClass pandaClass = new PandaClass()
{
Id = 6666,
Name = "Panda666",
MoneyCount = 9999M
};
db.PandaClasses.Add(pandaClass);
db.SaveChanges();
Console.WriteLine("Add Success!");
//查询数据
var queryResult = from item in db.PandaClasses
select item;
foreach (PandaClass item in queryResult)
{
Console.WriteLine("{0} - {1} - {2}",item.Id,item.Name,item.MoneyCount);
}
Console.WriteLine("Query Success!");
Console.ReadKey();
}
代码优先开发-已有数据库-使用Entity Framework#
添加EF到项目中
选择【ADO.NET实体数据模型】
选择【来自数据库的Code First】
配置数据库连接
选择要添加到EF模型中数据表和视图
Visual Studio自动生成了上下文文DbContext文件
测试添加数据到数据库中
using(Model1 model1 = new Model1())
{
//添加数据到数据库中
PandaTable pandaTable = new PandaTable()
{
Name = "Donkey",
Code = "99999999",
Note = "This is Donkey"
};
model1.PandaTable.Add(pandaTable);
//保存修改
model1.SaveChanges();
}
作者:重庆熊猫
出处:https://www.cnblogs.com/cqpanda/p/16771173.html
版权:本作品采用「不论是否商业使用都不允许转载,否则按3元1字进行收取费用」许可协议进行许可。
本文来自博客园,作者:重庆熊猫,转载请注明原文链接:https://www.cnblogs.com/cqpanda/p/16771173.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix