Although the name suggests otherwise you are not limited to using entity types (=objects with an id) in EF Core. EF Core 2.1 introduces support for query types, which can be used to query data that isnāt mapped to entity types.
This allows you to directly map your query results to DTOās, something especially useful on the query side when you are having a CQRS style architecture.
Letās try this!
First we have to create our DTO:
public class BlogDTO | |
{ | |
public string Name { get; set; } | |
public string Url { get; set; } | |
} |
Next step is to make EF Core aware of the existence of this query type. Weāll use the fluent configuration api but instead of calling the Entity<T>() method on the modelBuilder weāll use the Query<T>() method:
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
modelBuilder | |
.Query<BlogDTO>(); | |
} |
Next, we configure the DbContext
to include the DbQuery<T>
:
public class SampleContext: DbContext | |
{ | |
public SampleContext(DbContextOptions<SampleContext> options) | |
: base(options) | |
{ } | |
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
modelBuilder | |
.Query<BlogDTO>(); | |
//Removed other code | |
} | |
public DbSet<Blog> Blogs { get; set; } | |
public DbQuery<BlogDTO> BlogDTOs { get; set; } | |
} | |
You can then define queries directly in OnModelBuilding using a LINQ query through ToQuery():
public class SampleContext: DbContext | |
{ | |
public SampleContext(DbContextOptions<SampleContext> options) | |
: base(options) | |
{ } | |
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
modelBuilder | |
.Query<BlogDTO>().ToQuery(Blogs.Select(b => new BlogDTO { Name, Url }); | |
//Removed other code | |
} | |
public DbSet<Blog> Blogs { get; set; } | |
} |
Of course you can also map a query type to a view using ToView():
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
modelBuilder | |
.Query<BlogDTO>().ToView("vwBlogs"); | |
} |
A last option is to directly map it to a raw SQL query using the FromSql method on your DbContext:
var blogs = db.BlogDTOs.FromSql(@"select b.Name, b.Url from Blogs b"); |
Remark: The query type must be registered with the DbContext
as a DbQuery
and all columns in the SQL need to match all of the properties in the query type.
More information: https://docs.microsoft.com/en-us/ef/core/modeling/query-types