Có gì khác biệt .AsNoTracking () tạo ra?


228

Tôi có một câu hỏi liên quan đến .AsNoTracking()phần mở rộng, vì đây là tất cả khá mới và khá khó hiểu.

Tôi đang sử dụng bối cảnh theo yêu cầu cho một trang web.

Rất nhiều thực thể của tôi không thay đổi nên không cần phải theo dõi, nhưng tôi có kịch bản sau đây khi tôi không chắc chắn về những gì sẽ đến cơ sở dữ liệu, hoặc thậm chí liệu nó có tạo ra sự khác biệt trong trường hợp này hay không.

Ví dụ này là những gì tôi đang làm:

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

Điều này giống như trên nhưng loại bỏ .AsNoTracking()khỏi Bước 1:

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

Bước 1 & 2 sử dụng cùng một bối cảnh nhưng xảy ra ở những thời điểm khác nhau. Những gì tôi không thể làm việc là liệu có sự khác biệt nào không. Vì Bước 2 là một bản cập nhật, tôi đoán cả hai sẽ tấn công cơ sở dữ liệu hai lần.

Bất cứ ai có thể cho tôi biết sự khác biệt là gì?

Câu trả lời:


187

Sự khác biệt là trong trường hợp đầu tiên, người dùng được truy xuất không được theo dõi theo ngữ cảnh nên khi bạn định lưu người dùng trở lại cơ sở dữ liệu, bạn phải đính kèm và đặt trạng thái chính xác của người dùng để EF biết rằng nên cập nhật người dùng hiện tại thay vì chèn một cái mới. Trong trường hợp thứ hai, bạn không cần phải làm điều đó nếu bạn tải và lưu người dùng với cùng một ngữ cảnh vì cơ chế theo dõi xử lý việc đó cho bạn.


1
Chúng ta có thể nhận được lợi ích tương tự cho các lớp ẩn danh trong truy vấn chọn không, chẳng hạn như bối cảnh. Người dùng. Chọn (u => new {Name = u.Name})? Cảm ơn.
Dilhan Jayathilake

6
@DilhanJayathilake: Các lớp ẩn danh không đại diện cho chính thực thể để họ không theo dõi.
Ladislav Mrnka

1
Do đôi khi EF6 xâm nhập khóa thực thể không chính xác vào Chế độ xem, nên AsNoTracking () bỏ qua khóa và do đó thay thế cho việc sửa khóa thủ công (giả sử không cần các lợi ích khác của khóa).
crokusek

4
Cũng lưu ý, ảnh hưởng lớn nhất mà AsNoTracking mang lại là việc tải lười biếng sẽ không hoạt động
Douglas Gaskell

170

xem trang này Entity Framework và AsNoTracking

Những gì AsNoTracking làm

Entity Framework hiển thị một số tùy chọn điều chỉnh hiệu suất để giúp bạn tối ưu hóa hiệu suất của các ứng dụng của mình. Một trong những tùy chọn điều chỉnh là .AsNoTracking(). Tối ưu hóa này cho phép bạn nói Entity Frameworkkhông theo dõi kết quả của một truy vấn. Điều này có nghĩa là Entity Frameworkthực hiện không xử lý bổ sung hoặc lưu trữ các thực thể được truy vấn trả về. Tuy nhiên, điều đó cũng có nghĩa là bạn không thể cập nhật các thực thể này mà không gắn lại chúng vào biểu đồ theo dõi.

có những mức tăng hiệu suất đáng kể để có được bằng cách sử dụng AsNoTracking


11
Có vẻ như mức tăng đôi khi có thể bị đối trọng: stackoverflow.com/questions/9259480/ Khăn
Fabrice

3
Hiệu suất của tôi đạt được với một truy vấn phức tạp tải mối quan hệ cha mẹ con bao gồm trong một bước là khoảng 50%
Karl

53

Không có truy vấn LINQ đến các thực thể

Nên sử dụng AsNoTracking () khi truy vấn của bạn dành cho các hoạt động đọc. Trong các trường hợp này, bạn lấy lại các thực thể của mình nhưng chúng không bị theo dõi bởi ngữ cảnh của bạn. Điều này đảm bảo sử dụng bộ nhớ tối thiểu và hiệu suất tối ưu

Ưu

  1. Cải thiện hiệu suất so với các truy vấn LINQ thông thường.
  2. Vật thể đầy đủ.
  3. Đơn giản nhất để viết với cú pháp được xây dựng trong ngôn ngữ lập trình.

Nhược điểm

  1. Không phù hợp với hoạt động của CUD.
  2. Một số hạn chế kỹ thuật nhất định, chẳng hạn như: Các mẫu sử dụng Default IfEmpty cho các truy vấn OUTER THAM GIA dẫn đến các truy vấn phức tạp hơn các câu lệnh OUTER THAM GIA đơn giản trong Entity SQL.
  3. Bạn vẫn không thể sử dụng THÍCH với khớp mẫu chung.

Thêm thông tin có sẵn ở đây:

Cân nhắc hiệu năng cho Entity Framework

Khung thực thể và Không theo dõi



10

AsNoTracking () cho phép bỏ qua yêu cầu "khóa duy nhất trên mỗi bản ghi" trong EF (không được đề cập rõ ràng bằng các câu trả lời khác).

Điều này cực kỳ hữu ích khi đọc Chế độ xem không hỗ trợ khóa duy nhất vì có thể một số trường là không thể hoặc bản chất của chế độ xem không thể lập chỉ mục một cách hợp lý.

Đối với những trường hợp này, "khóa" có thể được đặt thành bất kỳ cột không thể nào nhưng sau đó AsNoTracking () phải được sử dụng với mọi bản ghi truy vấn khác (trùng lặp bởi khóa) sẽ bị bỏ qua.


2
Chỉ cần nhắc lại tầm quan trọng của điều này với Lượt xem, tôi có một truy vấn từ chế độ xem trả về 7 bản ghi duy nhất khi chạy qua SSMS. Khi chạy qua EF, không có công cụ sửa đổi AsNoTracking, tôi nhận được bản ghi đầu tiên, ba bản sao thứ hai và ba bản sao thứ ba. Điều này cần rất nhiều sự cố gắng đáng kinh ngạc để khắc phục, và nó đã sử dụng AsNoTracking để sửa nó!
Ade

Tôi đã gặp vấn đề chính xác tương tự khi sử dụng Linq cho các Thực thể trong khi truy vấn Chế độ xem không có khóa chính. Chỉ phát hiện ra về AsNoTracking sau nửa ngày gãi đầu. Bài viết diễn đàn ASP.Net này cuối cùng đã dẫn tôi đến nó. forum.asp.net/t/ Kẻ
red_dorian

6

Nếu bạn có điều gì khác làm thay đổi DB (nói một quy trình khác) và cần đảm bảo bạn thấy những thay đổi này, hãy sử dụng AsNoTracking(), nếu không, EF có thể cung cấp cho bạn bản sao cuối cùng mà bối cảnh của bạn đã thay thế, do đó, thường sử dụng bối cảnh mới mỗi lần truy vấn :

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.