网站后台改不了设置,深圳专业返利网站开发,产品工艺设计,公司网站建设说明书如何使用 ef core 的 code first 模式实现自定义类型转换器 前言 1. 项目结构2. 实现步骤2.1 定义转换器2.1.1 DateTime 转换器2.1.2 JsonDocument 转换器 2.2 创建实体类并配置数据结构类型2.3 定义 Utility 工具类2.4 配置 DbContext2.4.1 使用 EF Core 配置 DbContext 的两种… 如何使用 ef core 的 code first 模式实现自定义类型转换器 前言 1. 项目结构2. 实现步骤2.1 定义转换器2.1.1 DateTime 转换器2.1.2 JsonDocument 转换器 2.2 创建实体类并配置数据结构类型2.3 定义 Utility 工具类2.4 配置 DbContext2.4.1 使用 EF Core 配置 DbContext 的两种实现方式2.4.2 具体实现 MyDbContext 的两种方式 2.5 使用 DbContext 操作 Sqlite 数据库2.6 使用工具 dotnet ef 应用迁移2.6.1 执行 MyDb1Context 迁移2.6.2 执行 MyDb2Context 迁移 2.7 运行项目2.8 改造 ef core 使用仓储模式2.8.1 添加仓储Repositories层2.8.2 新增服务Services层 3. 安装 dotnet ef 工具3.1 安装 .NET SDK3.2 安装 Entity Framework Core 工具包3.3 使用 dotnet ef 命令 总结 前言
在使用 Entity Framework Core (EF Core) 的 Code First 模式时如果你想在 SQLite 数据库中存储 JsonDocument or DateTime 类型的数据需要确保数据类型的正确映射。
注意
- SQLite 默认没有 JsonDocument 类型而是使用 JSON 或 TEXT 类型来存储 JSON 值。
- SQLite 默认没有一个单独的用于存储日期和/或时间的存储类但 SQLite 能够把日期和时间存储为 TEXT、REAL 或 INTEGER 值。为了实现 JsonDocument DateTime 类型的正确转换你可以使用自定义 ValueConverter值转换器。下面是一个详细的示例展示如何实现 JsonDocument DateTime 到 SQLite JSON/TEXT 类型的转换。 关于 sqlite 更多数据类型请查看 https://www.runoob.com/sqlite/sqlite-data-types.html 1. 项目结构
创建控制台项目命名为 ConsoleApp1项目整体代码结构如下 项目中文件目录说明
1. Database 用于存放 Sqlite 的数据库文件.db;
2. Migrations 用于存放 dotnet ef migrations 应用迁移生产的类文件使用到的 NuGet 包信息如下
Project SdkMicrosoft.NET.SdkPropertyGroupOutputTypeExe/OutputTypeTargetFrameworknet8.0/TargetFrameworkImplicitUsingsenable/ImplicitUsingsNullableenable/Nullable/PropertyGroupItemGroupPackageReference IncludeMicrosoft.EntityFrameworkCore Version8.0.8 /PackageReference IncludeMicrosoft.EntityFrameworkCore.Design Version8.0.8PrivateAssetsall/PrivateAssetsIncludeAssetsruntime; build; native; contentfiles; analyzers; buildtransitive/IncludeAssets/PackageReferencePackageReference IncludeMicrosoft.EntityFrameworkCore.Sqlite Version8.0.8 /PackageReference IncludeMicrosoft.Extensions.DependencyInjection Version8.0.0 //ItemGroupItemGroupFolder IncludeDatabase\ /Folder IncludeMigrations\ //ItemGroup/Project2. 实现步骤
2.1 定义转换器
分别实现如下转换器
DateTime 转换器DateTimeToStringConverterJsonDocument 转换器JsonDocumentToStringConverter
2.1.1 DateTime 转换器
首先定义一个值转换器将 DateTime 转换为 string对应 SQLite 中的 TEXT 类型。
代码示例
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;namespace ConsoleApp1.TypeConverters;/// summary
/// DateTime 转换器
/// /summary
internal class DateTimeToStringConverter : ValueConverterDateTime, string
{/// summary/// 日期格式/// /summaryprivate static readonly string _timeFormat yyyy-MM-dd HH:mm:ss.SSS;public DateTimeToStringConverter(ConverterMappingHints? mappingHints null): base(v v.ToString(_timeFormat),v DateTime.ParseExact(v, _timeFormat, null),mappingHints){ }
}2.1.2 JsonDocument 转换器
接下来定义一个值转换器将 JsonDocument 转换为 string对应 SQLite 中的 TEXT 类型。
代码示例
using System.Text.Json;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;namespace ConsoleApp1.TypeConverters;/// summary
/// JsonDocument 转换器
/// /summary
internal class JsonDocumentToStringConverter : ValueConverterJsonDocument, string?
{public JsonDocumentToStringConverter() : base(jsonDocument jsonDocument.RootElement.GetRawText(),jsonString JsonStringToJsonDocument(jsonString, GetJsonDocumentOptions())){ }#region 私有方法/// summary/// json 字符串转换 JsonDocument 对象/// /summary/// param namejsonString/param/// param nameoptions/param/// returns/returnsprivate static JsonDocument JsonStringToJsonDocument(string? jsonString, JsonDocumentOptions? options){if (jsonString null)return JsonDocument.Parse({});return JsonDocument.Parse(jsonString);}/// summary/// JsonDocument 配置信息/// /summary/// returns/returnspublic static JsonDocumentOptions GetJsonDocumentOptions(){var options new JsonDocumentOptions(){MaxDepth 128, // 设置最大深度CommentHandling JsonCommentHandling.Skip, // 允许跳过注释AllowTrailingCommas true // 允许尾随逗号};return options;}#endregion
}2.2 创建实体类并配置数据结构类型
定义实体类型 MyEntity 和 MyEntityTypeConfiguration 实体类型配置代码示例如下
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore;
using System.Text.Json;
using System.ComponentModel.DataAnnotations.Schema;
using ConsoleApp1.TypeConverters;namespace ConsoleApp1.Entitys;/// summary
/// 实体对象
/// /summary
internal class MyEntity
{public string Id { get; set; } Guid.NewGuid().ToString();public int RandomNo { get; set; }[Column(TypeName json)]public JsonDocument Data { get; set; } JsonDocument.Parse({ });[Column(TypeName text)]public DateTime CreatedTime { get; set; }
}/// summary
/// 实体类型定义此处使用 code first fluent api 方式
/// /summary
internal class MyEntityTypeConfiguration : IEntityTypeConfigurationMyEntity
{public void Configure(EntityTypeBuilderMyEntity entity){entity.ToTable(nameof(MyEntity)); // 指定表名为 Artifactentity.HasKey(a a.Id); // 指定主键PKentity.Property(p p.Id).HasColumnName(Id).HasColumnType(TEXT).HasMaxLength(36).IsRequired();entity.Property(p p.RandomNo).HasColumnName(RandomNo).HasColumnType(INTEGER).IsRequired();entity.Property(a a.Data).HasConversion(new JsonDocumentToStringConverter()).HasColumnName(Data).HasColumnType(JSON).IsRequired();entity.Property(a a.CreatedTime).HasConversion(new DateTimeToStringConverter()).HasColumnName(CreatedTime).HasColumnType(TEXT).HasMaxLength(16).IsRequired();}
}2.3 定义 Utility 工具类
定义文件目录助手 DirectoryHelper用于指定 sqlite 数据库文件存储位置同时构建 sqlite 数据库连接字符串。示例代码如下
using Microsoft.Data.Sqlite;namespace ConsoleApp1.Utility;/// summary
/// 目录助手
/// /summary
internal class DirectoryHelper
{/// summary/// 获取当前目录/// /summarypublic string CurrentDirectory Directory.GetCurrentDirectory();/// summary/// 设置根目录/// /summary/// param namedirectory跟目录名称/param/// returns/returnspublic string BuildRootDirectory(string directory) Path.Combine(CurrentDirectory, directory);#region 构建 sqlite 连接字符串public string GetSqliteConnectionString(string directory Database, string password 123456){// 设置根目录string rootDirectory BuildRootDirectory(directory);string sqliteFilePath Path.Combine(rootDirectory, test.db);//string connectionString $Data Source{ sqliteFilePath };ModeMemory;CacheShared; //可共享内存数据库return BuildSqliteConnectionString(sqliteFilePath, password);}public string BuildSqliteConnectionString(string filePath, string password){var builder new SqliteConnectionStringBuilder(){DataSource filePath,Cache SqliteCacheMode.Shared,Mode SqliteOpenMode.ReadWriteCreate,// Password password, // 此处对应的 nuget 包暂不支持密码设置Pooling true,DefaultTimeout 30,};return builder.ToString();} #endregion
}2.4 配置 DbContext
2.4.1 使用 EF Core 配置 DbContext 的两种实现方式
首先我们来看下 DbContext 的两种配置方式
namespace Microsoft.EntityFrameworkCore;protected DbContext();
public DbContext([NotNullAttribute] DbContextOptions options);还有 DbContext 的两个重写方法
protected internal virtual void OnConfiguring(DbContextOptionsBuilder optionsBuilder);
protected internal virtual void OnModelCreating(ModelBuilder modelBuilder);4.1.1 使用无参构造函数必须重写 OnConfiguring() 函数
代码示例
public class BloggingContext : DbContext
{public DbSetBlog Blogs { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) optionsBuilder.UseSqlite(Data Sourceblog.db);
}这样使用的话应用程序可以简单地实例化此类上下文而无需将任何内容传递给构造函数
using (var context new BloggingContext())
{// do stuff
}4.1.2 使用有参构造函数无需重写 OnConfiguring() 函数
代码示例
public class BloggingContext : DbContext
{public BloggingContext(DbContextOptionsBloggingContext options) : base(options){ }public DbSetBlog Blogs { get; set; }
}这样使用的话应用程序现在可以在实例化上下文时传递 DbContextOptions如下所示
var optionsBuilder new DbContextOptionsBuilderBloggingContext();
optionsBuilder.UseSqlite(Data Sourceblog.db);using (var context new BloggingContext(optionsBuilder.Options))
{// do stuff
}控制台使用有参构造函数方式的 DbContext 数据库上下文使用 dotnet ef migrations 命令时会出现如下异常信息
Unable to create a DbContext of type MyDbContext. The exception Unable to resolve service for type Microsoft.EntityFrameworkCore.DbContextOptions1[ConsoleApp1.DbContexts.MyDbContext] while attempting to activate ConsoleApp1.DbContexts.MyDbContext. was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid851728大概意思就是 MyDbContext 主构函数里面的 DbContextOptionsMyDbContext 无法识别依赖注入问题。解决方案如下
“可以通过实现接口来告诉工具如何创建 DbContext通过创建类实现接口IDesignTimeDbContextFactoryTContext如果实现此接口的类在与派生的项目相同的项目中或应用程序的启动项目中找到则这些工具将绕过创建 DbContext 的其他方法并改用设计时工厂。”
实现接口 IDesignTimeDbContextFactoryTContext 的代码示例
public class BloggingContextFactory : IDesignTimeDbContextFactoryBloggingContext
{public BloggingContext CreateDbContext(string[] args){var optionsBuilder new DbContextOptionsBuilderBloggingContext();optionsBuilder.UseSqlite(Data Sourceblog.db);return new BloggingContext(optionsBuilder.Options);}
}使用 AddDbContextFactory 添加有参主构函数 BloggingContext 的示例代码
// 创建服务容器
var serviceCollection new ServiceCollection();
// 添加有参主构函数的 BloggingContext
serviceCollection.AddDbContextFactoryBloggingContext(options options.UseSqlite(connectionString));2.4.2 具体实现 MyDbContext 的两种方式
上面我们解释了实现 DbContext 的两种方式接着前面提到的 Demo 示例实现代码示例如下 注意区分 MyDb1Context 和 MyDb2Context 的实现。 4.2.1 无参构造函数实现 DbContext命名为 MyDb1Context
using ConsoleApp1.Entitys;
using ConsoleApp1.Utility;
using Microsoft.EntityFrameworkCore;namespace ConsoleApp1.DbContexts;/// summary
/// 数据库上下文无参构造函数实现
/// /summary
/// param nameoptions/param
internal class MyDb1Context : DbContext
{public DbSetMyEntity MyEntitys { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfiguration(new MyEntityTypeConfiguration());/** 此处代码等效同上 ApplyConfigurationmodelBuilder.EntityMyEntity().Property(e e.Data).HasConversion(new JsonDocumentToStringConverter());*/}/// summary/// 注意无参构造函数必须重写 OnConfiguring() 函数/// /summary/// param nameoptionsBuilder/paramprotected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){base.OnConfiguring(optionsBuilder);var directoryHelper new DirectoryHelper();string connectionString directoryHelper.GetSqliteConnectionString(); optionsBuilder.UseSqlite(connectionString);}
}4.2.2 有参构造函数实现 DbContext命名为 MyDb2Context
using ConsoleApp1.Entitys;
using Microsoft.EntityFrameworkCore;namespace ConsoleApp1.DbContexts;/// summary
/// 数据库上下文有参构造函数实现
/// /summary
/// param nameoptions/param
internal class MyDb2Context(DbContextOptionsMyDb2Context options) : DbContext(options)
{public DbSetMyEntity MyEntitys { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.ApplyConfiguration(new MyEntityTypeConfiguration());}
}MyDb2ContextFactory 实现 IDesignTimeDbContextFactoryMyDb2Context 的代码示例
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore;
using ConsoleApp1.Utility;namespace ConsoleApp1.DbContexts;/// summary
/// MyDb2Context 工厂
/// /summary
internal class MyDb2ContextFactory : IDesignTimeDbContextFactoryMyDb2Context
{public MyDb2Context CreateDbContext(string[] args){// 获取 sqlite 连接字符串var directoryHelper new DirectoryHelper();string connectionString directoryHelper.GetSqliteConnectionString();// 构建 DbContextOptions 对象var optionsBuilder new DbContextOptionsBuilderMyDb2Context();optionsBuilder.UseSqlite(connectionString);// 有参构造函数使用 DbContextOptions 对象return new MyDb2Context(optionsBuilder.Options);}
}2.5 使用 DbContext 操作 Sqlite 数据库
上面代码已经准备就绪接着我们来使用实现 DbContext 的自定义上下文来操作 Sqlite 数据库。
在 Program.cs 文件的 Main 函数代码示例如下
using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using ConsoleApp1.DbContexts;
using ConsoleApp1.Entitys;
using ConsoleApp1.Utility;
using ConsoleApp1.TypeConverters;namespace ConsoleApp1;internal class Program
{static void Main(string[] args){Console.WriteLine(Hello, Microsoft.EntityFrameworkCore.Sqlite!);{// 创建实体数据var entity new MyEntity{RandomNo Random.Shared.Next(0, 100),Data JsonDocument.Parse({\name\:\John\, \age\:30}, JsonDocumentToStringConverter.GetJsonDocumentOptions()),CreatedTime DateTime.Now};// 创建服务提供者var serviceProvider ConfigureServices();// 获取服务实例//using var context serviceProvider.GetServiceMyDb1Context();using var context serviceProvider.GetServiceMyDb2Context();// 使用服务// 新增数据context?.MyEntitys.Add(entity);context?.SaveChanges();// 读取数据var savedEntity context?.MyEntitys.FirstOrDefault(e e.Id entity.Id);var name savedEntity?.Data.RootElement.GetProperty(name).GetString();Console.WriteLine(name); // 输出 John}}/// summary/// 注册服务/// /summary/// returns/returnsprivate static ServiceProvider ConfigureServices(){// 创建服务容器var serviceCollection new ServiceCollection();#region 添加 EF Core DbContextserviceCollection.AddDbContextMyDb1Context();var directoryHelper new DirectoryHelper();string connectionString directoryHelper.GetSqliteConnectionString();serviceCollection.AddDbContextFactoryMyDb2Context(options options.UseSqlite(connectionString));#endregion// 构建 ServiceProvider 服务提供者return serviceCollection.BuildServiceProvider();}
}2.6 使用工具 dotnet ef 应用迁移
使用工具 dotnet ef 创建并应用迁移以生成数据库表结构。
2.6.1 执行 MyDb1Context 迁移
执行 MyDb1Context 迁移命令
# 创建迁移
dotnet ef migrations add test_v1.0.0 -c MyDb1Context
# 应用迁移
dotnet ef database update -c MyDb1Context输出信息
PS D:\Jeff\Project\Demo\ConsoleApp1 dotnet ef migrations add test_v1.0.0 -c MyDb1Context
Build started...
Build succeeded.
Done. To undo this action, use ef migrations remove
PS D:\Jeff\Project\Demo\ConsoleApp1 dotnet ef database update -c MyDb1Context
Build started...
Build succeeded.
Applying migration 20240904085736_test_v1.0.0.
Done.2.6.2 执行 MyDb2Context 迁移
执行 MyDb2Context 迁移命令
# 创建迁移
dotnet ef migrations add test_v1.0.1 -c MyDb2Context
# 应用迁移
dotnet ef database update -c MyDb2Context输出信息
PS D:\Jeff\Project\Demo\ConsoleApp1 dotnet ef migrations add test_v1.0.1 -c MyDb2Context
Build started...
Build succeeded.
Done. To undo this action, use ef migrations remove
PS D:\Jeff\Project\Demo\ConsoleApp1 dotnet ef database update -c MyDb2Context
Build started...
Build succeeded.
Applying migration 20240904090346_test_v1.0.1.
Done.查看迁移生成 sqlite 文件 test.db 中数据库表结构是否和实体类型配置一致从下图中可以看到符合预期。 通过实验证明上面两种方式均可实现应用迁移。
2.7 运行项目
启动项目运行均可执行 sqlite 数据库操作方法。 注意使用 dotnet ef 命令生成的 sqlite 数据库文件设置属性复制内容
ItemGroupNone RemoveDatabase\test.db /
/ItemGroupItemGroupContent IncludeDatabase\test.dbCopyToOutputDirectoryAlways/CopyToOutputDirectory/Content
/ItemGroup2.8 改造 ef core 使用仓储模式 说明此处实现 MyDb1Context 的仓储模式实现 MyDb2Context 等效类似。 2.8.1 添加仓储Repositories层
项目新增 Repositories 文件目录分别添加如下代码文件
IMyEntityRepository 实体 crud 接口定义
using ConsoleApp1.Entitys;namespace ConsoleApp1.Repositories;internal interface IMyEntityRepository
{Taskstring? AddAsync(MyEntity entity);TaskMyEntity? GetAsync(string id);TaskListMyEntity GetListAsync(Liststring ids);
}MyEntityRepository 实体 crud 接口实现
using ConsoleApp1.DbContexts;
using ConsoleApp1.Entitys;
using Microsoft.EntityFrameworkCore;namespace ConsoleApp1.Repositories;internal class MyEntityRepository(MyDb1Context context) : IMyEntityRepository
{private readonly MyDb1Context _context context ?? throw new ArgumentNullException(nameof(context));public async Taskstring? AddAsync(MyEntity entity){await _context.MyEntitys.AddAsync(entity);await _context.SaveChangesAsync();return entity.Id;}public async TaskMyEntity? GetAsync(string id){return await _context.MyEntitys.FirstOrDefaultAsync(x x.Id id);}public async TaskListMyEntity GetListAsync(Liststring ids){return await _context.MyEntitys.Where(x ids.Contains(x.Id)).ToListAsync();}
}添加 仓储对象 DI 注入
在 Program.cs 文件的 ConfigureServices() 方法中添加 MyDb1Context 对应的仓储对象注入代码示例如下 /// summary/// 注册服务/// /summary/// returns/returnsprivate static ServiceProvider ConfigureServices(){// 创建服务容器var serviceCollection new ServiceCollection();#region 添加 EF Core DbContextserviceCollection.AddDbContextMyDb1Context();var directoryHelper new DirectoryHelper();string connectionString directoryHelper.GetSqliteConnectionString();serviceCollection.AddDbContextFactoryMyDb2Context(options options.UseSqlite(connectionString));#endregion// 注入 MyDb1Context 仓储模式serviceCollection.AddScopedIMyEntityRepository, MyEntityRepository();// 构建服务提供者return serviceCollection.BuildServiceProvider();}修改 Main 方法
此处 MyDb1Context 实现的仓储模式方法是异步化相应的修改 Main 方法也异步化代码示例
static async Task Main(string[] args)
{Console.WriteLine(Hello, Microsoft.EntityFrameworkCore.Sqlite!);// 创建实体数据var entity new MyEntity{RandomNo Random.Shared.Next(0, 100),Data JsonDocument.Parse({\name\:\John\, \age\:30}, JsonDocumentToStringConverter.GetJsonDocumentOptions()),CreatedTime DateTime.Now};// 创建服务提供者var serviceProvider ConfigureServices();{/*// 1.常规模式// 获取服务实例//using var context serviceProvider.GetServiceMyDb1Context();using var context serviceProvider.GetServiceMyDb2Context();// 使用服务// 新增数据context?.MyEntitys.Add(entity);context?.SaveChanges();// 读取数据var savedEntity context?.MyEntitys.FirstOrDefault(e e.Id entity.Id);var name savedEntity?.Data.RootElement.GetProperty(name).GetString();Console.WriteLine(name); // 输出 John*/}{// 2.仓储模式// 获取服务实例var repository serviceProvider.GetServiceIMyEntityRepository();if (repository ! null){// 使用服务新增数据var id await repository!.AddAsync(entity);// 读取数据var savedEntity await repository!.GetAsync(id);var name savedEntity?.Data.RootElement.GetProperty(name).GetString();Console.WriteLine(name); // 输出 John}}
}2.8.2 新增服务Services层
项目添加 Services 文件目录 分别添加如下代码文件
IMyEntityService 实体 crud 接口定义
using Sample.ConsoleApp.CodeFist.Sqlite.Entitys;namespace Sample.ConsoleApp.CodeFist.Sqlite.Services;internal interface IMyEntityService
{Taskstring? AddAsync(MyEntity entity);TaskMyEntity? GetAsync(string id);TaskListMyEntity GetListAsync(Liststring ids);
}MyEntityService 实体 crud 接口实现
using Microsoft.Extensions.Logging;
using Sample.ConsoleApp.CodeFist.Sqlite.Entitys;
using Sample.ConsoleApp.CodeFist.Sqlite.Repositories;namespace Sample.ConsoleApp.CodeFist.Sqlite.Services;internal class MyEntityService(ILoggerMyEntityService logger,IMyEntityRepository myEntityRepository) : IMyEntityService
{public async Taskstring? AddAsync(MyEntity entity){return await myEntityRepository.AddAsync(entity);}public async TaskMyEntity? GetAsync(string id){return await myEntityRepository.GetAsync(id);}public async TaskListMyEntity GetListAsync(Liststring ids){return await myEntityRepository.GetListAsync(ids);}
}注入DI服务 // 注入 MyDb1Context 仓储模式serviceCollection.AddScopedIMyEntityRepository, MyEntityRepository();// 注入 IMyEntityService 服务serviceCollection.AddScopedIMyEntityService, MyEntityService();到此步骤我的服务就改造支持仓储模式了在业务系统中个人推荐使用仓储模式Repositories可以更好的隔离且解耦业务代码从而提升代码的可维护性和扩展性。
3. 安装 dotnet ef 工具
安装 dotnet efEntity Framework Core 的命令行工具非常简单。以下是如何在不同的环境中安装和使用 dotnet ef 的详细步骤。
3.1 安装 .NET SDK
首先确保你已经安装了 .NET SDK。如果没有安装请访问 官方下载页面 下载并安装最新版本的 .NET SDK。
3.2 安装 Entity Framework Core 工具包
接下来安装 Entity Framework Core 工具包。你可以通过以下两种方式之一进行安装
方式一全局安装
打开命令提示符或终端。运行以下命令来全局安装 Entity Framework Core 工具包
dotnet tool install --global dotnet-ef验证安装是否成功
dotnet ef --version如果安装成功你会看到 Entity Framework Core 的版本号。
方式二本地安装
如果你想在特定项目中安装 Entity Framework Core 工具包可以在项目目录中执行以下命令
打开命令提示符或终端。导航到你的项目目录。运行以下命令来安装 Entity Framework Core 工具包
dotnet tool install --tool-path . dotnet-ef验证安装是否成功
./dotnet-ef --version如果安装成功你会看到 Entity Framework Core 的版本号。
3.3 使用 dotnet ef 命令
现在你可以在项目中使用 dotnet ef 命令了。
PS C:\Windows\system32 dotnet ef migrations -hUsage: dotnet ef migrations [options] [command]Options:-h|--help Show help information-v|--verbose Show verbose output.--no-color Dont colorize output.--prefix-output Prefix output with level.Commands:add Adds a new migration.bundle Creates an executable to update the database.has-pending-model-changes Checks if any changes have been made to the model since the last migration.list Lists available migrations.remove Removes the last migration.script Generates a SQL script from migrations.Use migrations [command] --help for more information about a command.以下是一些常用的命令示例
# 创建迁移
dotnet ef migrations add InitialCreate
# 应用迁移这将应用所有未应用的迁移。
dotnet ef database update
# 查看迁移状态这将列出所有已创建的迁移及其状态。
dotnet ef migrations list
# 删除迁移这将删除最后一个迁移文件。
dotnet ef migrations remove
# 清空迁移历史记录这将删除数据库并清空迁移历史记录。
dotnet ef database drop
dotnet ef migrations remove总结
我们介绍了如何在 EF Core 的 Code First 模式下使用自定义类型转换器实现 JsonDocument 和 DateTime 类型到 SQLite 数据库的正确映射。通过自定义 ValueConverter实现了数据类型的转换并展示了完整的项目结构和代码实现包括实体类定义、DbContext 配置及数据库应用迁移Migrations操作。