Linq 多表連接查詢join


在查詢語言中,通常需要使用聯接操作。在 LINQ 中,可以通過 join 子句實現聯接操作。join 子句可以將來自不同源序列,並且在對象模型中沒有直接關系(數據庫表之間沒有關系)的元素相關聯,唯一的要求是每個源中的元素需要共享某個可以進行比較,以判斷是否相等的值。

LINQ 中,join 句可以實現 3 種類型的分別是內部聯接、接和部聯接。

 

1、內部連接(相對於sql:join | inner join)

格式:join element in dataSource on exp1 equals exp2

int[] intAry1 = {5, 15, 25, 30, 33, 40};//創建整數數組 intAry1 作為數據源
int[] intAry2 = {10, 20, 30, 50, 60, 70, 80};//創建整數數組 intAry2 作為數據源
//查詢 query1 使用 join 子句從兩個數據源獲取數據
//演示內部聯接的使用
var query1 =
from val1 in intAry1
join val2 in intAry2 on val1%5 equals val2%15
select new {VAL1=val1, VAL2=val2};

2、分組連接

格式: join element in dataSource on exp1 equals exp2 into grpName

其中,into 字表示將這些數據組並保存到 grpName 中,grpName 是保存一組數據的集合。(感覺和sql不同,sql查詢的結果是平面矩形的,而linq則是平面樹形的,意思是像對象的元素也是個對象)  

int[] intAry1 = { 5, 15, 25, 30, 33, 40 };//創建整數數組 intAry1 作為數據源
int[] intAry2 = { 10, 20, 30, 50, 60, 70, 80 };//創建整數數組 intAry2 作為數據源
//查詢 query1 使用 join 子句從兩個數據源獲取數據
//演示分組聯接的使用
var query1 =
from val1 in intAry1
join val2 in intAry2 on val1 % 5 equals val2 % 15 into val2Grp
select new { VAL1 = val1, VAL2GRP = val2Grp};

3、左外部聯接 (相對於sql:left join | left outer join)

第三種聯接是左外部聯接,它返回第一個集合中的所有元素,無論它是否在第二個集合中有相關元素。在 LINQ 中,通過對分組聯接的結果調用 DefaultIfEmpty()方法來執行左外部聯接。DefaultIfEmpty()方法從列表中獲取指定元素。如果列表為空,則返回默認值。

int[] intAry1 = { 5, 15, 23, 30, 33, 40 };//創建整數數組 intAry1 作為數據源
int[] intAry2 = { 10, 20, 30, 50, 60, 70, 80 };//創建整數數組 intAry2 作為數據源
//查詢 query1 使用 join 子句從兩個數據源獲取數據
//演示左聯接的使用
var query1 =
from val1 in intAry1
join val2 in intAry2 on val1 % 5 equals val2 % 15 into val2Grp
from grp in val2Grp.DefaultIfEmpty()
select new { VAL1 = val1, VAL2GRP = grp };

查詢方法Lambda示例(GroupJoin):

原形:https://msdn.microsoft.com/zh-cn/library/bb534297(v=vs.105).aspx

public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, IEnumerable<TInner>, TResult> resultSelector
)

重載

public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
    IEqualityComparer<TKey> comparer
)

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinqDemo2
{
    /// <summary>
    /// 學生實體
    /// </summary>
    public class Student
    {
        public int StudentId { get; set; }
        public string StudentName { get; set; }
        public int StandardId { get; set; }//水平
    }

    /// <summary>
    /// 水平/等級
    /// </summary>
    public class Standard
    {
        public int StandardId { get; set; }
        public string StandardName { get; set; }//
    }
    class Program
    {
        static void Main(string[] args)
        {
            #region 數據源
            IList<Student> studentList = new List<Student>()
            {
                new Student() {StudentId = 1, StudentName = "John", StandardId = 1},
                new Student() {StudentId = 2, StudentName = "Moin", StandardId = 1},
                new Student() {StudentId = 3, StudentName = "Bill", StandardId = 2},
                new Student() {StudentId = 4, StudentName = "Ram", StandardId = 2},
                new Student() {StudentId = 5, StudentName = "Ron"}
            };
            IList<Standard> standardList = new List<Standard>()
            {
                new Standard() {StandardId = 1, StandardName = "優秀"},
                new Standard() {StandardId = 2, StandardName = "中等"},
                new Standard() {StandardId = 3, StandardName = "差生"}
            };
            #endregion

            //查詢公式
            var groupJoin = standardList.GroupJoin(studentList,
                standard => standard.StandardId,
                student => student.StandardId,
                (standard, studentGroup) => new
                {
                    StandarFullName = standard.StandardName,
                    Students = studentGroup
                });//感覺和字典類型一樣,一個key,對應一個velue, velue = IEnumerable<Student>

            //執行查詢
            foreach (var item in groupJoin)
            {
                Console.WriteLine(item.StandarFullName);

                foreach (var student in item.Students)
                {
                    Console.WriteLine(student.StudentName);
                }
            }

            /* 輸出:
             * 
            優秀
            John
            Moin
            中等
            Bill
            Ram
            差生
            */


        }
    }
}

示例:分頁查詢

var page = 1;
            var pageSize = 10;
            var query = (from user in db.Set<User>()
                         join userRole in db.Set<UserRole>() on user.Id equals userRole.UserId
                         join rolePrivilege in db.Set<RolePrivilege>() on userRole.RoleId equals rolePrivilege.RoleId
                         join priviege in db.Set<Privilege>() on rolePrivilege.PrivilegeId equals priviege.Id
                         join role in db.Set<Role>() on userRole.RoleId equals role.Id
                         where user.Id == 1 && userRole.RoleId == 1
                         orderby user.Id descending
                         select new
                         {
                             user.Id,
                             userRole.RoleId,
                             user.Username,
                             PrivilegeName = priviege.Name,
                             RoleName = role.Name
                         }).Skip((page - 1) * pageSize).Take(pageSize);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM