Rovdjuret
Rovdjuret

Reputation: 1528

EF7 Migrations - The corresponding CLR type for entity type '' is not instantiable

I'm trying to use EF7 migrations and got stuck when I modeled an Organization model with inheritance.

Organization is an abstract class. There are two concrete classes that inherit from it called Individual and Company.

I set the Organization abstract class as DbSet<Organization> in DbContext and run migrations.

I'm following this tutorial here.

The following error is shown:

The corresponding CLR type for entity type 'Organization' is not instantiable and there is no derived entity type in the model that corresponds to a concrete CLR type.

Whats should I do?

EDIT - Updated with code.

Organization:

public abstract class Organization
{
    public Organization()
    {
        ChildOrganizations = new HashSet<Organization>();
    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public bool Enabled { get; set; }
    public bool PaymentNode { get; set; }
    public DateTime Created { get; set; }
    public DateTime Updated { get; set; }

    // virtual
    public virtual ICollection<Organization> ChildOrganizations { get; set; }
}

Individual

public class Individual : Organization
{
    public string SocialSecurityNumber { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

Company

public class Company : Organization
{
    public string Name { get; set; }
    public string OrganizationNumber { get; set; }
}

DbContext

public class CoreDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Organization> Organization { get; set; }

    public CoreDbContext(DbContextOptions<CoreDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}

Thanks in advance!

Upvotes: 25

Views: 30517

Answers (5)

aardbol
aardbol

Reputation: 2295

You should also put in your CoreDbContext class the classes that inherit Organization. Then it will discriminate and instantiate those objects correctly. It should look like this:

public DbSet<Organization> Organization { get; set; }
public DbSet<Individual> Individual { get; set; }
public DbSet<Company> Company { get; set; }

Source: https://learn.microsoft.com/en-us/ef/core/modeling/inheritance

Upvotes: 1

Manzur Alahi
Manzur Alahi

Reputation: 2096

In case anyone makes a stupid mistake like me, My entity was abstract. So maybe check if you have mistakenly made the same issue.

Upvotes: 22

Joel McBeth
Joel McBeth

Reputation: 1318

Please see: https://learn.microsoft.com/en-us/ef/core/modeling/inheritance

If you don’t want to expose a DbSet for one or more entities in the hierarchy, you can use the Fluent API to ensure they are included in the model.

If you don't want to have to create a DbSet for each subclass then you have to explicitly define them in the OnModelCreating override of the DbContext:

public class CoreDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Organization> Organization { get; set; }

    public CoreDbContext(DbContextOptions<CoreDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Individual>();
        builder.Entity<Company>();

        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}

Upvotes: 41

Nick Cromwell
Nick Cromwell

Reputation: 254

Similar to the tutorial you linked, your DbSet<> properties should be the inheriting Individual and Companyclasses.

Try having your CoreDbContext look more like this:

public class CoreDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Company> Companies { get; set; }
    public DbSet<Individual> Individuals { get; set; }

    public CoreDbContext(DbContextOptions<CoreDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}

Upvotes: 3

Tom Droste
Tom Droste

Reputation: 1324

The problem could be that you use a class library project. In RC2 of EF Core you can't place your DBContext in such a project. This is a known issue. When you convert it to a 'app' project it should work again.

More info & source:

Workaround: https://docs.efproject.net/en/latest/cli/dotnet.html#dotnet-cli-issues

Github issue: https://github.com/aspnet/EntityFramework/issues/5460

Upvotes: 0

Related Questions