将 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

    // ...

    公共 DbSet FooReport  获取;放; 

    // ...

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&lt;FooReport&gt;(); 调用添加到 OnModelCreating 方法,或使用 NotMapped 属性标记 FooReport

【讨论】:

以上是关于将 POCO/实体添加到 DbContext 以进行自定义查询/过程,而无需先在实体框架代码中创建表的主要内容,如果未能解决你的问题,请参考以下文章

如何从DbContext中清除未插入的POCO? - 实体框架代码优先

实体中的业务逻辑并注入 DbContext

EF 4.1 DbContext Generattor - 将实体放在不同的项目中?

使用 Automapper,将 DTO 映射回实体框架,包括引用的实体

生成 <DbContext> 时出错

没有行为的实体框架 POCO - 需要重新设计以消除代码异味