简体   繁体   中英

Add POCO / Entity to DbContext for Custom Query / Procedure Without Creating a Table in Entity Framework Code First

Background

I am using EF Core 3 for an application with a number of POCOs in a DbContext that I want to be created as database tables - no problem here, I use Linq queries to get data here. and life is good.

I also have some raw SQL queries and procedures for some more complex reporting. I've created POCOs for the returned data, and added to the DbContext as a DbSet:

public class FooBarContext : DbContext
{
    // ...

    public DbSet<FooReport> FooReport { get; set; }

    // ...
}

Where FooReport looks like:

public class FooReport
{
    [Key]
    public int Id { get; set; }

    // ...
}

The Problem / Workaround

This creates a migration for creating a new table called FooReport , which isn't what I want.

My workaround right now is to manually remove this action from the Migration that is generated, so that, in essence, I have an empty migration:

public partial class AddFooReport : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // intentionally clear this out, so the entity isn't created / dropped as a table

        // migrationBuilder.CreateTable("FooReport", ... );
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        // intentionally clear this out, so the entity isn't created / dropped as a table

        // migrationBuilder.DropTable("FooReport");
    }
}

Then I'm able to call the procedure like so:

var result = this._fooBarContext.Set<FooReport>(@"[SP_FooReport]")
    .FromSqlRaw(sql)
    .ToList();

This does work , but seems hacky.

I also (unsuccessfully) tried to solve this problem by adding the NotMapped decorator to the FooReport POCO, but then the query itself fails.

TL;DR; - Can you define a DbSet as an entity that is specifically NOT a table?

You can try adding modelBuilder.Ignore<FooReport>(); call to OnModelCreating method on your DbContext or mark FooReport with NotMapped attribute.

In EF Core 3+ simply remove the Key from FooReport to make it a Keyless Entity Type

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    
 modelBuilder.Entity<FooReport>().HasNoKey();
 //. . .

}

In EF 5 there's an attribute for this too:

[Keyless]
public class FooReport
{
    public int Id { get; set; }

    // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM