การติดตามแบบไม่มีอะไรแตกต่างกัน ()


228

ฉันมีคำถามเกี่ยวกับ.AsNoTracking()ส่วนขยายเนื่องจากทั้งหมดค่อนข้างใหม่และค่อนข้างสับสน

ฉันใช้บริบทสำหรับคำขอต่อเว็บไซต์

เอนทิตีจำนวนมากของฉันไม่เปลี่ยนแปลงดังนั้นจึงไม่จำเป็นต้องถูกติดตาม แต่ฉันมีสถานการณ์ต่อไปนี้ที่ฉันไม่แน่ใจว่ากำลังจะไปยังฐานข้อมูลหรือแม้ว่ามันจะสร้างความแตกต่างในกรณีนี้

ตัวอย่างนี้คือสิ่งที่ฉันกำลังทำอยู่:

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

นี่เป็นเหมือนข้างต้น แต่การลบออก.AsNoTracking()จากขั้นตอนที่ 1:

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

ขั้นตอนที่ 1 & 2 ใช้บริบทเดียวกัน แต่เกิดขึ้นในเวลาที่ต่างกัน สิ่งที่ฉันไม่สามารถทำได้คือมีความแตกต่างหรือไม่ เนื่องจากขั้นตอนที่ 2 เป็นการอัปเดตฉันคาดว่าทั้งคู่จะตีฐานข้อมูลสองครั้ง

มีใครบอกฉันได้ไหมว่าความแตกต่างคืออะไร

คำตอบ:


187

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


1
เราจะได้รับสิทธิประโยชน์แบบเดียวกันสำหรับคลาสที่ไม่ระบุชื่อในแบบสอบถามแบบใช้เลือกข้อมูลเช่นบริบทผู้ใช้เลือก (u => ใหม่ {ชื่อ = u.Name}) ได้หรือไม่ ขอบคุณ
Dilhan Jayathilake

6
@DilhanJayathilake: คลาสที่ไม่ระบุตัวตนไม่ได้เป็นตัวแทนของนิติบุคคลดังนั้นพวกเขาจึงไม่มีการติดตาม
Ladislav Mrnka

1
เนื่องจาก EF6 infers คีย์เอนทิตีอย่างไม่ถูกต้องในมุมมอง AsNoTracking () จะเพิกเฉยต่อคีย์ดังนั้นจึงเป็นทางเลือกในการแก้ไขคีย์ด้วยตนเอง (สมมติว่าไม่จำเป็นต้องใช้ประโยชน์อื่น ๆ ของคีย์)
crokusek

4
นอกจากนี้โปรดทราบว่าผลที่ใหญ่ที่สุดที่ AsNoTracking มีคือการโหลดแบบขี้เกียจจะใช้ไม่ได้
Douglas Gaskell

170

ดูหน้านี้Entity Framework และ AsNoTracking

สิ่งที่ไม่มีการติดตาม

Entity Framework เปิดเผยตัวเลือกการปรับแต่งประสิทธิภาพจำนวนหนึ่งเพื่อช่วยให้คุณปรับประสิทธิภาพการทำงานของแอพพลิเคชั่นได้อย่างเหมาะสม .AsNoTracking()หนึ่งในตัวเลือกการปรับแต่งเหล่านี้คือ การเพิ่มประสิทธิภาพนี้ช่วยให้คุณสามารถบอกEntity Frameworkไม่ให้ติดตามผลลัพธ์ของแบบสอบถาม ซึ่งหมายความว่าEntity Frameworkไม่มีการดำเนินการเพิ่มเติมหรือการเก็บข้อมูลของเอนทิตีที่ถูกส่งกลับโดยแบบสอบถาม อย่างไรก็ตามก็หมายความว่าคุณไม่สามารถอัปเดตเอนทิตีเหล่านี้ได้โดยไม่ต้องติดตั้งลงในกราฟติดตามอีกครั้ง

มีการเพิ่มประสิทธิภาพอย่างมีนัยสำคัญโดยใช้ AsNoTracking


11
ดูเหมือนว่าผลกำไรอาจมีการยกบางครั้ง: stackoverflow.com/questions/9259480/…
Fabrice

3
ประสิทธิภาพการทำงานของฉันเพิ่มขึ้นด้วยข้อความค้นหาที่ซับซ้อนที่กำลังโหลดความสัมพันธ์ย่อยกับผู้ปกครองในหนึ่งขั้นตอนคือประมาณ 50%
Karl

53

ไม่มีการติดตาม LINQ ไปยังข้อความค้นหาเอนทิตี

ขอแนะนำให้ใช้การใช้ AsNoTracking () เมื่อการสืบค้นของคุณมีความหมาย ในสถานการณ์เหล่านี้คุณจะได้รับเอนทิตีของคุณ แต่ไม่ได้ถูกติดตามโดยบริบทของคุณซึ่งจะทำให้มั่นใจได้ว่าการใช้หน่วยความจำน้อยที่สุดและประสิทธิภาพที่ดีที่สุด

ข้อดี

  1. ปรับปรุงประสิทธิภาพมากกว่าการสืบค้น LINQ ปกติ
  2. วัตถุที่ปรากฏอย่างสมบูรณ์
  3. ง่ายที่สุดในการเขียนด้วยไวยากรณ์ที่สร้างขึ้นในภาษาการเขียนโปรแกรม

จุดด้อย

  1. ไม่เหมาะสำหรับการใช้งาน CUD
  2. ข้อ จำกัด ทางเทคนิคบางอย่างเช่น: รูปแบบที่ใช้ DefaultIfEmpty for OUTER JOIN แบบสอบถามส่งผลให้เกิดแบบสอบถามที่ซับซ้อนกว่าคำสั่ง OUTER JOIN ง่าย ๆ ใน Entity SQL
  3. คุณยังไม่สามารถใช้ LIKE กับการจับคู่รูปแบบทั่วไป

ข้อมูลเพิ่มเติมสามารถดูได้ที่นี่:

ข้อควรพิจารณาด้านประสิทธิภาพสำหรับ Entity Framework

Entity Framework และ NoTracking


34

การปิดใช้งานการติดตามจะทำให้ชุดผลลัพธ์ของคุณสตรีมไปยังหน่วยความจำ สิ่งนี้มีประสิทธิภาพมากขึ้นเมื่อคุณทำงานกับชุดข้อมูลจำนวนมากและไม่ต้องการชุดข้อมูลทั้งหมดพร้อมกัน

อ้างอิง:


10

AsNoTracking () อนุญาตให้ใช้ข้อกำหนด "คีย์เฉพาะต่อเรคคอร์ด" ใน EF เพื่อข้าม (ไม่ได้ระบุอย่างชัดเจนโดยคำตอบอื่น ๆ )

สิ่งนี้มีประโยชน์อย่างมากเมื่ออ่านมุมมองที่ไม่สนับสนุนคีย์ที่ไม่ซ้ำกันเนื่องจากบางฟิลด์อาจเป็นโมฆะหรือลักษณะของมุมมองนั้นไม่สามารถจัดทำดัชนีตามหลักเหตุผลได้

ในกรณีเหล่านี้ "คีย์" สามารถตั้งค่าเป็นคอลัมน์ที่ไม่เป็นโมฆะใด ๆ ได้ แต่ต้องใช้ AsNoTracking () กับทุกแบบสอบถามอื่น ๆ ระเบียน (ที่ซ้ำกันโดยคีย์) จะถูกข้าม


2
เพียงเพื่อย้ำถึงความสำคัญของสิ่งนี้กับ Views ฉันมีคิวรีจากมุมมองที่ส่งกลับ 7 ระเบียนที่ไม่ซ้ำกันเมื่อทำงานผ่าน SSMS เมื่อทำงานผ่าน EF โดยไม่ต้องใช้ตัวแก้ไข AsNoTracking ฉันจะได้รับระเบียนแรกสำเนาที่สองและสามชุดที่สาม นี่ใช้การเกาหัวอย่างไม่น่าเชื่อเพื่อแก้ไขและใช้ AsNoTracking ซึ่งแก้ไขมัน!
Ade

ฉันมีปัญหาเดียวกันนี้เมื่อใช้ Linq กับเอนทิตีในขณะที่ค้นหามุมมองโดยไม่มีคีย์หลัก ค้นพบเฉพาะเกี่ยวกับ AsNoTracking หลังจากผ่านไปครึ่งวันแล้ว โพสต์ฟอรัม ASP.Net นี้ในที่สุดก็พาฉันไป forums.asp.net/t/…
red_dorian

6

หากคุณมีสิ่งอื่นที่แก้ไขฐานข้อมูล (พูดอีกกระบวนการหนึ่ง) และต้องการให้แน่ใจว่าคุณเห็นการเปลี่ยนแปลงเหล่านี้ใช้AsNoTracking()มิฉะนั้น EF อาจให้สำเนาล่าสุดที่บริบทของคุณมีแทนดังนั้นจึงเป็นการดีที่จะใช้บริบทใหม่ทุกแบบสอบถาม :

http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/

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