日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ef 多个左联接查询_.NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记...

發布時間:2024/7/23 asp.net 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ef 多个左联接查询_.NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2.4.5 EF Core -- 查詢

  • 關聯數據加載
  • 客戶端與服務端運算
  • 跟蹤與不跟蹤
  • 復雜查詢運算
  • 原生 SQL 查詢
  • 全局查詢篩選器

關聯數據加載

學員和助教都在項目分組中,調整模型,刪除 Assistant

ProjectGroup 添加 Member 列表

public List<Member> Members { get; set; }

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

public bool IsAssistant { get; set; }public string GroupId { get; set; }public ProjectGroup Group { get; set; }

Task 添加 學員信息

public Member Member { get; set; }

接下來為每一個表添加一個控制器

一個 Project 對應多個 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<IActionResult> Create([FromBody] ProjectGroup group){_lighterDbContext.ProjectGroups.Add(group);await _lighterDbContext.SaveChangesAsync();return StatusCode((int) HttpStatusCode.Created, group);}[HttpGet][Route("{id}")]public async Task<IActionResult> GetAsync(string id, CancellationToken cancellationToken){var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);return Ok(project);}} }

遷移

dotnet ef migrations add RefactoryProjectEntitiesdotnet ef database update

Entity 主鍵添加自動生成

/// <summary> /// 主鍵Id /// </summary> [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public string Id { get; set; }

啟動程序,Postman 訪問

ProjectController

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

查詢項目信息,發現分組信息 groups 為空

因為 EF 默認不會查詢關聯數據,所以需要實現一下

ProjectController 獲取項目時使用 Include

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

由于項目中有分組引用,分組中有項目引用,所以需要在序列化的時候處理循環引用

Startup

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

這樣就可以查到項目信息

EF Core 為我們提供了三種加載數據的方式

  • 預先加載
  • 顯式加載
  • 延遲加載

加載相關數據:https://docs.microsoft.com/zh-cn/ef/core/querying/related-data/

預先加載

預先加載表示從數據庫中加載關聯數據,作為初始查詢的一部分。

在以下示例中,結果中返回的blogs將使用關聯的posts填充其 Posts 屬性。

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

顯式加載

顯式加載表示稍后從數據庫中顯式加載關聯數據。

可以通過 DbContext.Entry(...) API 顯式加載導航屬性。

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);

延遲加載

延遲加載表示在訪問導航屬性時,從數據庫中以透明方式加載關聯數據。

使用延遲加載的最簡單方式是通過安裝 Microsoft.EntityFrameworkCore.Proxies 包,并通過調用 UseLazyLoadingProxies 來啟用該包。

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

或在使用 AddDbContext 時:

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

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

public class Blog {public int Id { get; set; }public string Name { get; set; }public virtual ICollection<Post> 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<ProjectGroup> Groups { get; set; }

ProjectController

// 延遲加載 project.Groups// 引用到屬性時才加載

客戶端與服務端運算

客戶端與服務端運算:https://docs.microsoft.com/zh-cn/ef/core/querying/client-eval

由于 SQL Server 提供程序不了解此方法的實現方式,因此無法將其轉換為 SQL。 查詢的所有其余部分是在數據庫中評估的,但通過此方法傳遞返回的 URL 卻是在客戶端上完成。

var blogs = context.Blogs.OrderByDescending(blog => blog.Rating).Select(blog => new{Id = blog.BlogId,Url = StandardizeUrl(blog.Url)// 服務端轉換SQL,不了解客戶端方法實現}).ToList();public static string StandardizeUrl(string url) {url = url.ToLower();if (!url.StartsWith("http://")){url = string.Concat("http://", url);}return url; }

需要區分數據運算最終在客戶端,還是服務端運行

循環中獲取分組會導致多次查詢數據庫

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

應該一次性查詢

var projects = _lighterDbContext.Projects.ToList();

跟蹤與不跟蹤

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

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

非跟蹤查詢

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

還可以在上下文實例級別更改默認跟蹤行為:

context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;var blogs = context.Blogs.ToList();

復雜查詢運算

復雜查詢運算:https://docs.microsoft.com/zh-cn/ef/core/querying/complex-query-operators

聯接

var query = from photo in context.Set<PersonPhoto>()join person in context.Set<Person>()on photo.PersonPhotoId equals person.PhotoIdselect new { person, photo };

GroupJoin

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

SelectMany

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

GroupBy

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

Left Join

var query = from b in context.Set<Blog>()join p in context.Set<Post>()on b.BlogId equals p.BlogId into groupingfrom 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<Blog>().HasQueryFilter(b => EF.Property<string>(b, "_tenantId") == _tenantId); modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);

所有實體都繼承了基類 Entity,所以這樣會把過濾器添加在所有查詢上面

LighterDbContext

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

GitHub源碼鏈接:

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

總結

以上是生活随笔為你收集整理的ef 多个左联接查询_.NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。