Using ModelBuilder Query method with inherited classes (EF core 2.1) entity-framework-core inheritance stored-procedures


I have some problem with using dbContext Query method on base class which provide some inheritance to one other class (just for inherit properties, not for model / db building)

In my repo services I call something like:

IEnumerable<CoasterExtended> coasters = await _db.Query<CoasterExtended>()
            .FromSql(GetCoastersProcedure, pageNumberParam, pageSizeParam, orderByParam, sortParam, breweryIdParam, searchParam, coasterTypeParam)

GetCoastersProcedure is a sql procedure which return all properties of CoasterExtended class. This class is not used to model / db build. It is just mirror of sql procedure result.

In my OnModelCreating method i just have:


Querying the result of sql procedure worked fine until I decided to use this class for inheritance:

public class CollectionItemExtended : CoasterExtended {
    // some additional properties

And the OnModelCreating method:


The query (of CoasterExtended type) now return error "The required column 'Discriminator' was not present in the results of a 'FromSql' operation". I know that discriminator is used for inherited types, but I use both classes to mirror the result of separate sql procedures (these results I simply map to desired app model classes)

So I dont want to select (and fake) discriminator ... I just want to map results of sql procedures to independent classes (which I have inherited just because I dont want to duplicate properties and mappers which are following). How can I achieve that the query result will ignore inheritance and just return the described types?

2/11/2019 7:58:32 PM

Accepted Answer

The problem is that both the base and derived classes are registered as query types, thus EF Core considers them implementing the TPH database inheritance strategy (similar to normal entity types).

If you want to just share common properties, use a base class which is not registered as entity or query type.

In your case, change the name of the CoasterExtended class to let say CoasterExtendedBase and let both CoasterExtended and CollectionItemExtended inherit from it:

public class CoasterExtended : CoasterExtendedBase { }

public class CollectionItemExtended : CoasterExtendedBase
    // some additional properties

Now you can register both CoasterExtended and CollectionItemExtended as query types and everything will work as expected.

2/11/2019 8:43:15 PM

Popular Answer

Query is actually superfluous here. This boils down to the logic of FromSQL. In other words, Query<Foo>.FromSQL is really just FromSQL<Foo>. In short, FromSQL can only work with entity types, i.e. types that are actually mapped to your database. This is why it's assuming relational inheritance with a Discriminator column. In other words, it's not meant for mapping to random C# object types.


While the above is true, it's not comprehensive. It's better said that DbSet<T>.FromSQL must be an entity type. EF Core 2.1 added support for "query sets", but you must define such a query set on your context in order to utilize it:

public DbQuery<CollectionItemExtended> CollectionItemExtendeds { get; set; }

Then, you can utilize FromSQL on that:


Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow