Select specific properties from include ones in entity framework core

后端 未结 2 1929
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-04 13:54

I use Entity Framework Core 2.0 and have this 2 classes:

News

public class News
{
    public int Id { get; s         


        
相关标签:
2条回答
  • 2021-01-04 14:30

    Instead of using an anonymous object, you can return from your infra layer a method IQueryable<News> GetAll() and just do an context.NewsTable.Include(x => x.Author). Obs: Note that you're just returning a query and not retrieving data from your DB at this point.

    Then you create a NewsDTO class with the properties you want to retrieve (example bellow).

    public class NewsDTO
    {
        public int Id { get; set; }
        public string Title{ get; set; }
        public string Text { get; set; }
        public DateTime ReleaseDate{ get; set; }
        public string AuthorName { get; set; }
    }
    

    I prefer to use AutoMapper, your code will be cleaner, List<NewsDTO> newsDtoList = _repository.GetAll().ProjectTo<NewsDTO>().ToList()

    But you can do using this odd kind

    List<NewsDTO> newsDtoList = _repository.GetAll()
    .Select(x => new NewsDTO
            {
                Id = x.Id.,
                Title = x.Title,
                Text = x.Text,
                ReleaseDate = x.ReleaseDate,
                AuthorName = x.Author.Username
            }).ToList();
    

    You finish your command using .ToList(), at this point you retrieve your data, just one select with the fields you defined in your mapping configuration or in your select.

    0 讨论(0)
  • 2021-01-04 14:52

    If I understand correctly, you don't want to load the Author entity (because there is no way to load entity with just some non navigation properties populated).

    Then the question is why did you specifically add Include(x => x.Author) which is requesting EF to load the Author. Include / ThenInclude methods support eager loading of the related data entities. They are not needed when you use projection (Select).

    Interestingly, all EF (Core) versions before EFC 2.0 were ignoring includes for projection type queries. Even the current EFC documentation states that the projection queries fall into Ignored Includes category. However, as you've noticed EFC 2.0 is not ignoring it! So it's either implementation bug and will be fixed, or the documentation bug and will be updated.

    For now, simply don't use Include in projection queries. If you execute this:

    var result = ctx.News.Select(news => new
    {
        news = news,
        Username = news.Author.Username
    }).ToList();
    

    the EFC generated SQL query now is as expected:

    SELECT [news].[Id], [news].[AuthorID], [news].[ReleaseDate], [news].[Text], [news].[Title], [news.Author].[Username]
    FROM [News] AS [news]
    INNER JOIN [Authors] AS [news.Author] ON [news].[AuthorID] = [news.Author].[Id] 
    
    0 讨论(0)
提交回复
热议问题