Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to exclude/skip/ignore parts of the model from migrations so that a table is not created (for overlapping bounded contexts) #2725

Closed
brent-russell opened this issue Jul 28, 2015 · 47 comments · Fixed by #21390
Labels
area-migrations area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. punted-for-3.0 type-enhancement
Milestone

Comments

@brent-russell
Copy link

brent-russell commented Jul 28, 2015

I suggest having an attribute that can be applied to DbSet properties in a DbContext, which indicates whether or not to include them in the migration scaffolding process.

An example use case is when part of an application's database is replicated from another environment. Replicated entities will be included in the same DbContext as custom-developed entities so they can be queried. During development many migrations may be performed. Each time a migration is scaffolded, the replicated entities will be added to the migration, and then must be removed manually.

If an attribute only used for EF commands is too polluting to include in the DbContext, some alternatives might be: an additional config file that can be specified on the command line listing which entities should be excluded. Or perhaps additional command line arguments that allow a migration to be generated for specified entities only instead of scanning and comparing all entities.

Also consider the scenario of inherited models when looking at this feature #5572

@rowanmiller rowanmiller changed the title "Exclude from Migration" Attribute for DbSet Ability to exclude parts of the model from migrations (for overlapping bounded contexts) Jul 30, 2015
@rowanmiller rowanmiller added this to the Backlog milestone Jul 30, 2015
@rowanmiller
Copy link
Contributor

Agreed that this would be good to enable. Generalized the title a bit as an attribute may or may not be the best way to do this. An attribute may be good sugar over a more powerful hook to exclude parts of the model.

Moving to backlog as we will look at this after the first stable release.

@wwarby
Copy link

wwarby commented Jan 19, 2016

+1, this to would be extremely useful.

@rowanmiller rowanmiller changed the title Ability to exclude parts of the model from migrations (for overlapping bounded contexts) Ability to exclude/skip/ignore parts of the model from migrations so that a table is not created (for overlapping bounded contexts) Jan 21, 2016
@maleet
Copy link

maleet commented Mar 18, 2016

+1

1 similar comment
@ownakas1mon
Copy link

+1

@soeron
Copy link

soeron commented Sep 8, 2016

+1 any status on this item?

1 similar comment
@neridonk
Copy link

+1 any status on this item?

@rowanmiller
Copy link
Contributor

No updates. We want to do it, but there are several items higher than it on the backlog.

@omayhemo
Copy link

omayhemo commented Feb 17, 2017

Those items listed as higher on the backlog have now been closed. When can we expect inclusion to a sprint?

@rowanmiller
Copy link
Contributor

The main features we talk about being higher priority are the ones listed here https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features. There is still quite a list of them that have not been implemented.

@thiennn
Copy link

thiennn commented Mar 15, 2017

I just found a workaround

  1. Create another DbContext that inherit your DbContext, for example MigrationDbContext. Override the OnModelCreating method and ingore entities that you want it's table not being generated.
 protected override void OnModelCreating(ModelBuilder builder)
 {
     base.OnModelCreating(builder);
     builder.Ignore<Category>();
 }
  1. Create another class that implement IDbContextFactory. For example
    public class MigrationContextFactory : IDbContextFactory<MigrationDbContext>
    {
        public MigrationDbContext Create()
        {
            var optionsBuilder = new DbContextOptionsBuilder<MigrationDbContext>();
            optionsBuilder.UseSqlite("Data Source=blog.db");

            return new MigrationDbContext(optionsBuilder.Options);
        }
    }

The migration tool will discover this MigrationContextFactory and use the MigrationDbContext.

@Oskarsson
Copy link

+1, This would make it possible to use ef core in plugin based architectures with each context inheriting from the core context with working relationships between contexts.

@Mucaccino
Copy link

+1

1 similar comment
@soeron
Copy link

soeron commented May 29, 2017

+1

AndriySvyryd added a commit that referenced this issue Feb 13, 2020
Use the new model in migrations and update pipeline

Part of #12846, #2725, #8258, #15671, #17270
AndriySvyryd added a commit that referenced this issue Feb 13, 2020
Use the new model in migrations and update pipeline

Part of #12846, #2725, #8258, #15671, #17270
AndriySvyryd added a commit that referenced this issue Feb 13, 2020
Use the new model in migrations and update pipeline

Part of #12846, #2725, #8258, #15671, #17270
@webwarrior06
Copy link

I solved it checking from where the entity builder is called, (from "add-migration Xyz" command or the normal dbContext operations) If a migration operation calls the builder, I ignore the entity that I want to ignore just for migration purposes.
Here is my workaround;
https://stackoverflow.com/a/62281191/1928672

AndriySvyryd added a commit that referenced this issue Jun 23, 2020
Store the entity types mapped to views in the snapshot

Fixes #2725
AndriySvyryd added a commit that referenced this issue Jun 23, 2020
Store the entity types mapped to views in the snapshot

Fixes #2725
@AndriySvyryd AndriySvyryd removed their assignment Jun 23, 2020
@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jun 23, 2020
AndriySvyryd added a commit that referenced this issue Jun 24, 2020
Store the entity types mapped to views in the snapshot

Fixes #2725
AndriySvyryd added a commit that referenced this issue Jun 24, 2020
Store the entity types mapped to views in the snapshot

Fixes #2725
Fixes #21165
@ajcvickers ajcvickers modified the milestones: 5.0.0, 5.0.0-preview8 Jul 14, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-preview8, 5.0.0-rc1 Aug 23, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-rc1, 5.0.0 Nov 7, 2020
@aloksharma1
Copy link

did this ever got added in new versions, +1000000 btw :)

@AndriySvyryd
Copy link
Member

@VeMike
Copy link

VeMike commented Jan 13, 2023

So how would I ignore just a base class, but not a derived class using this approach?

Consider the following model:

[Table(nameof(Human))]
public class Human
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int HumanId { get; set; }
    
    public int Age { get; set; }
}

[Table(nameof(Developer))]
public class Developer : Human
{
    public string MainLanguage { get; set; }
}

The database context for this model is the following

public class FooContext : DbContext
{
    public DbSet<Developer> Developers { get; set; } = null!;

    /// <inheritdoc />
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // This is made to get TPT
        modelBuilder.Entity<Human>().ToTable(nameof(Human));
        modelBuilder.Entity<Developer>().ToTable(nameof(Developer));
        
        modelBuilder.Entity<Human>().ToTable(nameof(Human), t => t.ExcludeFromMigrations());
    }

    /// <inheritdoc />
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        optionsBuilder.UseSqlServer("<FooBarConnectionString>");
    }
}

As you can see I only want Developer to be in the migration. Human should be excluded. Why would I want to do this? I am extending an existing model and the base (Human) already exists in the database. I want to add Developer to this existing model.

But if I create a migration the whole hierarchy of Human is excluded (basically all classes of type Human). But I want the Developer to be created.

Of course, I could just remove the line

modelBuilder.Entity<Human>().ToTable(nameof(Human), t => t.ExcludeFromMigrations());

and then manually remove the added Human from the migration. But is there a way to do this automatically?

@ajcvickers
Copy link
Member

@VeMike Moved here: #30079

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-migrations area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. punted-for-3.0 type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.