国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一個Entity Framework Core的性能優(yōu)化案例

這篇具有很好參考價值的文章主要介紹了一個Entity Framework Core的性能優(yōu)化案例。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概要

本文提供一個EF Core的優(yōu)化案例,主要介紹一些EF Core常用的優(yōu)化方法,以及在優(yōu)化過程中,出現(xiàn)性能反復(fù)的時候的解決方法,并澄清一些對優(yōu)化概念的誤解,例如AsNoTracking并不包治百病。

本文使用的是Dotnet 6.0和EF Core 7.0。

代碼及實現(xiàn)

背景介紹

本文主要使用一個圖書和作者的案例,用于介紹優(yōu)化過程。

  • 一個作者Author有多本自己寫的的圖書Book
  • 一本圖書Book有一個發(fā)行商Publisher
  • 一個作者Author是一個系統(tǒng)用戶User
  • 一個系統(tǒng)用戶User有多個角色Role

本實例中Author表和Book數(shù)據(jù)量較大,記錄數(shù)量全部過萬條,其它數(shù)據(jù)表記錄大概都是幾十或幾百條。具體實體類定義請見附錄。

查詢需求

我們需要查找寫書最多的前兩名作家,該作家需要年齡在20歲以上,國籍是法國。需要他們的FirstName, LastName, Email,UserName以及在1900年以前他們發(fā)行的圖書信息,包括書名Name和發(fā)行日期Published。

基本優(yōu)化思路

本人做EF Core的復(fù)雜查詢優(yōu)化,并不推薦直接查看生成的SQL代碼,我習(xí)慣按照如下方式進行:

首先,進行EF的LINQ代碼檢查(初篩),找到明顯的錯誤。

  1. 查看代碼中是否有基本錯誤,主要針對全表載入的問題。例如EF需要每一步的LINQ擴展方法的返回值都是IQueryable類型,不能有IEnumerable類型;
  2. 查看是否有不需要的欄位;
  3. 根據(jù)情況決定是否加AsNoTracking,注意這個東西有時候加了也沒用;

其次,找到數(shù)據(jù)量較大的表,進行代碼整理和針對大數(shù)據(jù)表的優(yōu)化(精細化調(diào)整)

  1. 在操作大數(shù)據(jù)表時候,先要進行基本的過濾;
  2. 投影操作Select應(yīng)該放到排序操作后面;
  3. 減少返回值數(shù)量,推薦進行分頁操作;

本人推薦一旦出現(xiàn)性能反復(fù)的時候或者代碼整體基本完成的時候,再去查看生成的SQL代碼。

初始查詢代碼

public  List<AuthorWeb> GetAuthors() {
     using var dbContext = new AppDbContext();
     var authors = dbContext.Authors
                 .Include(x => x.User)
                  .ThenInclude(x => x.UserRoles)
                  .ThenInclude(x => x.Role)
                  .Include(x => x.Books)
                  .ThenInclude(x => x.Publisher)
                  .ToList()
                  .Select(x => new AuthorWeb
                  {
                      UserCreated = x.User.Created,
                      UserEmailConfirmed = x.User.EmailConfirmed,
                      UserFirstName = x.User.FirstName,
                      UserLastActivity = x.User.LastActivity,
                      UserLastName = x.User.LastName,
                      UserEmail = x.User.Email,
                      UserName = x.User.UserName,
                      UserId = x.User.Id,
                      RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                      BooksCount = x.BooksCount,
                      AllBooks = x.Books.Select(y => new BookWeb
                      {
                          Id = y.Id,
                          Name = y.Name,
                          Published = y.Published,
                          ISBN = y.ISBN,
                          PublisherName = y.Publisher.Name
                      }).ToList(),
                      AuthorAge = x.Age,
                      AuthorCountry = x.Country,
                      AuthorNickName = x.NickName,
                      Id = x.Id
                  })
                  .ToList()
                  .Where(x => x.AuthorCountry == "France" && x.AuthorAge == 20)
                  .ToList();

     var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in orderedAuthors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }

Benchmark測試后,系統(tǒng)資源使用情況如下:

一個Entity Framework Core的性能優(yōu)化案例,.Net,EntityFramework,T-SQL,性能優(yōu)化,solr,lucene

代碼性能非常差,內(nèi)存消耗很大,一次執(zhí)行就要消耗190MB,執(zhí)行時間超過2s。如果是放到WebAPI里面調(diào)用,用戶會有明顯的卡頓感覺;如果面臨高并發(fā)的情況,很可得會造成服務(wù)器資源緊張,返回各種500錯誤。

優(yōu)化代碼

初篩

按照我們的優(yōu)化思路,在查看上面的代碼后,發(fā)現(xiàn)一個嚴(yán)重的問題。

雖然每次LINQ查詢返回都是IQueryable類型,但是源碼中有多個ToList(),尤其是第一個,它的意思是將Author, Book,User,Role,Publisher等多個數(shù)據(jù)表的數(shù)據(jù)全部載入,前面已經(jīng)說了,Author, Book兩張表的數(shù)據(jù)量很大,必然影響性能。

我們需要刪除前面多余的ToList(),只保留最后的即可。請參考附錄中的方法GetAuthors_RemoveToList()。

在GetAuthors_RemoveToList()基礎(chǔ)上,對照用戶的需求,發(fā)現(xiàn)查詢結(jié)果中包含了Role相關(guān)的信息和很多Id信息,但是查詢結(jié)果并不需要這些,因此必須刪掉。請參考附錄中的方法GetAuthorsOptimized_RemoveColumn()

在GetAuthorsOptimized_RemoveColumn的基礎(chǔ)上,我們再加入AsNoTracking方法。請參考附錄中的方法GetAuthorsOptimized_AsNoTracking()

我們在Benchmark中,測試上面提到的三個方法,直接結(jié)果如下:

一個Entity Framework Core的性能優(yōu)化案例,.Net,EntityFramework,T-SQL,性能優(yōu)化,solr,lucene

從Benchmark的測試結(jié)果上看,刪除多余ToList方法和刪除多余的欄位,確實帶來了性能的大幅提升。

但是增加AsNoTracking,性能提反而下降了一點。這也說明了AsNoTracking并不是適用所有場景。Select投影操作生成的AuthorWeb對像,并不是EF管理的,與DbContext無關(guān),它只是作為前端API的返回值。相當(dāng)于EF做了沒有用的事,所以性能略有下降。

代碼進一步調(diào)整

初篩階段完成后,下面對代碼進一步整理

下面Take和Order操作可以并入基本的查詢中,Take可以幫助我們減少返回值的數(shù)量。請見 GetAuthorsOptimized_ChangeOrder()方法。

var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();

在GetAuthorsOptimized_ChangeOrder基礎(chǔ)上,對于dbContext.Authors,Author是一張數(shù)據(jù)量很大的表,我們需要在其進行聯(lián)表操作前,先過濾掉不需要的內(nèi)容,所以我們可以把Where前提,還有就是將排序操作放到投影的Select前面完成。請見 GetAuthorsOptimized_ChangeOrder方法。

上面的兩個優(yōu)化方法的執(zhí)行結(jié)果如下:

一個Entity Framework Core的性能優(yōu)化案例,.Net,EntityFramework,T-SQL,性能優(yōu)化,solr,lucene
可以看到性略能有提升。

下面我們?yōu)榱诉M一步提升性能,可以查看一下生成的SQL代碼,看看是否還有優(yōu)化的空間。

GetAuthorsOptimized_ChangeOrder方法生成的SQL如下:

      SELECT [u].[FirstName], [u].[LastName], [u].[Email], [u].[UserName], [t].[
BooksCount], [t].[Id], [u].[Id], [b].[Name], [b].[Published], [b].[Id], [t].[Age
], [t].[Country]
      FROM (
          SELECT TOP(@__p_0) [a].[Id], [a].[Age], [a].[BooksCount], [a].[Country
], [a].[UserId]
          FROM [Authors] AS [a]
          WHERE [a].[Country] = N'France' AND [a].[Age] >= 20
          ORDER BY [a].[BooksCount] DESC
      ) AS [t]
      INNER JOIN [Users] AS [u] ON [t].[UserId] = [u].[Id]
      LEFT JOIN [Books] AS [b] ON [t].[Id] = [b].[AuthorId]
      ORDER BY [t].[BooksCount] DESC, [t].[Id], [u].[Id]

從生成SQL來看,Author表在使用之前過濾掉了相關(guān)的內(nèi)容,但是直接Left Join了[Books]這個大表。我們可以按照前面提到的1900年以前的查詢要求,在左聯(lián)之前先過濾一下,請參考 GetAuthorsOptimized_SelectFilter方法。

該方法執(zhí)行后,生成的SQL如下:

      SELECT [u].[FirstName], [u].[LastName], [u].[Email], [u].[UserName], [t].[
BooksCount], [t].[Id], [u].[Id], [t0].[Name], [t0].[Published], [t0].[Id], [t].[
Age], [t].[Country]
      FROM (
          SELECT TOP(@__p_1) [a].[Id], [a].[Age], [a].[BooksCount], [a].[Country
], [a].[UserId]
          FROM [Authors] AS [a]
          WHERE [a].[Country] = N'France' AND [a].[Age] >= 20
          ORDER BY [a].[BooksCount] DESC
      ) AS [t]
      INNER JOIN [Users] AS [u] ON [t].[UserId] = [u].[Id]
      LEFT JOIN (
          SELECT [b].[Name], [b].[Published], [b].[Id], [b].[AuthorId]
          FROM [Books] AS [b]
          WHERE [b].[Published] < @__date_0
      ) AS [t0] ON [t].[Id] = [t0].[AuthorId]
      ORDER BY [t].[BooksCount] DESC, [t].[Id], [u].[Id]

在左聯(lián)之前,確實進行了過濾,該方法的性能測試如下:

一個Entity Framework Core的性能優(yōu)化案例,.Net,EntityFramework,T-SQL,性能優(yōu)化,solr,lucene
在避免Book表直接進行左聯(lián)后,性能有所提升。

最后一個優(yōu)化點,是在EF Core 5.0里面提供了帶Filter功能的Include方法,也可以用于本案例的優(yōu)化,但是該特性但是存在一些局限性,具體請參考EF Core中帶過濾器參數(shù)的Include方法

但是此方法又涉及了將IQueryable轉(zhuǎn)換成IEnumerable的操作,最后要將生成的Author對象全部轉(zhuǎn)換成AuthorWeb對象。代碼過于繁瑣,而且?guī)淼男阅芴嵘膊幻黠@。因此放棄這個點。

dbContext.Authors
   .AsNoTracking()
   .Include(x => x.Books.Where(b => b.Published < date))
   ......

結(jié)論

從這個優(yōu)化過程來看,其實對性能提升最大的貢獻就是刪除多余的ToList(),避免全表載入和刪除不需要的欄位兩項。其它所謂更精細的優(yōu)化,性能提升有限。文章來源地址http://www.zghlxwxcb.cn/news/detail-714797.html

附錄

實體類定義

 public class Author
    {
        public int Id { get; set; }
        public int Age { get; set; }
        public string Country { get; set; }
        public int BooksCount { get; set; }
        public string NickName { get; set; }

        [ForeignKey("UserId")]
        public User User { get; set; }
        public int UserId { get; set; }
        public virtual List<Book> Books { get; set; } = new List<Book>();
    }
 public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [ForeignKey("AuthorId")]
        public Author Author { get; set; }
        public int AuthorId { get; set; }
        public DateTime Published { get; set; }
        public string ISBN { get; set; }
        [ForeignKey("PublisherId")]
        public Publisher Publisher { get; set; }
        public int PublisherId { get; set; }
    }
public class Publisher
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime Established { get; set; }
    }
     public class User
    {
        public int Id { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string UserName { get; set; }
        public string Email { get; set; }
        public virtual List<UserRole> UserRoles { get; set; } = new List<UserRole>();
        public DateTime Created { get; set; }
        public bool EmailConfirmed { get; set; }
        public DateTime LastActivity { get; set; }
    }
    public class Role
    {
        public int Id { get; set; }
        public virtual List<UserRole> UserRoles { get; set; } = new List<UserRole>();
        public string Name { get; set; }
    }

public  class AuthorWeb
 {
     public DateTime UserCreated { get; set; }
     public bool UserEmailConfirmed { get; set; }
     public string UserFirstName { get; set; }
     public DateTime UserLastActivity { get; set; }
     public string UserLastName { get; set; }
     public string UserEmail { get; set; }
     public string UserName { get; set; }
     public int UserId { get; set; }
     public int AuthorId { get; set; }
     public int Id { get; set; }
     public int RoleId { get; set; }
     public int BooksCount { get; set; }
     public List<BookWeb> AllBooks { get; set; }
     public int AuthorAge { get; set; }
     public string AuthorCountry { get; set; }
     public string AuthorNickName { get; set; }
 }
 public class BookWeb
 {
         public int Id { get; set; }
         public string Name { get; set; }
         public DateTime Published { get; set; }
         public int PublishedYear { get; set; }
         public string PublisherName { get; set; }
         public string ISBN { get; set; }
     
 }

優(yōu)化方法

[Benchmark]
public  List<AuthorWeb> GetAuthors() {
     using var dbContext = new AppDbContext();

     var authors = dbContext.Authors
                                 .Include(x => x.User)
                                 .ThenInclude(x => x.UserRoles)
                                 .ThenInclude(x => x.Role)
                                 .Include(x => x.Books)
                                 .ThenInclude(x => x.Publisher)
                                 .ToList()
                                 .Select(x => new AuthorWeb
                                 {
                                     UserCreated = x.User.Created,
                                     UserEmailConfirmed = x.User.EmailConfirmed,
                                     UserFirstName = x.User.FirstName,
                                     UserLastActivity = x.User.LastActivity,
                                     UserLastName = x.User.LastName,
                                     UserEmail = x.User.Email,
                                     UserName = x.User.UserName,
                                     UserId = x.User.Id,
                                     RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                                     BooksCount = x.BooksCount,
                                     AllBooks = x.Books.Select(y => new BookWeb
                                     {
                                         Id = y.Id,
                                         Name = y.Name,
                                         Published = y.Published,
                                         ISBN = y.ISBN,
                                         PublisherName = y.Publisher.Name
                                     }).ToList(),
                                     AuthorAge = x.Age,
                                     AuthorCountry = x.Country,
                                     AuthorNickName = x.NickName,
                                     Id = x.Id
                                 })
                                 .ToList()
                                 .Where(x => x.AuthorCountry == "France" && x.AuthorAge >= 20)
                                 .ToList();

     var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in orderedAuthors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }

 [Benchmark]
 public List<AuthorWeb> GetAuthors_RemoveToList()
 {
     using var dbContext = new AppDbContext();

     var authors = dbContext.Authors
                                 .Include(x => x.User)
                                 .ThenInclude(x => x.UserRoles)
                                 .ThenInclude(x => x.Role)
                                 .Include(x => x.Books)
                                 .ThenInclude(x => x.Publisher)
                               //  .ToList()
                                 .Select(x => new AuthorWeb
                                 {
                                     UserCreated = x.User.Created,
                                     UserEmailConfirmed = x.User.EmailConfirmed,
                                     UserFirstName = x.User.FirstName,
                                     UserLastActivity = x.User.LastActivity,
                                     UserLastName = x.User.LastName,
                                     UserEmail = x.User.Email,
                                     UserName = x.User.UserName,
                                     UserId = x.User.Id,
                                     RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                                     BooksCount = x.BooksCount,
                                     AllBooks = x.Books.Select(y => new BookWeb
                                     {
                                         Id = y.Id,
                                         Name = y.Name,
                                         Published = y.Published,
                                         ISBN = y.ISBN,
                                         PublisherName = y.Publisher.Name
                                     }).ToList(),
                                     AuthorAge = x.Age,
                                     AuthorCountry = x.Country,
                                     AuthorNickName = x.NickName,
                                     Id = x.Id
                                 })
                                // .ToList()
                                 .Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20)
                                 .ToList();

     var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in orderedAuthors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }
 [Benchmark]
 public  List<AuthorWeb> GetAuthorsOptimized_RemoveColumn()
 {
     using var dbContext = new AppDbContext();

     var authors = dbContext.Authors
                              //   .Include(x => x.User)
                                 //.ThenInclude(x => x.UserRoles)
                              //   .ThenInclude(x => x.Role)
                              //   .Include(x => x.Books)
                            //     .ThenInclude(x => x.Publisher)
                                 .Select(x => new AuthorWeb
                                 {
                                  //   UserCreated = x.User.Created,
                                   //  UserEmailConfirmed = x.User.EmailConfirmed,
                                     UserFirstName = x.User.FirstName,
                                  //   UserLastActivity = x.User.LastActivity,
                                     UserLastName = x.User.LastName,
                                     UserEmail = x.User.Email,
                                     UserName = x.User.UserName,
                                //     UserId = x.User.Id,
                                //     RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                                     BooksCount = x.BooksCount,
                                     AllBooks = x.Books.Select(y => new BookWeb
                                     {
                                     //    Id = y.Id,
                                         Name = y.Name,
                                         Published = y.Published,
                                  //       ISBN = y.ISBN,
                                //         PublisherName = y.Publisher.Name
                                     }).ToList(),
                                     AuthorAge = x.Age,
                                     AuthorCountry = x.Country,
                                     AuthorNickName = x.NickName,
                                  //   Id = x.Id
                                 })
                                 .Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20)
                                 .ToList();

     var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in orderedAuthors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }

[Benchmark]
 public List<AuthorWeb> GetAuthorsOptimized_AsNoTracking()
 {
     using var dbContext = new AppDbContext();

     var authors = dbContext.Authors
                                 .AsNoTracking()
                                 // .Include(x => x.User)
                                 //   .ThenInclude(x => x.UserRoles)
                                 //   .ThenInclude(x => x.Role)
                                 //    .Include(x => x.Books)
                                 //   .ThenInclude(x => x.Publisher)
                                 .Select(x => new AuthorWeb
                                 {
                                     //UserCreated = x.User.Created,
                                     //    UserEmailConfirmed = x.User.EmailConfirmed,
                                     UserFirstName = x.User.FirstName,
                                     // UserLastActivity = x.User.LastActivity,
                                     UserLastName = x.User.LastName,
                                     UserEmail = x.User.Email,
                                     UserName = x.User.UserName,
                                     //  UserId = x.User.Id,
                                     //RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                                     BooksCount = x.BooksCount,
                                     AllBooks = x.Books.Select(y => new BookWeb
                                     {
                                         // Id = y.Id,
                                         Name = y.Name,
                                         Published = y.Published,
                                         //ISBN = y.ISBN,
                                         //PublisherName = y.Publisher.Name
                                     }).ToList(),
                                     AuthorAge = x.Age,
                                     AuthorCountry = x.Country,
                                     //AuthorNickName = x.NickName,
                                     Id = x.Id
                                 })
                                 .Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20)
                                 .ToList();

      var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in authors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }


 [Benchmark]
 public List<AuthorWeb> GetAuthorsOptimized_Take_Order()
 {
     using var dbContext = new AppDbContext();

     var authors = dbContext.Authors
                                 .AsNoTracking()
                                 .Select(x => new AuthorWeb
                                 {
                                     UserFirstName = x.User.FirstName,
                                     UserLastName = x.User.LastName,
                                     UserEmail = x.User.Email,
                                     UserName = x.User.UserName,
                                     BooksCount = x.BooksCount,
                                     AllBooks = x.Books.Select(y => new BookWeb
                                     {
                                         Name = y.Name,
                                         Published = y.Published,
                                     }).ToList(),
                                     AuthorAge = x.Age,
                                     AuthorCountry = x.Country,
                                     AuthorNickName = x.NickName,
                                 })
                                 .Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20)
                                 .OrderByDescending(x => x.BooksCount)
                                 .Take(2)
                                 .ToList();

    // var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in authors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }


 [Benchmark]
 public List<AuthorWeb> GetAuthorsOptimized_ChangeOrder()
 {
     using var dbContext = new AppDbContext();

     var authors = dbContext.Authors
                                  .AsNoTracking()
                                  .Where(x => x.Country == "France" && x.Age >=20)
                                  .OrderByDescending(x => x.BooksCount)
                                 // .Include(x => x.User)
                                 //   .ThenInclude(x => x.UserRoles)
                                 //   .ThenInclude(x => x.Role)
                                 //    .Include(x => x.Books)
                                 //   .ThenInclude(x => x.Publisher)
                                 .Select(x => new AuthorWeb
                                 {
                                     //UserCreated = x.User.Created,
                                     //    UserEmailConfirmed = x.User.EmailConfirmed,
                                     UserFirstName = x.User.FirstName,
                                     // UserLastActivity = x.User.LastActivity,
                                     UserLastName = x.User.LastName,
                                     UserEmail = x.User.Email,
                                     UserName = x.User.UserName,
                                     //  UserId = x.User.Id,
                                     //RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                                     BooksCount = x.BooksCount,
                                     AllBooks = x.Books.Select(y => new BookWeb
                                     {
                                         // Id = y.Id,
                                         Name = y.Name,
                                         Published = y.Published,
                                         //ISBN = y.ISBN,
                                         //PublisherName = y.Publisher.Name
                                     }).ToList(),
                                     AuthorAge = x.Age,
                                     AuthorCountry = x.Country,
                                     //AuthorNickName = x.NickName,
                                     Id = x.Id
                                 })                                     
                                 .Take(2)
                                 .ToList();

     // var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();

     List<AuthorWeb> finalAuthors = new List<AuthorWeb>();
     foreach (var author in authors)
     {
         List<BookWeb> books = new List<BookWeb>();

         var allBooks = author.AllBooks;

         foreach (var book in allBooks)
         {
             if (book.Published.Year < 1900)
             {
                 book.PublishedYear = book.Published.Year;
                 books.Add(book);
             }
         }

         author.AllBooks = books;
         finalAuthors.Add(author);
     }

     return finalAuthors;
 }

//  [Benchmark]
 public List<AuthorWeb> GetAuthorsOptimized_IncludeFilter()
 {
     using var dbContext = new AppDbContext();
     var date = new DateTime(1900, 1, 1);
     var authors = dbContext.Authors
                                 .AsNoTracking()
                                 .Include(x => x.Books.Where(b => b.Published < date))
                                 .Include(x => x.User)
                                  // .IncludeFilter(x =>x.Books.Where(b =>b.Published.Year < 1900))
                                  .Where(x => x.Country == "France" && x.Age >=20)
                                  .OrderByDescending(x => x.BooksCount)
                              
                                 //   .ThenInclude(x => x.UserRoles)
                                 //   .ThenInclude(x => x.Role)
                                 //    .Include(x => x.Books)
                                 //   .ThenInclude(x => x.Publisher)
                                 .Take(2)
                                 .ToList();

     // var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();

     var authorList = authors.AsEnumerable().Select(x => new AuthorWeb
     {
         //UserCreated = x.User.Created,
         //    UserEmailConfirmed = x.User.EmailConfirmed,
         UserFirstName = x.User.FirstName,
         // UserLastActivity = x.User.LastActivity,
         UserLastName = x.User.LastName,
         UserEmail = x.User.Email,
         UserName = x.User.UserName,
         //  UserId = x.User.Id,
         //RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
         BooksCount = x.BooksCount,
         AllBooks = x.Books
                                        //    .Where(b => b.Published < date)
                                        .Select(y => new BookWeb
                                        {
                                            // Id = y.Id,
                                            Name = y.Name,
                                            Published = y.Published,
                                            //ISBN = y.ISBN,
                                            //PublisherName = y.Publisher.Name
                                        }).ToList(),
         AuthorAge = x.Age,
         AuthorCountry = x.Country,
         //AuthorNickName = x.NickName,
         //    Id = x.Id
     }).ToList();

     return authorList;
 }


 [Benchmark]
 public List<AuthorWeb> GetAuthorsOptimized_SelectFilter()
 {
     using var dbContext = new AppDbContext();
     var date = new DateTime(1900, 1, 1);
     var authors = dbContext.Authors
                                 .AsNoTracking()
                                 .Include(x => x.Books.Where(b => b.Published < date))
                                 .Where(x => x.Country == "France" && x.Age >=20)
                                 .OrderByDescending(x => x.BooksCount)
                                 .Select(x => new AuthorWeb
                                  {
                                      //UserCreated = x.User.Created,
                                      //    UserEmailConfirmed = x.User.EmailConfirmed,
                                      UserFirstName = x.User.FirstName,
                                      // UserLastActivity = x.User.LastActivity,
                                      UserLastName = x.User.LastName,
                                      UserEmail = x.User.Email,
                                      UserName = x.User.UserName,
                                      //  UserId = x.User.Id,
                                      //RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,
                                      BooksCount = x.BooksCount,
                                      AllBooks = x.Books
                                         .Where(b => b.Published < date)
                                        .Select(y => new BookWeb
                                        {
                                            // Id = y.Id,
                                            Name = y.Name,
                                            Published = y.Published,
                                            //ISBN = y.ISBN,
                                            //PublisherName = y.Publisher.Name
                                        }).ToList(),
                                      AuthorAge = x.Age,
                                      AuthorCountry = x.Country,
                                      //AuthorNickName = x.NickName,
                                      //    Id = x.Id
                                  })
                                 .Take(2)
                                 .ToList();
     return authors;
 }

到了這里,關(guān)于一個Entity Framework Core的性能優(yōu)化案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • ASP.Net Core Web API結(jié)合Entity Framework Core框架(API的創(chuàng)建使用,接口前端權(quán)限設(shè)置,前端獲取API的Get,post方法)(程序包引用以及導(dǎo)入數(shù)據(jù)庫)

    ASP.Net Core Web API結(jié)合Entity Framework Core框架(API的創(chuàng)建使用,接口前端權(quán)限設(shè)置,前端獲取API的Get,post方法)(程序包引用以及導(dǎo)入數(shù)據(jù)庫)

    目錄 1. Web Api 程序包引用 2. Web Api 的創(chuàng)建與Http類型的介紹 2.1?ASP.Net Core Web API項目的創(chuàng)建 2?.2? API接口的創(chuàng)建 2.3?HttpGet和HttpPost類型的區(qū)別 3.接口權(quán)限設(shè)置 4.HttpGet方法和HttpPOst方法 5.前端中用HttpGet/Poset獲取接口數(shù)據(jù) 6.EF框架——配置數(shù)據(jù)庫鏈接字符串(即將數(shù)據(jù)庫中的表導(dǎo)入項

    2024年02月08日
    瀏覽(31)
  • Entity Framework Core 大小寫敏感處理

    可以使用\\\'StringComparison\\\'嗎? 在數(shù)據(jù)庫查詢操作中,不可避免去考慮字母大小寫的問題,比如要在Movie表中查找“X-Men”這部電影,為了不區(qū)分字母大小寫,按照Linq to memory的習(xí)慣,可能會寫出如下代碼: 但是上述代碼執(zhí)行會報錯,提示?\\\'StringComparison\\\'參數(shù)不支持。 怎么解決這

    2023年04月13日
    瀏覽(26)
  • .NET Core性能優(yōu)化技巧

    .NET Core作為一個跨平臺的開源框架,以其高效、靈活和可擴展的特性受到了廣大開發(fā)者的青睞。但在實際開發(fā)中,如何確保應(yīng)用程序的性能始終是一個關(guān)鍵的問題。本文將介紹十大.NET Core性能優(yōu)化技巧,幫助開發(fā)者提升應(yīng)用程序的性能。 1. 使用異步編程 .NET Core支持異步編程

    2024年02月19日
    瀏覽(19)
  • 楊中科 .NETCORE ENTITY FRAMEWORK CORE-1 EFCORE 第一部分

    楊中科 .NETCORE ENTITY FRAMEWORK CORE-1 EFCORE 第一部分

    1、說明: 本課程需要你有數(shù)據(jù)庫、SOL等基礎(chǔ)知識。 2、ORM: ObjectRelational Mapping。讓開發(fā)者用對象操作的形式操作關(guān)系數(shù)據(jù)庫 比如插入: 比如查詢: 3、有哪些ORM: EF core(官方推薦)、Dapper、SqlSugar、FreeSql等 1、Entity Framework Core(EF Coxe)是微軟官方的ORM框架優(yōu)點: 功能強大、官方支持、生

    2024年02月02日
    瀏覽(21)
  • 【ASP.NET Core 基礎(chǔ)知識】--部署和維護--性能優(yōu)化技巧

    一、應(yīng)用程序設(shè)計和架構(gòu)優(yōu)化 1.1 選擇適當(dāng)?shù)脑O(shè)計模式 應(yīng)用程序設(shè)計和架構(gòu)優(yōu)化是提高 ASP.NET Core 應(yīng)用程序性能的重要方面之一。適當(dāng)?shù)脑O(shè)計模式是優(yōu)化架構(gòu)的關(guān)鍵之一。設(shè)計模式是解決特定問題的經(jīng)驗總結(jié),能夠提高代碼的可讀性、可維護性和可擴展性,從而間接地提高了

    2024年02月20日
    瀏覽(102)
  • ASP.NET中使用Entity Framework(EF)關(guān)聯(lián)表查詢

    在ASP.NET中使用Entity Framework(EF)進行關(guān)聯(lián)表查詢的具體步驟如下: 配置數(shù)據(jù)庫上下文(DbContext):在 DbContext 派生類中,使用 DbSetT 屬性表示每個實體對應(yīng)的數(shù)據(jù)庫表。確保每個實體類和關(guān)系都正確映射到數(shù)據(jù)庫表。 定義關(guān)聯(lián)表之間的導(dǎo)航屬性:在實體類中,使用導(dǎo)航屬性表

    2024年02月14日
    瀏覽(20)
  • 微軟.NET、.NET Framework和.NET Core聯(lián)系和區(qū)別

    微軟.NET、.NET Framework和.NET Core聯(lián)系和區(qū)別

    我是荔園微風(fēng),作為一名在IT界整整25年的老兵,看到不少初學(xué)者在學(xué)習(xí)編程語言的過程中如此的痛苦,我決定做點什么,我小時候喜歡看小人書(連環(huán)畫),在那個沒有電視、沒有手機的年代,這是為數(shù)不多的課余生活方式這一。我畫的不好,但是如果能幫大家理解編程語言

    2024年01月16日
    瀏覽(103)
  • .net framework、.net standard、 .net core .net 5/6 區(qū)別

    .net framework、.net standard、 .net core .net 5/6 區(qū)別

    之前一直使用.net framework框架編寫程序,這幾年微軟的動作有點大,更新迭代的有些快,對出現(xiàn)的.net standard、 .net core 、.net 5/6框架一直搞不清是什么關(guān)系,今天整理下這幾個框架的關(guān)系。 物聯(lián)網(wǎng)時代到來,各種跨平臺的需求原來越強烈,.net framework框架只能在windows上運行,

    2024年02月08日
    瀏覽(92)
  • 什么是.NET?什么是.NET Core?以及什么是.NET Framework,.NET和.NET Core區(qū)別又是什么呢?

    什么是.NET?什么是.NET Core?以及什么是.NET Framework,.NET和.NET Core區(qū)別又是什么呢?

    概述 對于.NET平臺的初學(xué)者來說,有時候比較困惑“什么是.NET?什么是.NET Core?.NET和.NET Core區(qū)別又是什么呢?”。確實,目前微軟的開發(fā)平臺有兩種不同的.NET運行時環(huán)境,一種是.NET Framework,另一種則是.NET Core(.NET 5),不同的目標(biāo)框架運行時環(huán)境不同。 那這兩者的區(qū)別到底是

    2024年02月06日
    瀏覽(93)
  • SignalR實戰(zhàn):在.NET Framework和.NET Core中如何使用SignalR?

    SignalR實戰(zhàn):在.NET Framework和.NET Core中如何使用SignalR?

    官網(wǎng)文檔:https://learn.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0tabs=visual-studio SignalR開源代碼:https://github.com/signalr 很多小伙伴問:在前后端分離項目中,后端是.NET Core前端是Vue如何使用SignalR?在前后端不分離項目中,.NET Framework MVC項目中又如何使用SignalR技術(shù)呢?

    2024年02月12日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包