ความแตกต่างระหว่างอินเทอร์เฟซ IQueryable, ICollection, IList และ IDictionary

ฉันกำลังพยายามเข้าใจความแตกต่างระหว่างอินเทอร์เฟซ IQueryable, ICollection, IList และ IDictionary ซึ่งเร็วกว่าสำหรับการดำเนินการพื้นฐาน เช่น การวนซ้ำ การจัดทำดัชนี การสืบค้น และอื่นๆ

คลาสใดเช่น Collection, List, Dictionary ฯลฯ เหมาะที่จะเริ่มต้นด้วยอินเทอร์เฟซเหล่านี้ และเมื่อใดที่เราควรใช้คลาสเหล่านี้ ข้อดีพื้นฐานของการใช้คลาสเหล่านี้เหนือคลาสอื่นๆ

ฉันลองอ่านโพสต์อื่นที่มีคำถามที่คล้ายกัน แต่ไม่มีอะไรตอบคำถามของฉันทั้งหมด ขอบคุณสำหรับความช่วยเหลือ


person Praneeth    schedule 15.12.2010    source แหล่งที่มา


คำตอบ (3)


อินเทอร์เฟซทั้งหมดนี้สืบทอดมาจาก IEnumerable ซึ่งคุณควรแน่ใจว่าคุณเข้าใจ โดยพื้นฐานแล้วอินเทอร์เฟซนั้นให้คุณใช้คลาสในคำสั่ง foreach (ใน C#)

  • ICollection เป็นอินเทอร์เฟซพื้นฐานที่สุดที่คุณระบุไว้ มันเป็นอินเทอร์เฟซนับไม่ถ้วนที่รองรับการนับและก็ประมาณนั้น
  • IList คือทุกสิ่งที่ ICollection เป็น แต่ยังรองรับการเพิ่มและลบรายการ การดึงรายการตามดัชนี ฯลฯ เป็นอินเทอร์เฟซที่ใช้บ่อยที่สุดสำหรับ "รายการวัตถุ" ซึ่งฉันรู้คลุมเครือ
  • IQueryable เป็นอินเทอร์เฟซนับได้ที่รองรับ LINQ คุณสามารถสร้าง IQueryable จาก IList และใช้ LINQ กับ Objects ได้เสมอ แต่คุณยังพบ IQueryable ที่ใช้สำหรับการดำเนินการคำสั่ง SQL แบบเลื่อนออกไปใน LINQ เป็น SQL และ LINQ ไปยัง Entities
  • IDictionary เป็นสัตว์ชนิดอื่นในแง่ที่ว่าเป็นการแมปคีย์ที่ไม่ซ้ำกับค่า นอกจากนี้ ยังมีการแจกแจงด้วยว่าคุณสามารถระบุคู่คีย์/ค่าได้ แต่อย่างอื่นจะทำหน้าที่เพื่อวัตถุประสงค์ที่แตกต่างจากรายการอื่นๆ ที่คุณระบุไว้

เอกสาร MSDN สำหรับแต่ละเอกสารเหล่านี้มีความเหมาะสม ดังนั้น ฉันจะเริ่มต้นในการสรุปความเข้าใจของคุณ

person John Bledsoe    schedule 15.12.2010
comment
+1 สำหรับคำอธิบายโดยละเอียดสำหรับอินเทอร์เฟซเหล่านี้ แต่คุณพลาดคำถามอื่น ๆ ของฉัน - person Praneeth; 16.12.2010
comment
ในแง่ของอินเทอร์เฟซเวอร์ชันทั่วไป ICollection‹T› รองรับ Add/Remove/Clear/Contains/CopyTo ตาม msdn.microsoft.com/en-us/library/92t2ye13.aspx - person Joshua Rodgers; 16.12.2010

ฉันสังเกตเห็นปัญหาหลายประการในคำตอบของ @ gunny229 ด้านบน ซึ่งเป็นสาเหตุที่ฉันเขียนโพสต์นี้ ฉันได้กล่าวถึงปัญหาเหล่านั้นในพื้นที่แสดงความคิดเห็นของโพสต์ของเขาแล้วเช่นกัน เพื่อแก้ไขโพสต์นั้น ฉันจะต้องเขียนใหม่เกือบทั้งโพสต์ ดังนั้นฉันจึงคิดที่จะสร้างโพสต์ของตัวเองขึ้นมา ฉันไม่ได้ตั้งใจที่จะตอบคำถามของ OP ทั้งหมด แต่ฉันต้องการชี้ให้เห็น ความแตกต่างระหว่าง IQueryable และ IEnumerable เมื่อใช้ LINQ กับ SQL

ฉันสร้างโครงสร้างต่อไปนี้ใน DB (สคริปต์ DDL):

CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)

นี่คือสคริปต์การแทรกเรคคอร์ด (สคริปต์ DML):

INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO

ตอนนี้เป้าหมายของฉันคือการได้รับ 2 อันดับแรกจากตาราง Employee ในฐานข้อมูล ดังนั้นฉันจึงเพิ่มรายการ ADO.NET Entity Data Model ลงในแอปพลิเคชันคอนโซลของฉันโดยชี้ไปที่ตาราง Employee ในฐานข้อมูลของฉัน และเริ่มเขียนแบบสอบถาม LINQ

รหัสสำหรับเส้นทาง IQueryable:

using (var efContext = new EfTestEntities())
{
    IQueryable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

เมื่อฉันเริ่มรันโปรแกรมนี้ ฉันได้เริ่มเซสชันของตัวสร้างโปรไฟล์ SQL Query บนอินสแตนซ์ SQL Server ของฉันด้วย และนี่คือบทสรุปของการดำเนินการ:

  1. จำนวนคำค้นหาทั้งหมดที่ถูกเรียกใช้: 1
  2. ข้อความค้นหา: SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]

เพียงแต่ IQueryable นั้นฉลาดพอที่จะใช้ส่วนคำสั่ง Top (2) บนฝั่งเซิร์ฟเวอร์ฐานข้อมูลเอง ดังนั้นจึงนำเพียง 2 จาก 5 ระเบียนผ่านทางสาย ไม่จำเป็นต้องกรองในหน่วยความจำเพิ่มเติมใดๆ ในฝั่งคอมพิวเตอร์ไคลเอนต์

รหัสสำหรับเส้นทาง IEnumerable:

using (var efContext = new EfTestEntities())
{
    IEnumerable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

สรุปการดำเนินการในกรณีนี้:

  1. จำนวนคำค้นหาทั้งหมดที่ถูกเรียกใช้: 1
  2. ข้อความค้นหาที่บันทึกในตัวสร้างโปรไฟล์ SQL: SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]

ตอนนี้สิ่งที่ IEnumerable นำระเบียนทั้งหมด 5 รายการที่มีอยู่ในตาราง Salary จากนั้นดำเนินการกรองในหน่วยความจำบนคอมพิวเตอร์ไคลเอนต์เพื่อให้ได้ 2 ระเบียนสูงสุด ดังนั้นข้อมูลเพิ่มเติม (บันทึกเพิ่มเติม 3 รายการในกรณีนี้) จึงถูกถ่ายโอนผ่านทางสายโดยไม่จำเป็น

person RBT    schedule 26.04.2017
comment
ขอบคุณ แต่ฉันไม่คิดว่าคำตอบของ @ gunny229 จะทำให้เข้าใจผิดอยู่แล้ว ใช่เขาใช้คำว่า 'แบบสอบถาม' แต่นั่นไม่ได้อยู่ในบริบทของฐานข้อมูล มันเป็นเพียงการคำนวณอื่นเพื่อให้ได้สองอันดับแรก อย่างน้อยนั่นคือสิ่งที่ฉันคิดเมื่ออ่านมัน ไชโย - person Ε Г И І И О; 06.12.2019

IQueryable, IList, IDictionary, ICollection สืบทอดอินเทอร์เฟซ IEnumerable อินเทอร์เฟซทั้งหมดของการรวบรวมประเภทจะสืบทอดอินเทอร์เฟซ IEnumerable

ความแตกต่างระหว่าง IEnumerable และ IQueryable IEnumerable:-เมื่อคุณเรียกใช้แบบสอบถามซึ่งส่งคืนประเภท IEnumerable IEnumerable จะดำเนินการแบบสอบถามแรกก่อนแล้วจึงดำเนินการแบบสอบถามย่อยที่เขียนขึ้นสำหรับแบบสอบถามนั้น

ตัวอย่าง:-หากคุณต้องการได้รับบันทึกประชากร 10 อันดับแรกจากประเทศใดประเทศหนึ่ง ข้อความค้นหาที่เราจะใช้ใน LinQ คือ

IEnumerable _Population=จาก s ในอินเดีย เลือก s.population;//แบบสอบถามแรก _Population=_Population.take(10);//แบบสอบถามที่สอง

ตอนนี้ถ้าเราดำเนินการแบบสอบถามนี้ แบบสอบถามแรกจะถูกดำเนินการก่อน IEnumerable จะได้รับบันทึกของประชากรทั้งหมดจากเซิร์ฟเวอร์ sql จากนั้นจะจัดเก็บข้อมูลไว้ในหน่วยความจำในกระบวนการ จากนั้นจึงดำเนินการประชากร 10 อันดับแรกในแบบสอบถามถัดไป (การดำเนินการเกิดขึ้นสองครั้งบนเซิร์ฟเวอร์ sql)

หากเราดำเนินการค้นหาเดียวกันโดยใช้ IQueryable

IQueryable _Population=จาก s ในอินเดีย เลือก s.population;//แบบสอบถามแรก _Population=_Population.take(10);//แบบสอบถามที่สอง

ใน IQueryable นี้ จะดำเนินการ 2 Query พร้อมกันในแง่ที่ว่าจะได้รับประชากรที่อยู่ใน 10 อันดับแรกใน Query เดียว แทนที่จะรับข้อมูลและกรอง 10 อันดับแรกอีกครั้ง (ดำเนินการครั้งเดียวบนเซิร์ฟเวอร์ sql) .

บทสรุปสำหรับ IQueryable และ IEnumerable

  1. หากคุณกำลังเขียนแบบสอบถามกับข้อมูลในฐานข้อมูล ให้ใช้ IQueryable
  2. หากคุณกำลังสืบค้นข้อมูลที่กำลังดำเนินการอยู่ ให้ใช้ IEnumerable IEnumerable มีเมธอด GetEnumerator(),Current() และ MoveNext()
person gunny 229    schedule 23.03.2015
comment
ดีจริงๆที่ทราบความแตกต่าง (ญ) - person Wasim Bajwa; 27.03.2017
comment
วิธีการขยาย Take ถูกกำหนดไว้ที่ IEnumerable<T> แทน ฉันตรวจสอบแล้วว่าข้อความค้นหา เพียง 1 เท่านั้นที่เริ่มทำงานในทั้งสองกรณี ไม่ว่าจะเป็น IEnumerable หรือ IQueryable เป็นเพียงการที่ IEnumerable ทำการกรองในหน่วยความจำซึ่งนำข้อมูลที่ไม่ต้องการมาผ่านสาย - person RBT; 26.04.2017