Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with SQL views in Entity Framework Core

For example, I have such model:

public class Blog {     public int BlogId { get; set; }     public string Url { get; set; }      public BlogImage BlogImage { get; set; } }  public class BlogImage {     public int BlogImageId { get; set; }     public byte[] Image { get; set; }     public string Caption { get; set; }      public int BlogId { get; set; }     public Blog Blog { get; set; } }  

I want to return in ImageView view Url and Image.

Where do I need to create and define that SQL view?

like image 516
Yurii N. Avatar asked Mar 15 '16 13:03

Yurii N.


People also ask

Can Entity Framework work with views?

Views can be used in a similar way as you can use tables. To use view as an entity, first you will need to add database views to EDM. After adding views to your model then you can work with it the same way as normal entities except for Create, Update, and Delete operations.

Does EF core support views?

With EF Core 5, we can introduce views in our DbContext and track the evolution of our views using the built-in database migration mechanism.

How do I view SQL Entity Framework?

To view the SQL that will be generated, simply call ToTraceString() . You can add it into your watch window and set a breakpoint to see what the query would be at any given point for any LINQ query. You can attach a tracer to your SQL server of choice, which will show you the final query in all its gory detail.


2 Answers

In Entity Framework Core 2.1 we can use Query Types as Yuriy N suggested.

A more detailed article on how to use them can be found here

The most straight forward approach according to the article's examples would be:

1.We have for example the following entity Models to manage publications

public class Magazine {   public int MagazineId { get; set; }   public string Name { get; set; }   public string Publisher { get; set; }   public List<Article> Articles { get; set; } }  public class Article {   public int ArticleId { get; set; }   public string Title { get; set; }   public int MagazineId { get; set; }   public DateTime PublishDate { get;  set; }   public Author Author { get; set; }   public int AuthorId { get; set; } } public class Author {   public int AuthorId { get; set; }   public string Name { get; set; }   public List<Article> Articles { get; set; } } 

2.We have a view called AuthorArticleCounts, defined to return the name and number of articles an author has written

SELECT   a.AuthorName,   Count(r.ArticleId) as ArticleCount from Authors a   JOIN Articles r on r.AuthorId = a.AuthorId GROUP BY a.AuthorName 

3.We go and create a model to be used for the View

public class AuthorArticleCount {   public string AuthorName { get; private set; }   public int ArticleCount { get; private set; } } 

4.We create after that a DbQuery property in my DbContext to consume the view results inside the Model

public DbQuery<AuthorArticleCount> AuthorArticleCounts{get;set;} 

4.1. You might need to override OnModelCreating() and set up the View especially if you have different view name than your Class.

protected override void OnModelCreating(ModelBuilder modelBuilder) {     modelBuilder.Query<AuthorArticleCount>().ToView("AuthorArticleCount"); } 

5.Finally we can easily get the results of the View like this.

var results=_context.AuthorArticleCounts.ToList(); 

UPDATE According to ssougnez's comment

It's worth noting that DbQuery won't be/is not supported anymore in EF Core 3.0. See here

like image 63
Anastasios Selmani Avatar answered Oct 16 '22 20:10

Anastasios Selmani


Views are not currently supported by Entity Framework Core. See https://github.com/aspnet/EntityFramework/issues/827.

That said, you can trick EF into using a view by mapping your entity to the view as if it were a table. This approach comes with limitations. e.g. you can't use migrations, you need to manually specific a key for EF to use, and some queries may not work correctly. To get around this last part, you can write SQL queries by hand

context.Images.FromSql("SELECT * FROM dbo.ImageView") 
like image 44
natemcmaster Avatar answered Oct 16 '22 22:10

natemcmaster