ICollection <T> Vs List <T> ใน Entity Framework


116

ฉันดูเว็บคาสต์เพียงไม่กี่รายการก่อนที่จะเริ่มออกแบบแอปพลิเคชัน Entity Framework สองสามรายการก่อน ฉันไม่ได้อ่านเอกสารมากขนาดนั้นจริงๆและฉันรู้สึกว่าตอนนี้ฉันกำลังทุกข์ใจ

ฉันใช้List<T>ในชั้นเรียนของฉันและได้ผลดีมาก

ICollection<T>ตอนนี้ผมต้องอ่านเอกสารบางและมันระบุว่าฉันควรจะได้รับการใช้ ฉันเปลี่ยนเป็นสิ่งนี้และมันไม่ได้ทำให้บริบทของโมเดลเปลี่ยนไปด้วยซ้ำ นี่เป็นเพราะทั้งสองอย่างList<T>และICollection<T>สืบทอดIEnumerable<T>และนั่นคือสิ่งที่จำเป็นสำหรับ EF จริงหรือ?

แต่ถ้าเป็นกรณีนี้ทำไมไม่รัฐเอกสาร EF ว่ามันต้องIEnumerable<T>แทนICollection<T>?

ไม่ว่าในกรณีใดมีข้อเสียของสิ่งที่ฉันทำหรือฉันควรเปลี่ยนแปลงหรือไม่?

คำตอบ:


114

Entity Framework จะใช้ICollection<T>เนื่องจากต้องการสนับสนุนAddการดำเนินการซึ่งไม่ได้เป็นส่วนหนึ่งของIEnumerable<T>อินเทอร์เฟซ

โปรดทราบว่าคุณกำลังใช้ICollection<T>งานคุณเพียงแค่เปิดเผยว่าเป็นการList<T>ใช้งานเท่านั้น List<T>นำไปพร้อมกับมันIList<T>, และICollection<T>IEnumerable<T>

สำหรับการเปลี่ยนแปลงของคุณการเปิดเผยผ่านอินเทอร์เฟซเป็นทางเลือกที่ดีแม้ว่าจะList<T>ใช้งานได้ อินเทอร์เฟซกำหนดสัญญา แต่ไม่ใช่การนำไปใช้ การใช้งานอาจเปลี่ยนแปลงได้ ในบางกรณีการใช้งานอาจเป็นHashSet<T>ตัวอย่างเช่น (นี่เป็นความคิดที่คุณสามารถใช้ได้มากกว่า Entity Framework โดยวิธีการปฏิบัติเชิงวัตถุที่ดีคือการเขียนโปรแกรมไปยังอินเทอร์เฟซไม่ใช่การนำไปใช้งานการปรับใช้สามารถและจะเปลี่ยนแปลงได้)


2
ดังนั้น .... เพื่อให้ฉันเข้าใจเพิ่มเติมเล็กน้อย - List สืบทอด IList ซึ่งสืบทอด ICollection ซึ่งสืบทอด IEnumerable?
Wil

3
ใช่นั่นคือโซ่ List<T>มีการดำเนินการในแต่ละของการเชื่อมต่อเหล่านั้น ( IList<T>, ICollection<T>, IEnumerable<T>) เพราะลำดับชั้นมรดก สำหรับการก่อสร้างแล้วเสร็จIList<T>ยังหยิบไม่ทั่วไปIList, ICollectionและIEnumerableอินเตอร์เฟซ
Anthony Pegram

ขอบคุณ ... คุณสมบัติบางอย่างของ Ixxx ยังคงหนีไม่พ้นความเข้าใจของฉัน! คุณมีเหตุผลอย่างไรก็ตามสิ่งสุดท้ายที่ทำให้ฉันรำคาญถ้า Ixx ของ Ixx ตัวอื่นสืบทอด IEnumerable มันจะเพิ่มไปยัง IEnumerable ได้อย่างไรถ้า Ienumerable อ่านอย่างเดียว ... ถ้ามันซับซ้อนเกินไปไม่ต้องกังวลเมื่อฉันมีเวลาสักหน่อยฉันจะพยายามยิงตัวสะท้อนแสง!
Wil

10
การดำเนินการ Linq ปกติจะไม่เพิ่มหรือกลายพันธุ์สิ่งต่าง ๆ เพียงแค่กรองจัดกลุ่มโปรเจ็กต์ ฯลฯ ลำดับไปข้างหน้าอย่างเดียวอ่านอย่างเดียวเป็นสิ่งที่จำเป็นในการสนับสนุนการดำเนินการเหล่านั้น เมื่อคุณมีผู้ให้บริการ Linq เช่น Entity Framework ที่เกี่ยวข้องกับการคงอยู่ของข้อมูลความสามารถในการเพิ่มเป็นประโยชน์อย่างมากที่ต้องใช้อินเทอร์เฟซที่หนักกว่าซึ่งเป็นสิ่งที่เชิญชวนICollection<T>ให้เข้าร่วมปาร์ตี้ (และอินเทอร์เฟซนี้มาพร้อมกับมันIEnumerable<T>ดังนั้น "ปกติ "การดำเนินการ Linq ยังคงใช้ได้)
Anthony Pegram

@AnthonyPegram: ฉันคิดว่ามันไม่ถูกต้องอย่างยิ่งที่จะบอกว่าต้องใช้ทั้งสามอินเทอร์เฟซ เนื่องจาก IList <T> สืบทอด ICollection <T> ซึ่งสืบทอด IEnumerable <T> จึงเพียงพอสำหรับ List <T> ที่จะใช้ IList <T>
CJ7

51

พวกเขาเลือกอินเทอร์เฟซที่พวกเขาทำเพราะมันให้ความเป็นนามธรรมที่เข้าใจได้มากกว่าคำค้นหาเวทย์มนตร์ที่ Entity Framework ดำเนินการเมื่อคุณใช้ Linq

นี่คือความแตกต่างระหว่างอินเทอร์เฟซ:

  • IEnumerable<T> เป็นแบบอ่านอย่างเดียว
  • คุณสามารถเพิ่มและลบรายการในไฟล์ ICollection<T>
  • คุณสามารถเข้าถึงโดยสุ่ม (โดยดัชนี) ไปยังไฟล์ List<T>

จากสิ่งเหล่านั้นICollectionและIEnumerableแมปได้ดีกับการดำเนินการฐานข้อมูลเนื่องจากการสอบถามและการเพิ่ม / การลบเอนทิตีเป็นสิ่งที่คุณอาจทำได้ในฐานข้อมูล

การเข้าถึงแบบสุ่มโดยดัชนีจะไม่แมปเช่นกันเนื่องจากคุณต้องมีผลการสืบค้นที่มีอยู่แล้วจึงจะวนซ้ำได้ไม่เช่นนั้นการเข้าถึงแบบสุ่มแต่ละครั้งจะสืบค้นฐานข้อมูลอีกครั้ง แผนที่ดัชนีจะเป็นอย่างไร หมายเลขแถว? มีแบบสอบถามหมายเลขแถวไม่มากนักที่คุณต้องการทำและไม่มีประโยชน์เลยในการสร้างคำค้นหาที่ใหญ่ขึ้น ดังนั้นพวกเขาจึงไม่สนับสนุน

ICollection<T> ได้รับการสนับสนุนและจะช่วยให้คุณสามารถค้นหาและเปลี่ยนแปลงข้อมูลได้ดังนั้นให้ใช้สิ่งนั้น

เหตุผลList<T>ที่เริ่มต้นได้ก็คือเนื่องจากการใช้งาน EF จะส่งกลับมาในตอนท้าย แต่นั่นคือส่วนท้ายของห่วงโซ่การสืบค้นไม่ใช่ที่จุดเริ่มต้น ดังนั้นการสร้างคุณสมบัติของคุณICollection<T>จะทำให้ชัดเจนยิ่งขึ้นว่า EF สร้าง SQL จำนวนมากและส่งคืนเฉพาะList<T>ส่วนท้ายแทนที่จะทำแบบสอบถามสำหรับ Linq แต่ละระดับที่คุณใช้


8

ICollection แตกต่างจาก IEnumerable ตรงที่คุณสามารถเพิ่มไอเท็มลงในคอลเลคชันได้ในขณะที่ IEnumerable คุณไม่สามารถทำได้ ตัวอย่างเช่นในชั้นเรียน POCO ของคุณคุณต้องการใช้ ICollection หากคุณต้องการอนุญาตให้เพิ่มคอลเล็กชันเข้าไป ทำให้ ICollection เสมือนจริงเพื่อประโยชน์จากการโหลดที่ขี้เกียจเกินไป


1
ฉันต้องการที่จะเข้าใจ - คุณสามารถดำเนินการแบบเดียวกัน (และอื่น ๆ อีกมากมาย!) ด้วยรายการ <T> ทำไม ICollection <T>? ทำไมไม่ List <T>? ดูเรียบง่ายและมีประสิทธิภาพมากขึ้น
monstro

รายการ <T> ใช้ ICollection และ IEnumerable การทำงานที่มากขึ้น แต่ด้วยค่าใช้จ่ายที่มากขึ้น
IronAces

4

แม้ว่าคำถามจะถูกโพสต์ไปหลายปีแล้ว แต่ก็ยังใช้ได้เมื่อมีคนมองหาสถานการณ์เดียวกัน

มีที่ผ่านมา [2015] บทความ CodeProject ซึ่งจะอธิบายความแตกต่างในรายละเอียดมากและแสดงกราฟิกด้วยคือโค้ดตัวอย่าง ไม่ได้เน้นที่ EF โดยตรง แต่ยังหวังว่ามันจะช่วยได้มากขึ้น:

List vs IEnumerable vs IQueryable vs ICollection vs IDictionary

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.