Search code examples
c#entity-frameworktable-per-hierarchy

EF - Extract all record of specific type table per hierarchy


In my EF context I have a hierarchy of classes, managed with the table per hierarchy approach.

Therefore I have a base abstract class and a bunch of classes that derive from it:

public abstract class BaseClass
{
    [Required]
    public int Id {get; set;}

    ...
}

public abstract class ExtendedClass1 : BaseClass
{

    ...

}

public abstract class ExtendedClass2 : BaseClass
{

    ...

}

The classes are configured as follows:

public class ExtendedClass1Configuration : 
    EntityTypeConfiguration<ExtendedClass1>
{
    ...

    this.Map(m => m.Requires("Discriminator").HasValue("ExtendedClass1"));
}

To access the database I use a repository that derives from a generic repository:

public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity: BaseClass
{
    protected DbContext context;

    DbSet<TEntity> GetSet()
    {
        return this.context.Set<TEntity>();
    }

    public virtual void Add(TEntity entity)
    {
        this.GetSet().Add(entity);
    }

    ...
}

public class BaseClassRepository : Repository<BaseClass>, IBaseClassRepository
{

    ...

}

I want to add a method to my repository that will extract all the classes of a specific subtype (for example all the records of type ExtendedClass1).

I have tried some approaches as follows, without success:

public IEnumerable<BaseClass> GetByType(Type type) {
    return context.Set<BaseClass>().OfType<type>();
}

This gives me the following compilation error:

The type or namespace name 'type' could not be found

Another approach I'm trying right now is something like this:

public IEnumerable<TBaseClass> GetByType() where TBaseClass : BaseClass {
    return context.Set<BaseClass>().OfType<TBaseClass>();
}

What am I doing wrong? How can I implement it?


Solution

  • public IEnumerable<BaseClass> GetByType(Type type) 
    {
        return context.Set<BaseClass>().OfType<type>();
    }
    

    Isn't correct, use

    public IEnumerable<BaseClass> GetByType<T>() 
    {
        return context.Set<BaseClass>().OfType<T>();
    }
    

    Typeparams ftw.