【EF Core】EF Core 6.0 连接Sqlite3
概览
EF Core 6.0 是建立在ADO.NET框架之上的,它下面仍旧使用了ADO.NET方法和类来执行数据操作。DbContext负责将sqlite翻译成sqlite,跟踪数据状态。
EF Core 6.0底层是Miscrosoft.Data.sqlite。DbContext
,这个类是EF Code First的核心,在高层次上是数据库抽象,DbContext是一级缓存。DBSet类表示一个实体的集合,用来创建、更新、删除、查询操作,DBSet<TEntity>是DBSet的泛型版本,可以使用DbContext获取DBSet的引用,例如dbContext.PersonInfo
s
将实体映射到数据表格方式有两种:特性和Fluent API
学习顺序
1、了解ORM概念、POCO 类型、linq、mvvm模式
2、了解EF Core 6.0的历史、为什么要使用EF Core、Entity Framework的三种开发风格
3、了解DbSet与DbContext、模型、配置模型
4、DbSet crud操作 ,详细查看https://learn.microsoft.com/zh-cn/ef/core/performance/advanced-performance-topics?tabs=with-di%2Cwith-constant#dbcontext-pooling
开始实操(CodeFirst的数据库初始化)
1)环境:vs2022+.net6.0+EF Core 6.0 +sqlite3+mvvm模式
2)创建WPF应用程序MvvmDemo并且安装实体框架 NuGet 包 Microsoft.EntityFrameworkCore.qlite(6.0.9)、安装 Sqlite 包后,并且安装Microsoft.EntityFrameworkCore 基础包。可以选择安装 Microsoft.EntityFrameworkCore.Proxies 包提供对“延迟加载”数据的支持。
3)创建sqlite数据库Data.db和PersonInfo表
4)C# 创建实体模型 PersonInfo.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; namespace MvvmDemo.Mvvm.Models { public class Student { [Key] public string Name { get; set; } public string Age { get; set; } } public class PersonInfo : IDataErrorInfo { /// <summary> /// 对应数据库中 表格 /// </summary> /// #region 实体 private string? _email; //字段不会有映射到数据库的表格 private string? _firstName; private string? _lastName; [Column("Company")] //对应数据库中表的列 public string? Company { get; set; } [Column("FirstName")] //对应数据库中表的列 public string FirstName { get { return _firstName; } set { _firstName = value; } } [Column("LastName")] //对应数据库中表的列 public string? LastName { get { return _lastName; } set { _lastName = value; } } [Column("Email")] //对应数据库中表的列 [Key]//主键 public string Email { get; set; } [Column("IsCompany")] //对应数据库中表的列 public bool IsCompany { get; set; } = false; [Column("TotalSales")] //对应数据库中表的列 public double? TotalSales { get; set; } #endregion //不映射到对应数据库中表的列 public bool IsValid { get { foreach (string item in ValidationProperties) { if (string.IsNullOrEmpty(ValidationError(item))) return true; } return false; } } [NotMapped] //不映射到对应数据库中表的列 public string? IsSelected { get; set; } public PersonInfo() { } string IDataErrorInfo.Error => throw new NotImplementedException();//用于表格的行验证 //用于单元格属性验证 string IDataErrorInfo.this[string propertyName] => ValidationError(propertyName); private string? ValidationError(string propertyName) { //哪些属性需要验证 if (Array.IndexOf(ValidationProperties, propertyName) < 0) return null; switch (propertyName) { case "FirstName": return ValidationFirstName(); case "LastName": return ValidationLastName(); case "Company": return ValidationCompany(); case "Email": return ValidationEmail(); default: return ""; } } private string? ValidationEmail() { if (String.IsNullOrEmpty(_email)) return GetPropertyValue("EmailIsNotNull"); string partn = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; ; if (!Regex.IsMatch(_email, partn, RegexOptions.IgnoreCase)) { return GetPropertyValue("EmailFormatIsError"); } return null; } private string ValidationCompany() { throw new NotImplementedException(); } private string? ValidationLastName() { //本地化错误提示 if (String.IsNullOrEmpty(_firstName)) return GetPropertyValue("FirstName_NameIsNotnull"); if (_firstName.Length <= 5) return GetPropertyValue("FirstName_NameLengthMore5char"); return null; } static readonly string[] ValidationProperties = { "Email", "FirstName", "LastName", }; private string ValidationFirstName() { //本地化错误提示 if (String.IsNullOrEmpty(_firstName)) return GetPropertyValue("FirstName_NameIsNotnull"); if (_firstName.Length <= 5) return GetPropertyValue("FirstName_NameLengthMore5char"); return ""; } string GetPropertyValue(string name) { return (string)Application.Current.Resources[name]; } private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>(); public PersonInfo(string firstName, string? lastName, string email, bool isCompany, double? totalSales) { FirstName = firstName; LastName = lastName; Email = email; IsCompany = isCompany; TotalSales = totalSales; } } }
5)配置数据连接 App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings > <!--相对与当前目录的路径--> <add name="LoginString" connectionString="Data Source=D:\程序开发\观察者\mvvmdemo\MvvmDemo\MvvmDemo\Repositories\Data.db; " providerName="Microsoft.EntityFrameworkCore.Sqlite" /> </connectionStrings> </configuration>
6)建立实体和数据库表格映射。
有两种方式建立实体和数据表格之间映射关系。
在自定义的上下文DataContext 中采用Fluent API方式建立实体和数据库表格映射关系。详细查看微软官网 FluentAPI详细用法
在实体中通过Attribute特性建立实体和数据库表格映射关系。详细查看微软官网
定制DataContext 上下文,模型映射(Model Mapping),用于连接数据和poco
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Sqlite; using MvvmDemo.Mvvm.Models; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MvvmDemo.Repositories { public class DataContext : DbContext { private readonly string _connection; public DbSet<PersonInfo> PersonInfos{get;set;}//实体表,提供给外部crud使用,PersonInfos内部有DataContext 的实例 public DataContext() { //1、获取连接数据库的字符串 _connection = ConfigurationManager.ConnectionStrings["LoginString"].ConnectionString; } //2、联接数据库 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite(_connection); } //3、建立实体和数据库表格 一 一 映射。 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<PersonInfo>() .ToTable("PersonInfos"); } } }
7)可选配置.Net EF中DbContext动态生成DbSet
平时我们在使用EF的过程中,都是有DbContext中每一个表加一个DbSet,如果我们一个项目有上千个表,就得加上千个DbSet,是很麻烦的一个工程,现在采用一个简单的方法处理,在DbContext类的OnConfiguring方法中加上如下代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.ExportedTypes)
{
if (type.IsClass && type != typeof(EntityBase) && typeof(EntityBase).IsAssignableFrom(type))
{
var method = modelBuilder.GetType().GetMethods().Where(x => x.Name == "Entity").FirstOrDefault();
if (method != null)
{
method = method.MakeGenericMethod(new Type[] { type });
method.Invoke(modelBuilder, null);
}
}
}
base.OnModelCreating(modelBuilder);
}
动态加载,不用再一个一个写了,简单方便
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!