當前位置: 妍妍網 > 碼農

深入了解 LINQ:關聯數據查詢例項講解

2024-06-01碼農

概述: 現在重點介紹利用 LINQ 查詢資料庫,特別是在處理各種模型關系(如一對一、一對多和多對多)時。本高級指南旨在填補資源缺口,並為您提供掌握這些概念的實用見解和程式碼範例。1. 了解資料庫中的模型關系在深入研究 LINQ 查詢之前,請務必了解資料庫模型中的關系型別:一對一:表中的一條記錄連結到另一個表中的一條記錄,並且只有一條記錄鏈 接。一對多:一個表中的記錄可以與另一個表中的一個或多個記錄相關聯。多對多:一個表中的記錄可以與另一個表中的多個記錄相關聯,反之亦然。為了說明 C# 中的各種關系,我們需要建立幾個類來表示這些關系中涉及的實體。讓我們為 、 、 、 、 、 和 中間類建立類,以演示一對一

現在重點介紹利用 LINQ 查詢資料庫,特別是在處理各種模型關系(如一對一、一對多和多對多)時。本高級指南旨在填補資源缺口,並為您提供掌握這些概念的實用見解和程式碼範例。

1. 了解資料庫中的模型關系

在深入研究 LINQ 查詢之前,請務必了解資料庫模型中的關系型別:

一對一:表中的一條記錄連結到另一個表中的一條記錄,並且只有一條記錄鏈> 接。 一對多:一個表中的記錄可以與另一個表中的一個或多個記錄相關聯。 多對多:一個表中的記錄可以與另一個表中的多個記錄相關聯,反之亦然。

為了說明 C# 中的各種關系,我們需要建立幾個類來表示這些關系中涉及的實體。讓我們為 、 、 、 、 、 和 中間類建立類,以演示一對一、一對多和多對多的關系。UserUserProfileCustomerOrderStudentCourseStudentCourse

一對一關系:使用者和 UserProfile

public classUser
{
publicint ID { get; set; }
publicstring Name { get; set; }
publicUserProfile UserProfile { get; set; } // Navigation property for one-to-one relationship
}
public classUserProfile
{
publicint UserID { get; set; } // Primary key and also foreign key
publicstring ProfilePicture { get; set; }
publicUser User { get; set; } // Navigation property for one-to-one relationship
}

一對多關系:客戶和訂單

public classCustomer
{
publicint ID { get; set; }
publicstring Name { get; set; }
publicList<Order> Orders { get; set; } // Navigation property for one-to-many relationship
}
public classOrder
{
publicint OrderID { get; set; }
publicint CustomerID { get; set; } // Foreign key
publicdecimal TotalAmount { get; set; }
publicCustomer Customer { get; set; } // Navigation property for one-to-many relationship
}

多對多關系:學生、課程和 StudentCourse

public classStudent
{
publicint ID { get; set; }
publicstring Name { get; set; }
publicList<StudentCourse> StudentCourses { get; set; } // Navigation property for many-to-many relationship
}
public classCourse
{
publicint ID { get; set; }
publicstring CourseName { get; set; }
publicList<StudentCourse> StudentCourses { get; set; } // Navigation property for many-to-many relationship
}
public classStudentCourse
{
publicint StudentID { get; set; } // Composite key (StudentID, CourseID)
publicint CourseID { get; set; } // Composite key (StudentID, CourseID)
publicStudent Student { get; set; } // Navigation property
publicCourse Course { get; set; } // Navigation property
}

這些類表示演示關系所需的基本結構。在實際應用程式中,您還需要使用實體框架(或其他 ORM)特定配置(如 Fluent API 或數據註釋)配置這些關系,以確保關系在資料庫中正確對映。

2. 一對一關系的 LINQ 查詢

讓我們從最簡單的關系開始。考慮兩個實體:和 ,每個使用者都有一個唯一的配置檔。UserUserProfile

查詢語法:

var userWithProfile = from user in context.Users
join profile in context.UserProfiles
on user.ID equals profile.UserID
selectnew { user.Name, profile.ProfilePicture };

方法語法:

var userWithProfile = context.Users
.Join(context.UserProfiles,
user => user.ID,
profile => profile.UserID,
(user, profile) => new { user.Name, profile.ProfilePicture });

在此轉換後的查詢中:

  • context.Users以及正在連線的兩個集合。context.UserProfiles

  • lambda 運算式 和 用於指定連線條件(from 與 from 匹配)。user => user.IDprofile => profile.UserIDIDUsersUserIDUserProfiles

  • 結果選擇器建立一個匿名物件,其中包含 from 和 from 。(user, profile) => new { user.Name, profile.ProfilePicture }NameUserProfilePictureUserProfile

  • 此 LINQ 查詢檢索每個使用者及其關聯的配置檔圖片。

    3. 掌握使用 LINQ 的一對多關系

    一對多關系在資料庫中很常見。例如,一個實體可能與多個 .CustomerOrders

    查詢語法:

    var customerOrders = from customer in context.Customers
    join order in context.Orders
    on customer.ID equals order.CustomerID
    selectnew { customer.Name, order.OrderID, order.TotalAmount };

    方法語法:

    var customerOrders = context.Customers
    .Join(context.Orders,
    customer => customer.ID,
    order => order.CustomerID,
    (customer, order) => new { customer.Name, order.OrderID, order.TotalAmount });

    在此查詢中:

  • context.Customers以及正在連線的兩個集合。context.Orders

  • lambda 運算式並指定連線鍵(from 和 from )。customer => customer.IDorder => order.CustomerIDIDCustomersCustomerIDOrders

  • 最終的 lambda 運算式使用 from 、 和 from 構造一個新的匿名物件。(customer, order) => new { customer.Name, order.OrderID, order.TotalAmount }NameCustomerOrderIDTotalAmountOrder

  • 此查詢將為您提供客戶列表及其各自的訂單。

    4. 駕馭多對多關系

    多對多關系更為復雜。考慮 和 ,其中學生可以註冊多門課程,並且每門課程可以有多個學生。StudentsCourses

    在這裏,通常使用像 這樣的中間表來管理這種關系。StudentCourses

    查詢語法:

    var courseEnrollments = from student in context.Students
    join sc in context.StudentCourses on student.ID equals sc.StudentID
    join course in context.Courses on sc.CourseID equals course.ID
    selectnew { student.Name, course.CourseName };

    方法語法:

    var courseEnrollments = context.Students
    .Join(context.StudentCourses,
    student => student.ID,
    sc => sc.StudentID,
    (student, sc) => new { student, sc })
    .Join(context.Courses,
    studentAndSc => studentAndSc.sc.CourseID,
    course => course.ID,
    (studentAndSc, course) => new { studentAndSc.student.Name, course.CourseName });

    在此查詢中:

  • 第一個連線。它將每個學生與其課程註冊相關聯。JoinStudentsStudentCourses

  • 第二個將此中間結果連結到 .它將註冊的課程與每個學生相關聯。JoinCourses

  • 結果選擇器將建立一個匿名物件,其中包含學生的姓名和課程名稱。(studentAndSc, course) => new { studentAndSc.student.Name, course.CourseName }

  • 此 LINQ 查詢有助於檢索每個學生註冊的課程。

    5. 高級方案和提示

    1. 關系中的過濾和排序

    假設您要尋找特定客戶的所有訂單並按日期對它們進行排序。以下是使用這兩種語法的方法。

    查詢語法:

    var sortedOrders = from order in context.Orders
    whereorder.CustomerID == specificCustomerId
    orderby order.OrderDate
    select order;

    方法語法:

    var sortedOrders = context.Orders
    .Where(order => order.CustomerID == specificCustomerId)
    .OrderBy(order => order.OrderDate);

    2. 急切載入與延遲載入範例

    急速載入在單個查詢中獲取相關數據,而延遲載入則按需獲取相關數據。下面是一個急切載入的範例:

    查詢語法:

    var customersWithOrders = from customer in context.Customers
    .Include(c => c.Orders)
    select customer;

    方法語法:

    var customersWithOrders = context.Customers
    .Include(c => c.Orders);

    3. 效能註意事項和最佳化

    了解如何最佳化 LINQ 查詢至關重要,尤其是對於大型數據集。

  • 使用投影:僅選擇所需欄位,而不是獲取整個實體。

  • 避免 N+1 查詢:在多對多關系中,請確保不會對每個計畫執行其他查詢。

  • 批次處理操作:對於更新或插入,請考慮使用批次處理操作以減少資料庫往返。

  • 最佳化投影範例:

    查詢語法:

    var optimizedData = from student in context.Students
    selectnew { student.Name, student.Department };

    方法語法:

    var optimizedData = context.Students
    .Select(student => new { student.Name, student.Department });

    4. 唯讀方案的 AsNoTracking

    對於唯讀方案,使用可以透過不跟蹤更改來提高效能。AsNoTracking

    查詢語法:

    var readOnlyData = context.Students
    .AsNoTracking()
    .Where(s => s.Year == 2);

    方法語法:

    var readOnlyData = from student in context.Students.AsNoTracking()
    wherestudent.Year == 2
    select student;

    結論:使用 LINQ 提升資料庫查詢技能

    LINQ 是 .NET 庫中的一種通用工具,用於處理各種型別的資料庫關系。無論是簡單的一對一關系還是復雜的多對多方案,LINQ 都能簡化和簡化流程,使程式碼更加高效和可維護。

    如果你喜歡我的文章,請給我一個贊!謝謝