1

In the following classes I am trying to do a code first setup using abstract base classes. Sorry if this is a duplicate question. I did try to search the site and google for an answer but nothing I have tried has worked.

public abstract class IDObject
{
    [Key]
    public Int32 ID { get; internal set; }
}

public abstract class NamedObject : IDObject
{
    public String Name { get; set; }
}

public abstract class HWObject : NamedObject
{
    public Double Free { get; set; }
    public Double Max { get; set; }
    public Double Used { get; set; }
}

public abstract class CPUObject : HWObject { }
public abstract class MemoryObject : HWObject { }
public abstract class StorageObject : HWObject { }

public class Server : NamedObject
{
    [JsonConstructor]
    internal Server() { }
    public String CompanyName { get; set; }
    public Boolean IsRunning { get; set; }
    public CPUObject CPU { get; set; }
    public MemoryObject Memory { get; set; }
    public StorageObject Storage { get; set; }
}

I have the following DBContext:

public class DataContext : DbContext
{
    public DataContext() : base("name=DataContext") { }

    public DbSet<Server> Servers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    }
}

When I try to view the Read-Only Data Model I get the following error:

System.InvalidOperationException: The abstract type 'MyApp.CPUObject' has no mapped descendants and so cannot be mapped. Either remove 'MyApp.CPUObject' from the model or add one or more types deriving from 'MyApp.CPUObject' to the model.

How do I change the DBContext so the error goes away?

EDIT: According to the answer below I have removed abstract from the CPUObject, MemoryObject and StorageObject as they should have never been abstract.

I have changed the DBContext to the following: (The mappings create a 1 to 1 relationship)

public class DataContext : DbContext
{
    public DataContext() : base("name=DataContext") { }

    public DbSet<Server> Servers { get; set; }

    public DbSet<CPUObject> CPUObjects { get; set; }
    public DbSet<MemoryObject> MemoryObjects { get; set; }
    public DbSet<StorageObject> StorageObjects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Server>().HasRequired(u => u.CPU).WithRequiredDependent().Map(m => m.MapKey("CPUID"));
        modelBuilder.Entity<Server>().HasRequired(u => u.Memory).WithRequiredDependent().Map(m => m.MapKey("MemoryID"));
        modelBuilder.Entity<Server>().HasRequired(u => u.Storage).WithRequiredDependent().Map(m => m.MapKey("StorageID"));
    }
}
1
  • Add CPUObject to your context. Commented Jun 23, 2016 at 23:16

1 Answer 1

1

CPUObject is currently an abstract class, which cannot be instantiated. Just remove the abstract to make it a concrete object. Then, add public DbSet<CPUObject> CPUs { get; set; } to your DBContext

You are currently getting the error because EF is looking for a concrete class, so the error says you can make another concrete class that inherits (i.e. 'deriving from') CPUObject

Sign up to request clarification or add additional context in comments.

1 Comment

CPUObject, MemoryObject and StorageObject were never meant to be abstract. That was a mistake lol.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.