<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET 云原生架構(gòu)師訓(xùn)練營(yíng)(模塊二 基礎(chǔ)鞏固 EF Core 查詢)--學(xué)習(xí)筆記

          共 8293字,需瀏覽 17分鐘

           ·

          2021-01-06 12:29

          2.4.5 EF Core -- 查詢

          • 關(guān)聯(lián)數(shù)據(jù)加載

          • 客戶端與服務(wù)端運(yùn)算

          • 跟蹤與不跟蹤

          • 復(fù)雜查詢運(yùn)算

          • 原生 SQL 查詢

          • 全局查詢篩選器

          關(guān)聯(lián)數(shù)據(jù)加載

          學(xué)員和助教都在項(xiàng)目分組中,調(diào)整模型,刪除 Assistant

          ProjectGroup 添加 Member 列表

          public List
              
                Members { 
               get; 
               set; }
               

          Member 添加 是否助教判斷,分組信息

          public bool IsAssistant { get; set; }

          public string GroupId { get; set; }

          public ProjectGroup Group { get; set; }

          Task 添加 學(xué)員信息

          public Member Member { get; set; }

          接下來(lái)為每一個(gè)表添加一個(gè)控制器

          一個(gè) Project 對(duì)應(yīng)多個(gè) ProjectGroup

          ProjectGroup

          namespace LighterApi.Controller
          {
          [ApiController]
          [Route("api/[controller]")]
          public class ProjectGroupController : ControllerBase
          {
          private readonly LighterDbContext _lighterDbContext;

          public ProjectGroupController(LighterDbContext lighterDbContext)
          {
          _lighterDbContext = lighterDbContext;
          }

          [HttpPost]
          public async Task Create([FromBody] ProjectGroup group)
          {
          _lighterDbContext.ProjectGroups.Add( group);
          await _lighterDbContext.SaveChangesAsync();

          return StatusCode(( int) HttpStatusCode.Created, group);
          }

          [ HttpGet]
          [ Route("{id}")]
          public async Task GetAsync( string id, CancellationToken cancellationToken)
          {
          var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
          return Ok(project);
          }
          }
          }

          遷移

          dotnet ef migrations add RefactoryProjectEntities

          dotnet ef database update

          Entity 主鍵添加自動(dòng)生成

          /// 
          /// 主鍵Id
          ///

          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public string Id { get; set; }

          啟動(dòng)程序,Postman 訪問(wèn)

          ProjectController

          [HttpGet]
          [Route("{id}")]
          public async Task GetAsync( string id, CancellationToken cancellationToken)
          {
          var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
          return Ok(project);
          }

          查詢項(xiàng)目信息,發(fā)現(xiàn)分組信息 groups 為空

          因?yàn)?EF 默認(rèn)不會(huì)查詢關(guān)聯(lián)數(shù)據(jù),所以需要實(shí)現(xiàn)一下

          ProjectController 獲取項(xiàng)目時(shí)使用 Include

          [HttpGet]
          [Route("{id}")]
          public async Task GetAsync( string id, CancellationToken cancellationToken)
          {
          var project = await _lighterDbContext.Projects.Include(p => p.Groups)
          .FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
          return Ok(project);
          }

          由于項(xiàng)目中有分組引用,分組中有項(xiàng)目引用,所以需要在序列化的時(shí)候處理循環(huán)引用

          Startup

          services.AddControllers()
          .AddNewtonsoftJson(x=>x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

          這樣就可以查到項(xiàng)目信息

          EF Core 為我們提供了三種加載數(shù)據(jù)的方式

          • 預(yù)先加載

          • 顯式加載

          • 延遲加載

          加載相關(guān)數(shù)據(jù):https://docs.microsoft.com/zh-cn/ef/core/querying/related-data/

          預(yù)先加載

          預(yù)先加載表示從數(shù)據(jù)庫(kù)中加載關(guān)聯(lián)數(shù)據(jù),作為初始查詢的一部分。

          在以下示例中,結(jié)果中返回的blogs將使用關(guān)聯(lián)的posts填充其 Posts 屬性。

          using (var context = new BloggingContext())
          {
          var blogs = context.Blogs
          .Include(blog => blog.Posts)
          .ToList();
          }

          顯式加載

          顯式加載表示稍后從數(shù)據(jù)庫(kù)中顯式加載關(guān)聯(lián)數(shù)據(jù)。

          可以通過(guò) DbContext.Entry(...) API 顯式加載導(dǎo)航屬性。

          using (var context = new BloggingContext())
          {
          var blog = context.Blogs
          .Single(b => b.BlogId == 1);

          context.Entry(blog)
          .Collection(b => b.Posts)
          .Load();

          context.Entry(blog)
          .Reference(b => b.Owner)
          .Load();
          }

          ProjectController

          // 顯式加載
          var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
          await _lighterDbContext.Entry(project).Collection(p => p.Groups).LoadAsync(cancellationToken);

          延遲加載

          延遲加載表示在訪問(wèn)導(dǎo)航屬性時(shí),從數(shù)據(jù)庫(kù)中以透明方式加載關(guān)聯(lián)數(shù)據(jù)。

          使用延遲加載的最簡(jiǎn)單方式是通過(guò)安裝 Microsoft.EntityFrameworkCore.Proxies 包,并通過(guò)調(diào)用 UseLazyLoadingProxies 來(lái)啟用該包。

          protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          => optionsBuilder
          .UseLazyLoadingProxies()
          .UseSqlServer(myConnectionString);

          或在使用 AddDbContext 時(shí):

          .AddDbContext
               
                (
                
          b => b.UseLazyLoadingProxies()
          .UseSqlServer(myConnectionString));

          EF Core 接著會(huì)為可重寫的任何導(dǎo)航屬性(即,必須是 virtual 且在可被繼承的類上)啟用延遲加載。例如,在以下實(shí)體中,Post.Blog 和 Blog.Posts 導(dǎo)航屬性將被延遲加載。

          public class Blog
          {
          public int Id { get; set; }
          public string Name { get; set; }

          public virtual ICollection Posts { get; set; }
          }

          public class Post
          {
          public int Id { get; set; }
          public string Title { get; set; }
          public string Content { get; set; }

          public virtual Blog Blog { get; set; }
          }

          Project

          public virtual ICollection
              
                Groups { 
               get; 
               set; }
               

          ProjectController

          // 延遲加載
          project.Groups// 引用到屬性時(shí)才加載

          客戶端與服務(wù)端運(yùn)算

          客戶端與服務(wù)端運(yùn)算:https://docs.microsoft.com/zh-cn/ef/core/querying/client-eval

          由于 SQL Server 提供程序不了解此方法的實(shí)現(xiàn)方式,因此無(wú)法將其轉(zhuǎn)換為 SQL。查詢的所有其余部分是在數(shù)據(jù)庫(kù)中評(píng)估的,但通過(guò)此方法傳遞返回的 URL 卻是在客戶端上完成。

          var blogs = context.Blogs
          .OrderByDescending(blog => blog.Rating)
          .Select(blog => new
          {
          Id = blog.BlogId,
          Url = StandardizeUrl(blog.Url)// 服務(wù)端轉(zhuǎn)換SQL,不了解客戶端方法實(shí)現(xiàn)
          })
          .ToList();

          public static string StandardizeUrl(string url)
          {
          url = url.ToLower();

          if (!url.StartsWith("http://"))
          {
          url = string.Concat("http://", url);
          }

          return url;
          }

          需要區(qū)分?jǐn)?shù)據(jù)運(yùn)算最終在客戶端,還是服務(wù)端運(yùn)行

          循環(huán)中獲取分組會(huì)導(dǎo)致多次查詢數(shù)據(jù)庫(kù)

          foreach (var project in _lighterDbContext.Projects)
          {
          project.Groups// 多次查詢數(shù)據(jù)庫(kù)
          }

          應(yīng)該一次性查詢

          var projects = _lighterDbContext.Projects.ToList();

          跟蹤與不跟蹤

          跟蹤與不跟蹤:https://docs.microsoft.com/zh-cn/ef/core/querying/tracking

          默認(rèn)情況下,跟蹤返回實(shí)體類型的查詢。這表示可以更改這些實(shí)體實(shí)例,然后通過(guò) SaveChanges() 持久化這些更改。

          非跟蹤查詢

          var blogs = context.Blogs
          .AsNoTracking()
          .ToList();

          還可以在上下文實(shí)例級(jí)別更改默認(rèn)跟蹤行為:

          context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

          var blogs = context.Blogs.ToList();

          復(fù)雜查詢運(yùn)算

          復(fù)雜查詢運(yùn)算:https://docs.microsoft.com/zh-cn/ef/core/querying/complex-query-operators

          聯(lián)接

          var query = from photo in context.Set
              
               ()
               
          join person in context.Set ()
          on photo.PersonPhotoId equals person.PhotoId
          select new { person, photo };

          GroupJoin

          var query = from b in context.Set<Blog>()
          join p in context.Set ()
          on b.BlogId equals p.PostId into grouping
          select new { b, grouping };

          SelectMany

          var query = from b in context.Set<Blog>()
          from p in context.Set ()
          select new { b, p };

          GroupBy

          var query = from p in context.Set
              
               ()
               
          group p by p.AuthorId into g
          select new
          {
          g.Key,
          Count = g.Count()
          };

          Left Join

          var query = from b in context.Set<Blog>()
          join p in context.Set ()
          on b.BlogId equals p. BlogId into grouping
          from p in grouping.DefaultIfEmpty()
          select new { b, p };

          原生 SQL 查詢

          原生 SQL 查詢:https://docs.microsoft.com/zh-cn/ef/core/querying/raw-sql

          var blogs = context.Blogs
          .FromSqlRaw("SELECT * FROM dbo.Blogs")
          .ToList();

          全局查詢篩選器

          全局查詢篩選器:https://docs.microsoft.com/zh-cn/ef/core/querying/filters

          modelBuilder.Entity
              
               ().HasQueryFilter(b => EF.Property<
               string>(b, 
               "_tenantId") == _tenantId);
               
          modelBuilder.Entity ().HasQueryFilter(p => !p.IsDeleted);

          所有實(shí)體都繼承了基類 Entity,所以這樣會(huì)把過(guò)濾器添加在所有查詢上面

          LighterDbContext

          modelBuilder.Entity
              
               ().HasQueryFilter(x => x.TenantId == 
               "");
               

          GitHub源碼鏈接:

          https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi

          課程鏈接

          .NET云原生架構(gòu)師訓(xùn)練營(yíng)講什么,怎么講,講多久


          歡迎各位讀者加入微信群一起學(xué)習(xí)交流,
          在公眾號(hào)后臺(tái)回復(fù)“加群”即可~~


          瀏覽 35
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人人操国产 | 国产美女艹逼 | 国产女人18毛片水真多1 | 欧美成人性无码 | 国产操|