GetTrackedObjects
A Linq-to-SQL DataContext does change tracking for all the objects it creates. This is so that it knows what to insert/update when you call .SubmitChanges(). Unfortunately, the DataContext doesn't supply that information to the world, but it's uber helpful to know at times, especially if you want to create a DAL that enforces writing to a changelog on every DB commit. This method examines the gruesome innards of the DataContext and gives you the
Source
' Feel free not to use a Tuple here... this was just a
' quick way to demonstrate the code
<Extension()> _
Public Function GetTrackedObjects(Of T)(ByVal dc As DataContext) As IList(Of Tuple(Of T, T))
Dim result As New List(Of Tuple(Of T, T))
Dim dcType = GetType(DataContext)
' Use reflection to get to the underlying items being tracked in the DataContext
Dim bindings = BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.GetField
Dim services = dcType.GetField("services", bindings).GetValue(dc)
Dim tracker = services.GetType().GetField("tracker", bindings).GetValue(services)
Dim trackerItems = DirectCast(tracker.GetType().GetField("items", bindings).GetValue(tracker), IDictionary)
' iterate through each update in context, adding only those that are of type T to the method's result variable
For Each entry As DictionaryEntry In trackerItems
Dim original As Object = entry.Value.GetType().GetField("original", bindings).GetValue(entry.Value)
If TypeOf entry.Key Is T AndAlso TypeOf original Is T Then
result.Add(New Tuple(Of T, T)(DirectCast(original, T), DirectCast(entry.Key, T)))
End If
Next
Return result
End Function
Example
Option Infer On
Dim dc As New DataContext()
' get linq-to-sql objects from a DataContext
'...
' Examine the DataContext for objects tracked
Dim changeHistoryList = dc.GetTrackedObjects(Of People)()
For Each potentialChange In changeHistoryList
Dim original = potentialChange.Item1
Dim current = potentialChange.Item2
If original.Salary <> current.Salary Then
Console.WriteLine("Salary changed from {0} to {1} for {2}", original.Salary, current.Salary, original.ID)
End If
Next
Author: MattMc3
Submitted on: 18 okt. 2010
Language: VB
Type: System.Data.Linq.DataContext
Views: 3846