After this, however, it still couldn't update correctly because the TrackedEntity object it was updating was only getting instantiated with its Name and Description (and not its ID). So when the data access layer tried loading up the object to update, it couldn't find an object with an ID of zero, so it died.
As a work-around, I found that simply including the ID column in the GridView would do the trick, but that's a hack, at best. After much searching, I found out that GridViews have a DataKeyNames property, in which you can include a comma-separated list of fields that shouldn't be shown in a column, but which need to be persisted so that the object being saved gets instantiated with all its previous values.
Finally, if I left any of the fields blank, it would complain that the values could not be null. By default, Gridviews will convert empty strings to null values. I had to put the following attribute in each BoundField: ConvertEmptyStringToNull="False". Whew!