将 POCO/实体添加到 DbContext 以进行自定义查询/过程,而无需先在实体框架代码中创建表
Posted
技术标签:
【中文标题】将 POCO/实体添加到 DbContext 以进行自定义查询/过程,而无需先在实体框架代码中创建表【英文标题】:Add POCO / Entity to DbContext for Custom Query / Procedure Without Creating a Table in Entity Framework Code First 【发布时间】:2020-10-12 18:46:58 【问题描述】:背景
我正在将 EF Core 3 用于在 DbContext 中具有多个 POCO 的应用程序,我希望将其创建为数据库表 - 这里没问题!我这里用Linq查询取数据,生活还不错。
我还有一些用于更复杂报告的原始 SQL 查询和过程。我为返回的数据创建了 POCO,并作为 DbSet 添加到 DbContext:
公共类 FooBarContext : DbContext // ... 公共 DbSetFooReport 获取;放; // ...
FooReport
的样子:
公共类 FooReport [钥匙] 公共 int ID 获取;放; // ...
问题/解决方法
这会为创建一个名为FooReport
的新表创建迁移,这不是我想要的。
我现在的解决方法是从生成的Migration
中手动删除此操作,这样,本质上,我有一个空迁移:
公共部分类 AddFooReport : 迁移 protected override void Up(MigrationBuilder migrationBuilder) // 有意清除它,因此实体不会作为表创建/删除 // migrationBuilder.CreateTable("FooReport", ... ); protected override void Down(MigrationBuilder migrationBuilder) // 有意清除它,因此实体不会作为表创建/删除 // migrationBuilder.DropTable("FooReport");
然后我可以像这样调用该过程:
var 结果 = this._fooBarContext.Set(@"[SP_FooReport]") .FromSqlRaw(sql) .ToList();
这确实有效,但看起来很老套。
我也(未成功)尝试通过将 NotMapped
装饰器添加到 FooReport
POCO 来解决此问题,但随后查询本身失败。
TL;DR; - 你能将DbSet
定义为一个不是表的实体吗?
【问题讨论】:
【参考方案1】:在 EF Core 3+ 中,只需从 FooReport 中删除密钥,使其成为 Keyless Entity Type
protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<FooReport>().HasNoKey();
//. . .
在 EF 5 中也有一个属性:
[Keyless]
public class FooReport
public int Id get; set;
// ...
【讨论】:
来自链接的文档,看起来正是我想要的,但是 IDE 说它没有定义——我可能缺少包引用吗?我本来希望它在Microsoft.EntityFrameworkCore.Design
啊,我现在看到它只在 EF Core 5+ 中可用,现在是预览版:-/ (***.com/questions/61396213/…)
查看更新。该功能在 EF Core 3 中,而不是属性。 EF Core 3 你必须在 OnModelCreating 中使用 Fluent Configuration。【参考方案2】:
您可以尝试在 DbContext 上将 modelBuilder.Ignore<FooReport>();
调用添加到 OnModelCreating
方法,或使用 NotMapped
属性标记 FooReport
。
【讨论】:
以上是关于将 POCO/实体添加到 DbContext 以进行自定义查询/过程,而无需先在实体框架代码中创建表的主要内容,如果未能解决你的问题,请参考以下文章
如何从DbContext中清除未插入的POCO? - 实体框架代码优先
EF 4.1 DbContext Generattor - 将实体放在不同的项目中?