Tag: LINQ

  • ข้อมูลใน DropdownList แรกจนถึง DropdownList สุดท้ายกับค่าที่เหลืออยู่ของเขา ด้วย LINQ

    ในช่วงที่ผ่านมา ได้มีการพัฒนาระบบโดยมีการนำ LinQ มาใช้นิด ๆ หน่อย ๆ (มือใหม่หัดใช้ >< ) ซึ่งมีอยู่ฟังก์ชันนึงที่เกี่ยวกับ การ Bind ค่า DropdownList กรณีที่มี DropdownList หลาย ๆ ตัวและไม่อยากให้ค่าที่เคยเลือกจาก DropdownList ก่อนหน้าไปแสดงใน DropdownList ถัดไปอีก น่าสนใจทดลองใช้แล้วทำงานได้ดี ผู้เขียนจึงนำมาเขียนเพื่อไว้เตือนความจำ จะได้กลับมาอ่าน แนวคิดและวิธีการดังนี้ค่ะ

    ในขั้นตอนแรก สร้าง Data ที่ชื่อว่า MyList เก็บข้อมูล id และชื่อ เพื่อเตรียมเป็น DataSource สำหรับ Bind ให้กับ DropdownList1 ดังนี้

    class MyList
    {
        private string id = string.empty;
        private string name = string.empty;
    
        public MyList(string _id, string _name)
        {
            id = _id;
            name = _name;
        }
    
        public string ID
        {
            get{return id;}
            set {id = value;}
        }
    
        public string Name
        {
            get{return name;}
            set {name = value;}
        }
    }

    ต่อมากำหนดค่าให้กับ MyList เพื่อผูกให้กับ DropdownList1

    List<MyList> mylist = new List<MyList>{
                        new MyList(1,'name1'),
                        new MyList(2,'name2'),
                        new MyList(3,'name3'),
                        new MyList(5,'name5'),
                        new MyList(10,'name10')
                        };

    ผลลัพธ์ของ DropdownList1 ได้ดังนี้

    ID          Name
    1 name1
    2 name2
    3 name3
    5 name5
    10 name10

    ต่อมา กำหนดว่า DropdownList1 เลือกค่าเป็น ID = ‘2’

    string mySelectedValue = '2';

    จากนั้น ที่ Event SelectedIndexChange ของ DropdownList1 ให้ใส่ Code ดังนี้

    var myDataSource = from d in MyList
    where !mySelectedValue.Contains(d.ID)
    select d;

    จากนั้นผูก myDataSource ให้กับ DropdownList2 ค่าล่าสุดใน DropdownList2 จะแสดงดังด้านล่าง โดยที่ ID = ‘2’ จะหายไป เนื่องจากถูกเลือกไปแล้ว ดังนี้

    ID          Name
    1           name1
    3           name3
    5           name5
    10          name10

    กรณีที่มี DropdownList3 ก็ให้ทำเหมือนขั้นตอนก่อนหน้า ตัวอย่างกำหนดค่าการเลือกของ DropdownList1 = ‘2’ และ DropdownList2 = ‘5’ ดังนี้

    string mySelectedValue = '2,5';

    จากนั้น ที่ Event SelectedIndexChange ของ DropdownList2 ให้ใส่ Code แบบเดิม

    var myDataSource = from d in MyList
    where !mySelectedValue.Contains(d.ID)
    select d;

    จากนั้นผูก myDataSource ให้กับ DropdownList3 ค่าล่าสุดใน DropdownList3 จะแสดงดังด้านล่าง โดยที่ ID = ‘2’ และ ‘5’ จะหายไป เนื่องจากถูกเลือกไปแล้ว ดังนี้

    ID           Name
    1            name1
    3            name3
    10           name10

    จะเห็นได้ว่าเราใช้ Query เดียวกันในหลาย ๆ DropdownList ดังนั้นสามารถทำ Query นี้ให้เป็นฟังก์ชันเพื่อเรียกใช้งานได้

    หวังว่าจะเป็นประโยชน์ไม่มากก็น้อยสำหรับผู้อ่านนะคะ \(@^0^@)/

  • Refresh ข้อมูลในกรณีที่ฐานข้อมูลมีการอัพเดทใน LINQ และ Entity Framework (Refresh Query in LINQ)

    จากปัญหาที่เคยเจอในกรณีที่ฐานข้อมูลมีการอัพเดทไปแล้ว พอ Select ข้อมูลออกมาข้อมูลไม่ refresh ในกรณีนี้จะยกตัวอย่างการใช้งานฟังก์ชัน reload ของ System.Data.Entity.Infrastructure

    public class DbEntityEntry where TEntity : class

    // Summary:
    // Reloads the entity from the database overwriting any property values with values
    // from the database. The entity will be in the Unchanged state after calling this
    // method.
    public void Reload();

    โดยการใช้งานนั้นจะยกตัวอย่างตามโค้ดด้านล่าง

    ProjectEntities pe = new ProjectEntities();

    var project = pe.PROJECT.Where(w => w.ID == projectID && w.YEAR == year).FirstOrDefault();

    if (project != null)

    {
    pe.Entry(project).Reload();

    }

    หวังว่าคงจะได้ช่วยโปรแกรมเมอร์ทีมีปัญหาเรื่องการ refresh ข้อมูลผ่าน LINQ และ Entity Framework

  • การสร้างเงื่อนไขแบบหลายตัวแปรในการค้นหาข้อมูลผ่าน LINQ (Multiple Search In LINQ)

    การสร้างเงื่อนไขแบบหลายตัวแปรในการค้นหาข้อมูลผ่าน Linq เพื่อให้เห็นภาพชัดเจน จะยกตัวอย่างโดย กำหนดเงื่อนไข 3 ตัวแปร ดังนี้

    • ตัวแปร “ชื่อ/นามสกุล/เลขประจำตัวประชาชน”
      โดยใช้ control TextBox ที่ชื่อ ID=”txtSearch”
    • ตัวแปร “โครงการรับ” โดยใช้ control DropDownList ที่ชื่อ ID=”ddProject”
    • ตัวแปร “สถานะการตรวจเอกสาร”
      โดยใช้ control DropDownList ที่ชื่อ ID=”ddStatus”

    จากนั้นเราสร้าง Entity ยกตัวอย่างเป็น UploadEntities ซึ่งในที่นี้ สร้าง DbSet ที่เชื่อมต่อฝั่งฐานข้อมูลยกตัวอย่างเป็น V_REGISTRATION_UPLOAD ผ่าน Entity Framework 4.5 จากนั้นใช้ LINQ ในการเขียนเงื่อนไข ยกตัวอย่างตามโค้ดด้านล่าง

    project = ddProject.SelectedValue;

    status = ddStatus.SelectedValue;

    search = txtSearch.Text.Trim();

    outList = ue.V_REGISTRATION_UPLOAD

    .Where(w => (w.STUD_FNAME.Contains(search) || w.STUD_LNAME.Contains(search) || w.CITIZEN_ID.Contains(search)) || string.IsNullOrEmpty(search))

    .Where(x => x.PROJECT_ID == project || string.IsNullOrEmpty(project))

    .Where(y => y.APPROVED_STATUS == status || string.IsNullOrEmpty(status)) .ToList();

    gvUploadedList.DataSource = outList;

    gvUploadedList.DataBind();

    แสดงการใช้งานฟังก์ชัน Where ของ LINQ ในส่วนของ code behide
    ผลลัพธ์ที่ได้จากการเรียกใช้เงื่อนไขฟังก์ชัน Where ของ LINQ

    สรุปได้ว่าการนำฟังก์ชัน Where ของ LINQ มาใช้งานนั้น ทำให้โปรแกรมเมอร์สะดวกและลดการเขียนโค้ดให้ง่ายขึ้นจากเมื่อก่อนที่ต้องตรวจสอบเงื่อนไขเป็นแบบทีละเงื่อนไข

  • การใช้ LINQ ในการจัดการข้อมูลอย่างง่าย สำหรับมือใหม่(Ep.2)

              ความเดิมตอนที่แล้ว… ผู้เขียนได้ทิ้งท้ายไว้เกี่ยวกับเรื่องการใช้งาน LINQ ในการจัดการข้อมูลในเบื้องต้น ได้แก่ วิธีการดึงข้อมูลโดยทั่วไป(Select) การดึงข้อมูลแบบมีเงื่อนไข(Where) และการเรียงลำดับ(OrderBy) เป็นต้น หากใครที่ยังไม่เคยอ่านบทความที่แล้ว และต้องการศึกษาในส่วนดังกล่าวสามารถหาอ่านได้จากลิงค์ “การใช้ LINQ ในการจัดการข้อมูลอย่างง่าย สำหรับมือใหม่(Ep.1)” เพื่อเพิ่มความเข้าใจพื้นฐานในการใช้งานเบื้องต้น LINQ เพิ่มเติม และสำหรับในบทความนี้ ผู้เขียนจะขอพูดถึงการใช้งาน LINQ ในส่วนอื่นๆที่นอกเหนือจากการทำงานทั่วไป ที่คิดว่าน่าจะเป็นประโยชน์กับผู้พัฒนาที่มีความสนใจในการใช้งาน LINQ จัดการข้อมูล ดังนี้

    • การคำนวณค่าร่วม/นับจำนวน

    ตัวอย่างที่ 1 : การคำนวณค่าผลรวมของฟิลด์ที่ดึงข้อมูลโดยใช้เมธอด Sum

    decimal sumLineTotal = (from od in orderdetailscollection
    select od.LineTotal).Sum();
    

    หรือ

    decimal sumLineTotal = orderdetailscollection.Sum(od => od.LineTotal);
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการดึงข้อมูลโดยมีการคำนวณค่าผลรวมที่ได้จากการดึงข้อมูลทั้งหมดในฟิลด์ LineTotal ผ่านเมธอด Sum โดยที่ไม่ต้องมาวนค่าเพื่อหาผลรวมของแต่ละฟิลด์ที่ดึงมาอีกครั้งในภายหลัง ซึ่งถือว่าเป็นการอำนวยความสะดวกและประหยัดเวลาในการพัฒนาให้กับผู้พัฒนาที่ต้องการทำงานในกรณีดังกล่าวได้

    ตัวอย่างที่ 2 : เป็นการคำนวณค่าเฉลี่ยตามรหัส

    double RatingAverage = ctx.Rates.Where(r => r.Id == Id).Average(r => r.Rating);
    

    หรือ

    var RatingAverage = (from a in ctx.Rates where a. Id.Equals(id)
    select a.Rating).Average();
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการคำนวณหาค่าเฉลี่ยของฟิลด์ Rating โดยใช้เมธอด Average ภายใต้เงื่อนไขรหัส Id ในการดึงข้อมูล

    ตัวอย่างที่ 3 : เป็นตัวอย่างการคำนวณผลรวม และการนับจำนวนแถวของการอ่านข้อมูลโดยมีการจัดกลุ่มข้อมูลร่วมด้วย

    var ListByOwner = list.GroupBy(l => l.Owner)
    .Select(lg => new {
    Owner = lg.Key,
    Boxes = lg.Count(),
    TotalWeight = lg.Sum(w => w.Weight),
    AverageVolume = lg.Average(w => w.Volume)
    });
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นได้ว่าเป็นการจัดกลุ่มของข้อมูลตาม Owner โดยใช้เมธอด GroupBy และมีการนับจำนวนแถวเก็บไว้ในฟิลด์ Boxes คำนวณผลรวมของคอลัมน์ Weight และหาค่าเฉลี่ยของคอลัมน์ Volume ใส่ในฟิลด์ TotalWeight และ AverageVolume นั่นเอง

    ตัวอย่างที่ 4 : เป็นการนับจำนวนข้อมูลตามเงื่อนไขที่กำหนดโดยใช้เมธอด Count

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    
    int oddNumbers = numbers.Count(n => n % 2 == 1);
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นว่า เป็นการดึงค่าจากตัวแปรอาร์เรย์ที่ชื่อว่า numbers และนับจำนวนตัวเลขเฉพาะที่เป็นเลขคี่(หารด้วยสองและมีค่าเศษ 1)เท่านั้นด้วยเมธอด Count ซึ่งในส่วนของเงื่อนไขดังกล่าว ผู้อ่านสามารถนำไปประยุกต์ใช้กับงานของตนในการนับจำนวนข้อมูลได้

    ผลลัพธ์ : จากการอ่านข้อมูลจากตัวแปร numbers ส่งผลให้ oddNumbers มีค่าเท่ากับ 5 นั่นคือในการดึงข้อมูลพบเลขที่มีค่าเป็นเลขคี่ดังนี้ 5,1,3,9,7

    • การค่าที่น้อยที่สุดและมากที่สุดโดยใช้เมธอด Min/Max

    ตัวอย่างที่ 1 : การหาค่าที่น้อยที่สุดโดยใช้เมธอด Min

    string[] words = { "cherry", "apple", "blueberry" };
    
    int shortestWord = words.Min(w => w.Length);
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นว่า เป็นการอ่านค่าจากตัวแปรอาร์เรย์ที่ชื่อว่า words และหาค่าที่น้อยที่สุดของจำนวนความยาวตัวอักษรจากค่าที่อ่านได้ด้วยเมธอด Min

    ผลลัพธ์shortestWord มีค่าเท่ากับ 5 ซึ่งก็คือค่าความยาวตัวอักษรของคำว่า “apple” ที่มีค่าเท่ากับ 5 ซึ่งเป็นค่าที่น้อยที่สุดนั่นเอง

    ตัวอย่างที่ 2 : เป็นการหาราคาที่ถูกที่สุดจากรายการสินค้าที่อ่านได้แต่ละประเภท(จัดกลุ่มตามประเภทสินค้า) โดยใช้เมธอด Min

    List<Product> products = GetProductList();
    var categories =
    from p in products
    group p by p.Category into g
    select new { Category = g.Key, CheapestPrice = g.Min(p => p.UnitPrice) };
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการหาค่าที่น้อยที่สุดของราคาในคอลัมน์ UnitPrice จาก list ของคลาส Product ที่ดึงมาได้ และมีการจัดกลุ่มตามประเภทของสินค้า นั่นหมายถึง ค่าที่ได้จากการอ่านข้อมูลนี้จะเป็นค่าของราคาสินค้าต่อหน่วยที่น้อยที่สุดในแต่ละประเภทสินค้านั่นเอง

    หมายเหตุ : การใช้งานเมธอด Max จะมีลักษณะการทำงานเช่นเดียวกับเมธอด Min แต่เป็นการหาค่าที่มากที่สุดจากการอ่านข้อมูล ซึ่งผู้อ่านสามารถนำไปใช้แทนกันได้ตามตัวอย่างการใช้งานเมธอด Min ข้างต้นได้

    • การใช้งาน set operator
      • การกำจัดข้อมูลที่ซ้ำกัน

      ตัวอย่างที่ 1 : เป็นการจำกัดข้อมูลที่ซ้ำกันด้วยเมธอด Distinct/DistinctBy

      List<Product> products = GetProductList();
      var categoryNames = (
      from p in products
      select p.Category).Distinct();
      

      หรือ 

      List<Product> products = GetProductList();
      var categoryNames = products.DistinctBy(x=> x.Category);
      

      คำอธิบาย : เป็นการดึงข้อมูลประเภทสินค้าที่ไม่ซ้ำกันไว้ในตัวแปร categoryNames โดยใช้เมธอด Distinct และ DistinctBy (ที่เรียกใช้จาก MoreLinq Library)
      หมายเหตุ : หากต้องการกำจัดข้อมูลที่ซ้ำกันมากกว่า 1 คอลัมน์ สามารถทำได้ ดังนี้

      List<Product> products = GetProductList();
      var categoryNames = products.DistinctBy(a => new { a.Category, a.Code });
      

      ตัวอย่างที่ 2 :

      List<Product> products = GetProductList();
      var categoryNames = products
       .GroupBy(a => a.Category )
       .Select(g => g.First());
      

      คำอธิบาย : เป็นการดึงข้อมูลประเภทสินค้าที่ไม่ซ้ำกันไว้ โดยใช้เมธอดการจัดกลุ่มข้อมูลตามประเภทสินค้าด้วยเมธอด GroupBy และดึงค่าแรกสุดของแต่ละกลุ่มมาแสดงด้วยเมธอด First ตามลำดับ

      ตัวอย่างที่ 3 :

      var total = items.Select(item => item.Value).Distinct().Count();
      

      คำอธิบาย : เป็นการนับจำนวนของข้อมูลที่ไม่ซ้ำกันโดยใช้เมธอด Distinct และเมธอด Count

      • การผสานข้อมูลโดยใช้ Union

      ตัวอย่างที่ 1 :

      int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
      int[] numbersB = { 1, 3, 5, 7, 8 }; 
      var uniqueNumbers = numbersA.Union(numbersB); 
      

      คำอธิบาย : เป็นการรวมข้อมูลจาก 2 แหล่ง ด้วยเมธอด Union
      ผลลัพธ์ : uniqueNumbers = {0, 2, 4, 5, 6, 8, 9,1, 3, 7, 8}

      • การเลือกเฉพาะข้อมูลที่ซ้ำกันจากข้อมูล 2 แหล่งมาแสดงด้วยเมธอด Intersect

      ตัวอย่างที่ 1 :

      var infoQuery =
       (from cust in db.Customers
       select cust.Country)
       .Intersect
       (from emp in db.Employees
       select emp.Country);
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในตาราง Customers และ Employees เพื่อเปรียบเทียบค่าคอลัมน์ Country จาก 2 แหล่ง หากมีซ้ำกันทั้ง 2 ที่จะดึงมาเก็บไว้ในตัวแปร infoQuery

      ตัวอย่างที่ 2 :

       int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
       int[] numbersB = { 1, 3, 5, 7, 8 }; 
       
       var commonNumbers = numbersA.Intersect(numbersB); 
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในตัวแปรอาร์เรย์ numbersA และ numbersB เพื่อเปรียบเทียบค่า หากมีซ้ำกันทั้ง 2 ที่จะดึงมาเก็บไว้ในตัวแปร commonNumbers
      ผลลัพธ์ : commonNumbers = { 5, 8}

      • การยกเว้นการอ่านข้อมูลโดยใช้ Except

      ตัวอย่างที่ 1 :

       List<Product> products = GetProductList(); 
       List<Customer> customers = GetCustomerList(); 
       
       var productFirstChars = 
       from p in products 
       select p.ProductName[0]; ///ดึงอักษรตัวแรกของชื่อสินค้า
       var customerFirstChars = 
       from c in customers 
       select c.CompanyName[0]; ///ดึงอักษรตัวแรกของชื่อบริษัท
       
       var productOnlyFirstChars = productFirstChars.Except(customerFirstChars); 
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในส่วนของลิสต์ products และ customers โดยเอาเฉพาะอักษรตัวแรกของข้อมูลมาเพื่อเปรียบเทียบค่าโดยเทียบจาก productFirstChars หากพบว่าซ้ำกับในตัวอักษรแรกของข้อมูลชื่อบริษัทที่เก็บไว้ในตัวแปร customerFirstChars จะข้ามไป ไม่ดึงมาเก็บไว้ในตัวแปร productOnlyFirstChars แต่หากไม่ซ้ำ จะนำมาเก็บไว้ ผลลัพธ์สุดท้ายที่ได้จึงจะมีเฉพาะที่มีใน productFirstChars และไม่ซ้ำกับในข้อมูล customerFirstChars เท่านั้น
      ตัวอย่างที่ 2 :

       int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
       int[] numbersB = { 1, 3, 5, 7, 8 }; 
       
       IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB); 
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในตัวแปรอาร์เรย์ numbersA และ numbersB เพื่อเปรียบเทียบค่าโดยเทียบจาก numbersA เทียบกับ numbersB จะเอาเฉพาะที่มีใน numbersB แต่ไม่มีใน numbersB มาเก็บไว้ในตัวแปร aOnlyNumbers
      ผลลัพธ์ : aOnlyNumbers = { 0, 2, 4, 6, 9}

      • การอ่านข้อมูลจาก 2 แหล่งข้อมูลด้วยวิธีการ join
        • การ join แบบ innerjoin

        ตัวอย่างที่ 1 : เป็นการเชื่อมตาราง 2 ตารางโดยจะเอาเฉพาะข้อมูลแถวที่มี key ร่วมกันจากทั้ง 2 แหล่ง

        var result = from p in Person.BuiltPersons()
         join a in Address.BuiltAddresses() ///ระบุตารางที่นำมาเชื่อมกัน
         on p.IdAddress equals a.IdAddress ///กำหนด key ร่วมจาก 2 ตาราง
         select new 
         { ///เลือกคอลัมน์ที่ต้องการนำมาใช้
         Name = a.MyPerson.Name,
         Age = a.MyPerson.Age,
         PersonIdAddress = a.MyPerson.IdAddress,
         AddressIdAddress = a.MyAddress.IdAddress,
         Street = a.MyAddress.Street
         }; 
        

        คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นเป็นการเชื่อมตาราง 2 ตารางเข้าด้วยกัน และเลือกเฉพาะข้อมูลที่มีรหัส IdAddress ตรงกันมาแสดงเท่านั้น

        หรือ 

        var resultJoint = Person.BuiltPersons().Join( /// Source Collection
         Address.BuiltAddresses(), /// Inner Collection
         p => p.IdAddress, /// กำหนด key จากตาราง Person.BuiltPersons()
         a => a.IdAddress, /// กำหนด key จากตาราง Address.BuiltAddresses()
         (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
         .Select(a => new
         {
         Name = a.MyPerson.Name,
         Age = a.MyPerson.Age,
         PersonIdAddress = a.MyPerson.IdAddress,
         AddressIdAddress = a.MyAddress.IdAddress,
         Street = a.MyAddress.Street
         });
        • การ join แบบ leftjoin

        ตัวอย่างที่ 1 :

        string[] categories = new string[]{ 
         "Beverages", 
         "Condiments", 
         "Vegetables", 
         "Dairy Products", 
         "Seafood" }; 
          List<Product> products = GetProductList(); 
          
         var q = 
         from c in categories 
         join p in products on c equals p.Category into ps 
         from p in ps.DefaultIfEmpty() 
        ///ถ้าไม่มีข้อมูลจะแสดงข้อความ (No products)
         select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName }; 
        

        คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นได้ว่าเป็นการเชื่อมข้อมูล 2 แหล่ง โดยยึดตามแหล่งข้อมูลแรก ในที่นี้คือข้อมูล categories และเทียบกับข้อมูลใน products หากข้อมูลที่เปรียบเทียบมีใน categories แต่ไม่มีใน products ก็จะนำมาแสดง โดยให้ค่าของ ProductName เป็น (No products) แทน(ตามหลักการ join แบบ leftjoin ) หรืออธิบายง่ายๆว่า จะแสดงทุกรายการที่มีใน categories นั่นเอง

        • การ join แบบ rightjoin

        ตัวอย่างที่ 1 :

        var rightOuterJoin = from last in lastNames
         join first in firstNames
         on last.ID equals first.ID
         into temp
         from first in temp.DefaultIfEmpty(new { last.ID, Name = default(string) })
         select new
         {
         last.ID,
         FirstName = first.Name,
         LastName = last.Name,
         };
        

        คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นได้ว่าเป็นการเชื่อมข้อมูล 2 แหล่ง โดยยึดตามแหล่งข้อมูลแรก ในที่นี้คือข้อมูล lastNames และเทียบกับข้อมูลใน firstNames โดยยึดข้อมูลจาก firstNames หากข้อมูลที่เปรียบเทียบมีใน firstNames แต่ไม่มีใน lastNames ก็จะนำมาแสดง โดยให้ค่าของ default(string) แทน(ตามหลักการ join แบบ rightjoin ) หรืออธิบายง่ายๆว่า จะแสดงทุกรายการที่มีใน firstNames นั่นเอง

                จะเห็นได้ว่าจากบทความการใช้งาน LINQ ในการจัดการข้อมูลอย่างง่าย สำหรับมือใหม่ ทั้งใน Ep.1 และ Ep.2 นี้ ผู้เขียนพยายามรวบรวมวิธีที่เป็นการใช้งานพื้นฐานและยกตัวอย่างในกรณีต่างๆ เพื่อให้ผู้อ่านเห็นภาพ และทำความเข้าใจได้โดยง่ายขึ้น สามารถนำไปประยุกต์ใช้กับงานพัฒนาที่กำลังพัฒนาอยู่ได้ แต่ความสามารถของ LINQ ไม่ได้จบเพียงเท่านี้ ยังคงมีเมธอดและวิธีการใช้งานอื่นๆ รวมทั้งการประยุกต์ใช้งานอีกมากมายรอให้ผู้อ่านได้ทำการศึกษาเพิ่มเติมและหยิบมาใช้งานกัน เพื่อเพิ่มประสิทธิภาพและความคล่องตัวในการพัฒนาโปรแกรมกันต่อไป ผู้เขียนเชื่อว่าหากผู้อ่านได้มีการศึกษาและฝึกลองทำหลายๆกรณีก็จะทำให้สามารถใช้งาน LINQ ได้เกิดประโยชน์สูงสุด สุดท้ายนี้ผู้เขียนหวังเป็นอย่างยิ่งว่าสิ่งที่ผู้เขียนได้หยิบยกมาให้ผู้อ่านได้อ่านกันนี้จะเป็นประโยชน์ไม่มากก็น้อย หากผิดพลาดประการใดผู้เขียนขออภัยไว้ ณ ที่นี้ด้วย และขอบคุณที่ติดตามอ่านบทความนี้จนจบนะคะ ขอบคุณค่ะ

      แหล่งข้อมูลอ้างอิง :
      https://code.msdn.microsoft.com/LINQ-Aggregate-Operators-c51b3869

      http://stackoverflow.com/questions/61870/sum-of-items-in-a-collection

      http://stackoverflow.com/questions/17983024/finding-average-of-value-based-on-count-of-rows-in-linq?rq=1

      https://code.msdn.microsoft.com/LINQ-Set-Operators-374f34fe

      http://www.codeproject.com/Articles/535374/DistinctBy-in-Linq-Find-Distinct-object-by-Propert
      https://code.msdn.microsoft.com/LINQ-Join-Operators-dabef4e9

      http://www.codeproject.com/Articles/488643/LinQ-Extended-Joins