Entity Framework: ObjectContext observations on caching

I thought that my journey with the Entity Framework was going to be like falling off a cliff, fast and painless but instead it’s been more like driving a Hummer in a Smart car convention, just have to plow my way through.

The latest bump in my path has been the ObjectContext. Just to let it be known, I’m like most kids with a new game, I don’t bother to read the instructions and the throw the controller when I don’t have a clue what I’m doing. My use of the Entity Framework has been no different. So using “o’ skool” standards, I immediately decided that I would have some kind of Singleton context so that I didn’t keep making new ones, and assumedly new connections. Everything seemed fine and dandy until I hit this situation which brought some, at the time, unexplainable or difficult issues.

First off, say you have a Site and Role class, and Role is Many to One with Site. Now let’s say you are creating a page that is used to create/update/delete roles. On this page you have the usual section for updating or creating a new role that involves a Name for the Role and a drop down list to pick a Site from. Now on the update side of it you have basic rules: The Role must have a name, the Role must have a Site, and the Name of the Role can’t already exist in the database for the site. So a new role might look like:

  Role editRole = Role.GetByID(someID);
  editRole.RoleName = txtRoleName.Text;
  editRole.Site = GetSiteFromID(ddlSite.SelectedValue.ConvertTo<Int32>);

The GetByID is just a query that gets the Role by and ID by using the Singleton ObjectContext. (KEY POINT) Beyond that, nothing special except my awesome string convert. Yah. Now the next step before committing to the database is something like:

  if
  (
    context.Any
    (
      role => role.Name == editRole.RoleName
      && role.Site == editRole.Site
    )
  )
  {
     //return error or whatever
  }

So right there I’m checking to see if the new name for the role exists already. Now say I’m updating a role and that I KNOW the new name doesn’t exist. You would think that query would return false and life would be good. Unfortunately two things happened… and they will change your life forever. (EDIT: I realize I could also check to make sure the ID doesn’t match and should do that, but if I had done that initially I wouldn’t have figured out the next part)

First:

I got back an error saying the name already exists. Now as I said, I know it didn’t so how could that happen? Well remember that Singleton ObjectContext idea? First time I grab the Role, it doesn’t exist in the ObjectContext.Role list. So it grabs it from the database and then stores it so that every time I now run that GetByID method, I am actually getting the object from the context NOT THE PERSISTENCE LAYER. (IE database or whatever) Therefore, any changes I make are changes to the object in that context. So what does that mean? Well say I do update the RoleName on that object and then run a query to see if that name exists, guess where that query is looking? Yup the context. And since it’s looking at the same stupid object I just changed, of course the name is going to exist now. Basically I comparing the object to itself to see if it’s name exists. Ouch.

B:

After cancelling, (IE not saving) The grid that I had displaying all the Roles now has that new RoleName in it. What the f? My code specifically says NOT to save unless that (name already exists) query returns false. So how the hell has the name changed? Well just like before, the query that gets the list of Roles is no longer looking at the database but now at the Roles list in the context. That same Roles list that has the Role I changed earlier. Therefore any change to that object will now be reflected when getting the list from the context. Uhg.

So what can you learn about this? Once a list is “loaded” for the first time, it is held in the context until (presumably) you use the Refresh method on the context to refresh the given list. (Not sure how well this works). Therefore, any queries after the first will reflect all changes to the objects in the context, whether you saved to the database or not. The Singleton idea isn’t looking real great right now.

Entity Framework: Many to One property and how to load

Ok so this is the situation, you’ve just stolen 50 billion dollars from various wealthy people using a ponzi scheme and you’ve been caught. What do you do? I have no idea but if that’s your situation and you’ve ended up at this site, I’m guessing your escape route has something to do with the Entity Framework and how to load a many to one relationship. Or maybe you’re just interested in the latter anyhow.

So here’s the problem I ran into the other day. I have a Site table and a Role table, and every Role record has a SiteID (Foreign Key) that the Entity Map represents in a property. (Site Class) Now, when I “hydrate” a Role, the Site property is null. This is because Entity Framework, in a round about way, supports lazy loading sort of. (Lazy Loading meaning that any relationship, be it a Site object on a Role or say a Users list on a Role, will not be loaded at the time you “hydrate” the main object and will only be loaded when the property is accessed.) So it makes sense that the Site object exposed by the property is not loaded yet because I haven’t accessed the property.

With the Entity Framework, and one to many relationships (Say a Users list on a Role object) you have to not only access the property, but you have use the Load method to make sure it gets loaded:

    from user in someRole.Users.Load()

Well with a many to one relationship (Many Roles to one Site) this is a propblem since the Site property returns only a single Site:

    someRole.Site.Load(); //Boom, not possible

Load can’t be used since Site isn’t a collection. So how the hell do I load this stupid thing? Well that has to be done in the query itself. Kind of annoying:

    context.Role.Include("Site").Where(someClause).ToList();

As you can see, in that query I had to add the Include method and the value is actually the property name. Now when I look at the list of roles returned, the roles now have the Site property loaded. As I said, kind of annoying, but there is something interesting about these relationships that I’ll post about next.

My jQuery Primer

So you have been reading about jQuery and want to dive in and try some? I recently attended the MSDN Dev Conference in Detroit where jQuery integration and client-side programming were very hot topics. With Microsoft’s acceptance of the open source library, I figured I would give it a try. This is what I have learned so far. Before I can show you what you can do with jQuery, I think I should probably show you how to get a reference to jQuery into your code. In ASP.NET you can add your reference directly to your Script Manager

<asp:scriptmanager id="pageScriptManager" runat="server">
<scripts>
<asp:scriptreference path="/client/jquery-1.3.1.min.js" />
</scripts>
</asp:scriptmanager>

What does jQuery have to offer? First and foremost, jQuery has given me power over the Document Object Model (DOM)! jQuery Selectors are the greatest thing since sliced bread, no lie. Being able to EASILY find an object or group of objects in the DOM by ID, CSS Class, or by HTML Tag is something web developers have long needed. To select an object from the DOM by ID would look like this:

$('#ID_Goes_Here')

To select an object from the DOM by CSS Class would look like this:

$('.CSS_Class_Name_Goes_Here')

To select an object from the DOM by HTML Tag would look like this:

$('<tag_goes_here>')

With jQuery Selectors being so simple, it allows the developer to easily select an object or a group of objects. Now that we can select objects, what can we do with them? This is where the power of Selectors really builds into what else you can do. In a web application, round trips to the server to manage UI is wasteful. I avoid JavaScript like the plague because it’s a pain in the ass. jQuery makes client-side UI management feel like climbing the rope in gym class. For example, if I have a label that I want to be rendered but not visible I could create the label.

<asp:label id="Label4" runat="server" cssclass="myLabel" text="This is " />

And later on in jQuery I can hide it like this.

$('#Label4').css('display', 'none');

It’s nice to be able to easily select an object and modify it, but what if you have a whole group of items you want to modify? With jQuery, you can EASILY loop through a collection of objects. In this example I have a group of labels.

<asp:label id="Label1" runat="server" cssclass="myLabel" text="This is " />
<asp:label id="Label2" runat="server" cssclass="myLabel" text="This is " />
<asp:label id="Label3" runat="server" cssclass="myLabel" text="This is " />
<asp:label id="Label4" runat="server" cssclass="myLabel" text="This is " />

Now I want to update the text of each label to include its ID. I am going to loop through each object in the DOM with a CSS Class of .myLabel.

$('.myLabel').each(function() { $(this).append(this.id); });

What the jQuery code above does is execute a function that will append the object’s ID to its text value. Notice the Selector inside the function $(this). The syntax is used to find the loop’s current object in the DOM. I do a lot of web work where I create controls on the fly. For my last example, I just wanted to show a way to quickly insert some HTML into a container object. I will start with a Panel AKA a DIV.

<asp:panel id="Panel1" runat="server" />

Now I am going to use jQuery to select my DIV and add some HTML to it.

$("#Panel1").html("<ul><li>Item One</li><li>Item 2</li></ul>");

Now I have shown you some snippets here and there, let me show you what my page actually looks like.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
	<title>jQuery Examples</title>
	<link href="/style/jQuery.css" rel="Stylesheet" type="text/css" />

	<script type="text/javascript">  function pageLoad() { $('.myLabel').each(function() { $(this).append(this.id); }); $('.myLabel').css('color', '#FFFFFF').css('font-size', '30px'); $('#Label4').css('display', 'none'); $("#Panel1").html("<ul><li>Item One</li><li>Item 2</li></ul>"); } </script>

</head>
<body>
	<form id=	<form id="pageForm" runat="server">
	<asp:scriptmanager id="pageScriptManager" runat="server">  <scripts>  <asp:scriptreference path="/client/jquery-1.3.1.min.js" />  </scripts>  </asp:scriptmanager>
	<asp:label id="Label1" runat="server" cssclass="myLabel" text="This is " />
	<br />
	<asp:label id="Label2" runat="server" cssclass="myLabel" text="This is " />
	<br />
	<asp:label id="Label3" runat="server" cssclass="myLabel" text="This is " />
	<br />
	<asp:label id="Label4" runat="server" cssclass="myLabel" text="This is " />
	<br />
	<asp:panel id="Panel1" runat="server" />
	<br />
	</form>
</body>
</html>

Links
jQuery: http://www.jQuery.com/
Object Model: http://en.wikipedhttp://en.wikipedia.org/wiki/Document_Object_Model

ConfigurationManager And AppSettings… A Wrapper Class Story

You can file this under “Do I really need this?” but for now I kind of like it. That, however, may change in the next hour.

The idea is simple, create a class that uses the ConfigurationManager AppSettings NameValueCollection (Triple Combo!) but only presents properties that represent the keys in the .config file. This way there is no guessing of how the key is spelled or that that type returned is converted to something it should be. (Say you have a numeric value in the .config file) Now this doesn’t seem like a big deal, but I’m not happy with something that is just simple like:

    public String SomeKey
    {
       get
       {
          return System.Configuration.ConfigurationManager.AppSettings["SomeKey"];
       }
    }

Oh no, that’s just not good enough. Call it divine intervention. Call it spontaneous brilliance. Call it whatever the guy that invented the corn dog had. But what I came up with is far better. (And by better I mean more complex)

Remember, the idea isn’t to have to grab just the value from System.Configuration.ConfigurationManager.AppSettings but also to have it be typed on the way back. Now we know this to be true: I am awesome. What we also know to be true is that the value held in the appSettings area of the .config file is going to correspond to a value type but is going to be read in as a string. If you’ve read some of my posts (Which I assume you haven’t), you might have stumbled upon this little gem and know that I already have something to convert from a string to pretty much any value type. (Those having a TryParse method) So the converting part is already done, but what about the getting?

    protected static T? GetValueFromConfiguration<T>(String key) where T : struct
    {
      T? returnValue = null;
      if (System.Configuration.ConfigurationManager.AppSettings[key] != null)
      {
        returnValue = System.Configuration.ConfigurationManager.AppSettings[key]
                           .ConvertTo<T>(); //MY AWSOME CONVERTTO METHOD!!11
      }

      return returnValue;
    }

Ok so you can see, this is really simple. I check to see if the key exists, get the value from the .config file, and convert to whatever I said it should. In use this would be:

    public static DateTime? TestDate
    {
       get
       {
          return GetValueFromConfiguration<DateTime>("TestDate");
        }
      }

Now you might have noticed something about this… yes besides the fact that it’s Mentos fresh. First, the method returns nullable versions. The reason for doing this is you really don’t know what the value will be in the .config file. Say this was an integer and you returned just a normal integer. (Non nullable) What would you set the value to? Sure you could do minimum value but COULD mean that there was a value in the .config file. This is more of a design choice though.

Second is that the method doesn’t cover strings. This is an ouch due to how nullables and strings work. You can’t return a nullable string since string doesn’t fit in the non nullable value category. This is a real pain but easily overcome with a non generic overload:

    protected static String GetValueFromConfiguration(String key)
    {
      String returnValue = null;

      if (System.Configuration.ConfigurationManager.AppSettings[key] != null)
      {
        returnValue = System.Configuration
                           .ConfigurationManager.AppSettings[key];
       }
       return returnValue;
    }

See? Easy way to side step the problem. There might be a better way to handle that, but not sure at this point. Something to revisit I suppose. Oh and here’s the whole class for the hell of it:

    public class BaseConfigurationManager
    {
       private const String SOME_KEY = "SomeKey";

       protected static T? GetValueFromConfiguration<T>(String key) where T : struct
       {
         T? returnValue = null;

         if (System.Configuration.ConfigurationManager.AppSettings[key] != null)
         {
           returnValue = System.Configuration.ConfigurationManager.AppSettings[key]
                         .ConvertTo<T>();
         }

         return returnValue;
       }

       protected static String GetValueFromConfiguration(String key)
       {
         String returnValue = null;

         if (System.Configuration.ConfigurationManager.AppSettings[key] != null)
         {
           returnValue = System.Configuration.ConfigurationManager.AppSettings[key];
         }

       return returnValue;
     }

     public static String SomeKey
     {
       get
       {
         return GetValueFromConfiguration(SOME_KEY);
       }
     }

    }

Oddly enough I spelled “spontaneous brilliance” correctly the first time around but thought “numeric” had a silent ‘b’. Go figure. Should have finished middle school.