Monday, April 28, 2008

EntityStateObjects, to me, are one of the most important little pieces of the EF puzzle. IT is the EntityStateObject that maintains all of the critical info for change tracking. But it's hard to get the big picture of what's going on in there when debugging because all of the important stuff is delivered through methods, not properties.

I wanted so badly to write a debugger visualizer for them but they are not serializable (big pout) so instead, I wrote an extension method that uses a ConditionalAttribute to ensure it doesn't pop up during run time. It's for my book but I didn't want to hold onto it until October when the book should be published.

Since it's not a Debugger Visualiser, I refer to it as a DebugTime visualizer. :-)

Here's what my ObjectStateEntry Visualizer looks like in action:

All of the info is pulled from the ObjectStateEntry. At the top it tells the fully qualified name of the type of the object being inspected as well as the object's EntityState.

Then I use the various methods of the ObjectStateENtry to get the Original Values, the Current Values, the names of the fields and a list of the names of the modified fields.

All of this data I feed into the grid.

If the object is detached, then there is no ObjectStateEntry and the visualizer shows this message when you try to run it:

So enough with the screenshots. Here's the code. And here's a collection of important punctuations for you C# programmers who feel a need to translate

[ ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ;]

 

Imports System.Runtime.CompilerServices
Imports System.Data.Objects

'NOTE: The objects in use here are not serializable so they can't be used
'in debugger visualizers. Instead, you'll need to use them directly, but you can 
'give them a debug attribute so they are only available during debug mode.
<Extension()> _
Public Module Visualizers


  <ConditionalAttribute("DEBUG")> _
  <Extension()> _
  Public Sub VisualizeObjectStateEntry(ByVal eKey As EntityKey, ByVal context As ObjectContext)
    Dim ose As ObjectStateEntry = Nothing
    If Not context.ObjectStateManager.TryGetObjectStateEntry(eKey, ose) Then
      Windows.Forms.MessageBox.Show("Object is not currently being change tracked and no ObjectStateEntry exists.", _
"ObjectStateEntry Visualizer", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Warning) Else Dim currentValues = ose.CurrentValues Dim originalValues = ose.OriginalValues Dim valueArray As New ArrayList For i = 0 To currentValues.FieldCount - 1



'you can get from the ObjectStateEntry into the MetaData which actually comes from the EDM
Dim sName = currentValues.DataRecordInfo.FieldMetadata.Item(i).FieldType.Name Dim sCurrVal = currentValues.Item(i) Dim sOrigVal = originalValues.Item(i)
'nothing like a little LINQ query to find some info Dim changedProp = (From prop In ose.GetModifiedProperties Where prop = sName).FirstOrDefault Dim propModified As String propModified = If(changedProp = Nothing, "", "X")

'the funky property naming in this anonymous type is to get around a wierdness with
'LINQ databinding that only occurs in VB - it alphabetizes the fields
valueArray.Add(New With _
{._Index = i.ToString, ._Property = sName, .Current = sCurrVal, _
.Original = sOrigVal, .ValueModified = propModified}) Next Dim frm As New debuggerForm With frm.DataGridView1 .DataSource = valueArray End With frm.lblState.Text = ose.State.ToString frm.lblType.Text = ose.Entity.ToString frm.ShowDialog() End If End Sub End Module

The form has no code, just a few controls:

I created an assembly for my Entity Framework extension methods and just reference the assembly anywhere I want to use it.

Then when I want to use it, I call it against the EntityKey of an Entity Object:

  context = new AWModel.AWModel.AWEntities();
  cust = context.Customers.Where(c => c.CustomerID == 223).First();
  cust.CompanyName = "JULIE COMPANY";
  cust.EntityKey.VisualizeObjectStateEntry(context);

This has been an enormously useful tool for when I have been presenting as well as just working.

Enjoy!

Monday, April 28, 2008 8:07:48 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
All comments require the approval of the site owner before being displayed.
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview