Entity Framework操作SQLite时如何访问数据表及区分同实体多DbSet
关于Entity Framework中同实体类型多DbSet的区分访问方案
误区澄清
Entity Framework 的表访问逻辑和使用的数据库提供者(SQL Server/SQLite 等)没有关系,你在SQLite场景下无法直接通过
_SqliteDBContext.Messages访问表,核心原因是你的SqliteDBContext类中没有定义对应的DbSet<Message> Messages公开属性,补充定义后即可和SQL Server场景一样直接通过属性访问表,不需要强制调用Set<>()方法。
同实体类型多DbSet的区分方案
如果需要给同一个Message实体类型绑定两个DbSet、分别对应两张不同的物理表,必须手动配置映射规则,否则EF默认会将两个DbSet都映射到同一张表,无法区分。
方案1:通过Fluent API配置映射(推荐)
在你的SqliteDBContext的OnModelCreating方法中,分别给两个DbSet指定对应的物理表名,EF Core 5及以上版本可以直接使用HasDbSet方法关联属性:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置Messages属性对应物理表Messages modelBuilder.Entity<Message>() .ToTable("Messages") .HasDbSet(nameof(Messages)); // 配置OtherTypes属性对应物理表OtherTypes modelBuilder.Entity<Message>() .ToTable("OtherTypes") .HasDbSet(nameof(OtherTypes)); }
配置完成后即可直接通过属性访问不同的表:
// 查询Messages表 var messageFromTable1 = _SqliteDBContext.Messages.Where(m => m.id == id).FirstOrDefault(); // 查询OtherTypes表 var messageFromTable2 = _SqliteDBContext.OtherTypes.Where(m => m.id == id).FirstOrDefault();
方案2:查询时显式指定表名
如果不想修改模型配置,也可以在每次查询时调用ToTable扩展方法指定要操作的表:
// 查询Messages表 var messageFromTable1 = _SqliteDBContext.Set<Message>().ToTable("Messages").Where(m => m.id == id).FirstOrDefault(); // 查询OtherTypes表 var messageFromTable2 = _SqliteDBContext.Set<Message>().ToTable("OtherTypes").Where(m => m.id == id).FirstOrDefault();
注意事项
- 两个物理表
Messages和OtherTypes的结构必须和Message类的属性完全匹配,否则查询时会抛出字段映射异常 - 增删改操作也遵循同样的规则,只要配置了映射,直接对对应
DbSet执行操作就会作用到关联的物理表上
内容的提问来源于stack exchange,提问作者Luca Prodan
相关产品推荐
相关产品推荐

