ความแตกต่างระหว่างIQueryable<T>
และIEnumerable<T>
คืออะไร?
ดูเพิ่มเติมความแตกต่างระหว่าง IQueryable และ IEnumerableที่ทับซ้อนกับคำถามนี้คืออะไร
ความแตกต่างระหว่างIQueryable<T>
และIEnumerable<T>
คืออะไร?
ดูเพิ่มเติมความแตกต่างระหว่าง IQueryable และ IEnumerableที่ทับซ้อนกับคำถามนี้คืออะไร
คำตอบ:
แรกของทุกขยายอินเตอร์เฟซดังนั้นสิ่งที่คุณสามารถทำได้ด้วย "ธรรมดา" คุณยังสามารถทำอะไรกับIQueryable<T>
IEnumerable<T>
IEnumerable<T>
IQueryable<T>
IEnumerable<T>
เพียงแค่มีGetEnumerator()
วิธีการที่ส่งกลับEnumerator<T>
ที่คุณสามารถเรียกมันMoveNext()
วิธีการย้ำถึงลำดับของT
อะไรIQueryable<T>
ได้ว่าIEnumerable<T>
ไม่เป็นสองคุณสมบัติโดยเฉพาะอย่างยิ่งหนึ่งที่ชี้ไปยังผู้ให้บริการแบบสอบถาม (เช่น LINQ เพื่อให้บริการ SQL) และชี้อีกครั้งเพื่อให้การแสดงออกแบบสอบถามที่เป็นตัวแทนของIQueryable<T>
วัตถุเป็นรันไทม์ทะลุต้นไม้ไวยากรณ์นามธรรมที่สามารถ เข้าใจโดยผู้ให้บริการแบบสอบถามที่กำหนด (ส่วนใหญ่คุณไม่สามารถให้ LINQ กับนิพจน์ SQL แก่ผู้ให้บริการ LINQ to Entities ได้โดยไม่มีข้อยกเว้นเกิดขึ้น)
นิพจน์สามารถเป็นนิพจน์คงที่ของวัตถุเองหรือโครงสร้างที่ซับซ้อนมากขึ้นของชุดตัวดำเนินการแบบสอบถามและตัวถูกดำเนินการ ตัวให้บริการแบบสอบถามIQueryProvider.Execute()
หรือIQueryProvider.CreateQuery()
วิธีการที่เรียกว่ามีการแสดงออกผ่านไปแล้วผลIQueryable
ตอบแทนแบบสอบถามหรืออื่นจะถูกส่งกลับตามลำดับ
AsQueryable()
มันจะทำการส่ง enumerable ให้กับ queryable และคืนมันถ้ามันใช้IQueryable
อินเตอร์เฟสหรือไม่ก็มันจะล้อมรอบด้วย a ConstantExpression
ซึ่งถูกอ้างถึงในEnumerableQuery
วัตถุที่ถูกส่งคืน
ข้อแตกต่างหลักคือตัวดำเนินการ LINQ สำหรับIQueryable<T>
นำExpression
วัตถุแทนผู้รับมอบสิทธิ์ซึ่งหมายถึงตรรกะคิวรีแบบกำหนดเองที่ได้รับเช่นตัวเลือกเพรดิเคตหรือตัวเลือกค่าอยู่ในรูปแบบของแผนภูมินิพจน์แทนผู้แทนไปยังวิธีการ
IEnumerable<T>
ดีมากสำหรับการทำงานกับลำดับที่ซ้ำในหน่วยความจำ แต่ IQueryable<T>
ช่วยให้หน่วยความจำไม่เพียงพอเช่นแหล่งข้อมูลระยะไกลเช่นฐานข้อมูลหรือบริการบนเว็บโดยที่การดำเนินการของแบบสอบถามจะถูกดำเนินการ"อยู่ระหว่างดำเนินการ"โดยทั่วไปสิ่งที่จำเป็นต้องมีคือรหัส (เป็นรหัส) เพื่อดำเนินการแต่ละส่วนของแบบสอบถาม
ในกรณีที่การดำเนินการจะดำเนินการนอกกระบวนการตรรกะของแบบสอบถามจะต้องมีการแสดงในข้อมูลเช่นผู้ให้บริการ LINQ สามารถแปลงเป็นรูปแบบที่เหมาะสมสำหรับการดำเนินการออกจากหน่วยความจำ - ไม่ว่าจะเป็นแบบสอบถาม LDAP SQL หรืออะไรก็ตาม
เพิ่มเติมใน:
นี่เป็นวิดีโอที่ดีใน youtubeซึ่งแสดงให้เห็นว่าอินเทอร์เฟซเหล่านี้แตกต่างกันอย่างไรน่าดู
ด้านล่างมีคำตอบยาว ๆ สำหรับคำอธิบาย
จุดสำคัญแรกที่ต้องจดจำคือIQueryable
อินเทอร์เฟซที่สืบทอดมาจากIEnumerable
ดังนั้นสิ่งที่IEnumerable
สามารถทำได้IQueryable
สามารถทำได้
มีความแตกต่างมากมาย แต่ให้เราคุยกันเกี่ยวกับความแตกต่างที่ยิ่งใหญ่ซึ่งทำให้แตกต่างมากที่สุด IEnumerable
อินเตอร์เฟสมีประโยชน์เมื่อโหลดคอลเล็กชันของคุณโดยใช้LINQ
หรือ Framework เอนทิตีและคุณต้องการใช้ตัวกรองกับคอลเลกชัน
พิจารณารหัสง่าย ๆ ด้านล่างซึ่งใช้IEnumerable
กับกรอบงานเอนทิตี มันใช้Where
ตัวกรองที่จะได้รับการบันทึกที่มีคือEmpId
2
EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
ที่นี่ตัวกรองจะถูกดำเนินการในฝั่งไคลเอ็นต์ที่เป็นIEnumerable
รหัส ในคำอื่น ๆ ข้อมูลทั้งหมดจะถูกดึงข้อมูลจากฐานข้อมูลแล้วที่ลูกค้าสแกนและได้รับการบันทึกด้วยมีEmpId
2
แต่ตอนนี้ดูโค้ดด้านล่างนี้เรามีการเปลี่ยนแปลงไปIEnumerable
IQueryable
มันสร้างแบบสอบถาม SQL ที่ฝั่งเซิร์ฟเวอร์และข้อมูลที่จำเป็นเท่านั้นที่ถูกส่งไปยังฝั่งไคลเอ็นต์
EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
ดังนั้นความแตกต่างระหว่างIQueryable
และIEnumerable
เป็นเรื่องเกี่ยวกับที่ดำเนินการตรรกะตัวกรอง หนึ่งรันบนฝั่งไคลเอ็นต์และอีกหนึ่งรันบนฐานข้อมูล
ดังนั้นหากคุณทำงานกับการเก็บรวบรวมข้อมูลในหน่วยความจำเท่านั้นIEnumerable
เป็นตัวเลือกที่ดี แต่ถ้าคุณต้องการสืบค้นข้อมูลที่เชื่อมต่อกับฐานข้อมูล `` IQueryable เป็นตัวเลือกที่ดีกว่าเพราะช่วยลดปริมาณการใช้งานเครือข่ายและใช้ภาษา SQL
IEnumerable: IEnumerable เหมาะสมที่สุดสำหรับการทำงานกับการรวบรวมในหน่วยความจำ (หรือแบบสอบถามแบบโลคัล) IEnumerable ไม่ย้ายระหว่างรายการมันเป็นเพียงการรวบรวมเท่านั้น
IQueryable: เหมาะสมที่สุดกับ IQueryable สำหรับแหล่งข้อมูลระยะไกลเช่นฐานข้อมูลหรือบริการบนเว็บ (หรือข้อความค้นหาระยะไกล) IQueryable เป็นคุณสมบัติที่ทรงพลังมากที่ช่วยให้สถานการณ์การดำเนินการรอการตัดบัญชีที่น่าสนใจหลากหลาย (เช่นการสอบถามเพจและการเรียงตามองค์ประกอบ)
ดังนั้นเมื่อคุณต้องทำซ้ำผ่านคอลเลกชันในหน่วยความจำให้ใช้ IEnumerable หากคุณต้องการจัดการกับคอลเลกชันเช่นชุดข้อมูลและแหล่งข้อมูลอื่น ๆ ให้ใช้ IQueryable
ในคำง่าย ๆ ความแตกต่างที่สำคัญอื่น ๆ คือ IEnumerable เรียกใช้แบบสอบถามแบบใช้เลือกข้อมูลในฝั่งเซิร์ฟเวอร์โหลดข้อมูลในหน่วยความจำในฝั่งไคลเอ็นต์แล้วกรองข้อมูลในขณะที่ IQueryable เรียกใช้แบบสอบถามแบบใช้เลือกข้อมูลบนฝั่งเซิร์ฟเวอร์พร้อมตัวกรองทั้งหมด
ในชีวิตจริงถ้าคุณใช้ ORM เช่น LINQ-to-SQL
ในทั้งสองกรณีหากคุณไม่ได้โทรหา A ToList()
หรือToArray()
แบบสอบถามจะถูกดำเนินการทุกครั้งที่มีการใช้งานดังนั้นคุณจะต้องIQueryable<T>
กรอกข้อมูลลงในกล่องรายการ 4 รายการจากนั้นแบบสอบถามจะทำงานกับฐานข้อมูล 4 ครั้ง
นอกจากนี้หากคุณขยายขอบเขตการค้นหาของคุณ:
q.Where(x.name = "a").ToList()
จากนั้นด้วย IQueryable SQL ที่สร้างขึ้นจะมี“ โดยที่ name =“ a” แต่ด้วย IEnumerable บทบาทอีกมากมายจะถูกดึงกลับมาจากฐานข้อมูลจากนั้นการตรวจสอบ x.name =“ a” จะดำเนินการโดย. NET
IEnumerable อ้างถึงคอลเล็กชัน แต่ IQueryable เป็นเพียงแบบสอบถามและจะถูกสร้างขึ้นภายใน Expression Tree เราจะเรียกใช้แบบสอบถามนี้เพื่อรับข้อมูลจากฐานข้อมูล
ด้านล่างทดสอบขนาดเล็กพูดถึงอาจจะช่วยให้คุณเข้าใจแง่มุมหนึ่งของความแตกต่างระหว่างและIQueryable<T>
IEnumerable<T>
ฉันทำซ้ำคำตอบนี้จากโพสต์นี้ที่ฉันพยายามเพิ่มการแก้ไขในโพสต์ของคนอื่น
ฉันสร้างโครงสร้างต่อไปนี้ใน 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 ของฉันและนี่คือบทสรุปของการดำเนินการ:
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);
}
}
บทสรุปของการดำเนินการในกรณีนี้:
SELECT [Extent1].[Salary] AS [Salary]
FROM [dbo].[Employee] AS [Extent1]
ตอนนี้สิ่งที่IEnumerable
นำระเบียนทั้ง 5 อยู่ในSalary
ตารางแล้วทำการกรองในหน่วยความจำบนคอมพิวเตอร์ไคลเอนต์เพื่อรับระเบียน 2 อันดับแรก ดังนั้นข้อมูลเพิ่มเติม (3 บันทึกเพิ่มเติมในกรณีนี้) จึงถูกโอนผ่านสายโดยไม่จำเป็น
นี่คือสิ่งที่ฉันเขียนในโพสต์ที่คล้ายกัน (ในหัวข้อนี้) (และไม่ฉันมักจะไม่พูดเอง แต่บทความเหล่านี้เป็นบทความที่ดีมาก)
"บทความนี้จะเป็นประโยชน์: IQueryable VS IEnumerable ใน LINQ
การอ้างอิงบทความนั้น 'ตามเอกสาร MSDN การเรียกใช้งาน IQueryable จะดำเนินการโดยสร้างแผนผังนิพจน์ภายในแทน "วิธีการเหล่านี้ที่ขยาย IQueryable (Of T) ไม่ทำการสืบค้นใด ๆ โดยตรง แต่หน้าที่การใช้งานของพวกเขาคือการสร้างวัตถุ Expression ซึ่งเป็นทรีนิพจน์ที่แสดงถึงแบบสอบถามแบบสะสม" '
ต้นไม้ Expression เป็นโครงสร้างที่สำคัญมากใน C # และบนแพลตฟอร์ม. NET (สิ่งเหล่านี้มีความสำคัญโดยทั่วไป แต่ C # ทำให้มีประโยชน์มาก) เพื่อให้เข้าใจถึงความแตกต่างได้ดียิ่งขึ้นฉันขอแนะนำให้อ่านเกี่ยวกับความแตกต่างระหว่างนิพจน์และข้อความ ในข้อกำหนด C # 5.0 อย่างเป็นทางการที่นี่ สำหรับแนวคิดทางทฤษฎีขั้นสูงที่แยกเป็นแคลคูลัสแลมบ์ดานิพจน์ช่วยให้การสนับสนุนวิธีการเป็นวัตถุชั้นหนึ่ง ความแตกต่างระหว่าง IQueryable และ IEnumerable นั้นมีศูนย์กลางอยู่ที่จุดนี้ IQueryable สร้าง tree expression ในขณะที่ IEnumerable ไม่ได้อย่างน้อยก็ไม่ได้อยู่ในเงื่อนไขทั่วไปสำหรับพวกเราที่ไม่ทำงานในห้องปฏิบัติการลับของ Microsoft
นี่เป็นอีกบทความที่มีประโยชน์มากที่ให้รายละเอียดความแตกต่างจากมุมมองแบบพุชกับแบบดึง (โดย "push" กับ "pull" ฉันหมายถึงทิศทางของการไหลของข้อมูลเทคนิคการเขียนโปรแกรมแบบโต้ตอบสำหรับ. NET และ C #
นี่เป็นบทความที่ดีมากที่ให้รายละเอียดความแตกต่างระหว่างคำสั่ง lambdas และ lambdas การแสดงออกและกล่าวถึงแนวคิดของการแสดงออกของการแสดงออกในเชิงลึกยิ่งขึ้น: การเยี่ยมชมผู้แทน C #, ต้นไม้แสดงออกและการแสดงออก lambda ."
เราใช้IEnumerable
และIQueryable
จัดการข้อมูลที่ดึงมาจากฐานข้อมูล IQueryable
สืบทอดมาจากIEnumerable
ดังนั้นจึงIQueryable
มีIEnumerable
คุณสมบัติทั้งหมด ข้อแตกต่างที่สำคัญระหว่างIQueryable
และIEnumerable
คือIQueryable
เรียกใช้งานแบบสอบถามด้วยตัวกรองในขณะที่IEnumerable
เรียกใช้แบบสอบถามก่อนแล้วจึงกรองข้อมูลตามเงื่อนไข
ค้นหาความแตกต่างของรายละเอียดเพิ่มเติมด้านล่าง:
IEnumerable
IEnumerable
มีอยู่ในSystem.Collections
เนมสเปซIEnumerable
ดำเนินการแบบสอบถามแบบใช้เลือกข้อมูลในฝั่งเซิร์ฟเวอร์โหลดข้อมูลในหน่วยความจำบนฝั่งไคลเอ็นต์จากนั้นกรองข้อมูลIEnumerable
เหมาะสำหรับการสืบค้นข้อมูลจากการรวบรวมในหน่วยความจำเช่น List, ArrayIEnumerable
มีประโยชน์สำหรับ LINQ to Object และ LINQ to XML queryIQueryable
IQueryable
มีอยู่ในSystem.Linq
เนมสเปซIQueryable
ดำเนินการ 'เลือกแบบสอบถาม' บนฝั่งเซิร์ฟเวอร์พร้อมตัวกรองทั้งหมดIQueryable
เหมาะสำหรับการสืบค้นข้อมูลจากหน่วยความจำนอก (เช่นฐานข้อมูลระยะไกลบริการ)IQueryable
มีประโยชน์สำหรับ LINQ กับการสืบค้น SQLดังนั้นIEnumerable
โดยทั่วไปจะใช้สำหรับจัดการกับการรวบรวมในหน่วยความจำในขณะที่IQueryable
โดยทั่วไปจะใช้เพื่อจัดการกับคอลเลกชัน
ทั้ง IEnumerable และ IQueryable นั้นใช้สำหรับเก็บข้อมูลและทำการดำเนินการจัดการข้อมูลเช่นการกรองในการรวบรวมข้อมูล ที่นี่คุณสามารถค้นหาความแตกต่างที่ดีที่สุดพร้อมตัวอย่าง http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html
IQueryable เร็วกว่า IEnumerable ถ้าเราจัดการกับข้อมูลจำนวนมากจากฐานข้อมูลเพราะ IQueryable จะได้รับเฉพาะข้อมูลที่ต้องการจากฐานข้อมูลที่ IEnumerable ได้รับข้อมูลทั้งหมดโดยไม่คำนึงถึงความจำเป็นจากฐานข้อมูล
ienumerable: เมื่อเราต้องการจัดการกับหน่วยความจำ inprocess เช่นไม่มี dataconnection iqueryable: เมื่อต้องจัดการกับ sql server, เช่นการเชื่อมต่อ data ilist: การดำเนินการเพิ่มวัตถุลบวัตถุ ฯลฯ