Entity Framework Cache Busting

Entity Framework Cache Busting

September 26, 2020 1 By Nam Vu

Một số chú ý khi làm việc caching với linq EF
Có lẽ linq là một trong những kỹ thuật mà rất nhiều dev dùng, nhưng nếu đi sâu vào enhance performance thì lại phát sinh một số issue khi cache trong EF
Đặt vấn đề: Bạn hãy thử query một câu linq đơn giản và hãy để ý đến câu sql được dịch ra như sau:

var context = new MyDbContext(); var customers = context.Customers.Where(c => c.State == “VA”)   .Take(2).ToList();

ID    Name  State
—   —-  —–
850   Sam   VA
851   Sue   VA

SELECT TOP (2)     [Extent1].[CustomerId] AS [CustomerId],     [Extent1].[Name] AS [Name],     [Extent1].[State] AS [State],     — a bunch of other columns —     FROM [dbo].[Customers] AS [Extent1]     WHERE [Extent1].[State] = ‘VA’

Sau đó bạn hãy thử update giá trị Name trong Entity trên và query lại thử.

UPDATE Customers SET Name = ‘Susan’ WHERE CustomerID = 851
customers = context.Customers.Where(c => c.State == “VA”).Take(2).ToList();

Thật ngạc nhiên, data của bạn không hề thay đổi và chúng ta phải làm sao đây?

ID    Name  State
—   —-  —–
850   Sam   VA
851   Sue   VA

Đó là vấn đề cache trong linq của EF, thật khó chịu nhưng cũng không phải không có cách khắc phục. Dưới đây là một số solution mà bạn có thể cân nhắc:

  • Disable Tracking using AsNoTracking()

    Thường khi chúng ta create hay modify data của 1 entry nào đó trong entity. Ở một chỗ khác thì get data đó lên thì hay sử dụng AsNoTracking() với mục đích giúp cho data mới không bị cache lại khi các câu query giống nhau.  Tuy nhiên nếu entry lồng cấp tức là Entity này được include vào entity kia khi get lên thì có một chú ý là AsNoTracking() nên nằm cuối cùng câu query linq để tránh cache include data entry

— Còn tiếp —

  • Throw away the DbContext and create a new one
  • Use an ObjectQuery instead of a DBQuery and set MergeOptions
  • Refresh the Entities
  • Detatch the Entities
  • Call GetDatabaseValues to get the updated values for a single Entity
  • Use the stale data