Second Stanza

August 19, 2008

Handling Exceptions in ADO.NET Entity Framework

Filed under: .NET Development, ADO.NET Entity Framework — Tags: , — dfbaskin @ 10:06 pm

A new exception, UpdateException, was added to .NET 3.5 SP1 in order to support the ADO.NET Entity Framework. This exception is thrown when modifications to the object instances cannot be persisted to the data source.

Great! But how do you distinguish between the different reasons that the objects could not be persisted? In other words, how do you tell that the reason for the failure was due to a duplicate key versus a character field that was too long?

One answer is to validate the data in the business object so that you don’t get the exception in the first place. For field constraints, you could make sure your business object checks for valid field lengths before trying to store the data. For unique keys, you could ensure that the key doesn’t exist before persisting the object (doing so in a transaction, of course, to make sure another record doesn’t sneak in and use the key before you). You could, for example, customize your context object to handle these kinds of issues with techniques like this.

The other option is to interpret the exception being thrown. For example, the InnerException property of the UpdateException object might contain an SqlException object that holds details about errors reported by SQL Server. From there, you could look at the exact error codes to determine what happened. Some of us use a specific naming syntax for our SQL table constraints so that we can more easily identify constraint violations. Of course, this technique more closely associates the business objects with the data persistence layer. As we move towards more persistence-agnostic architectures, it would be nice not to tie our error handling so closely to SQL Server.

To get SQL Server 2005 list of error codes, you can use the T-SQL:

SELECT     *
FROM       sys.messages
WHERE      language_id = 1033

If I had my choice, a better solution to me would be another hook in the Entity Framework that would allow me to throw specific, strongly-typed exceptions that more clearly identify the errors being generated by the persistence layer. In other words, I would define exceptions in the business layer and the persistence layer would interpret exceptions or other errors returned from the store and throw these specific, business-layer exceptions for each case that require special handling, such as a DuplicateKeyException or InvalidDataException. The
OptimisticConcurrencyException
is an example of a move in this direction.

Advertisement

August 15, 2008

ADO.NET Entity Framework Default Values

Filed under: .NET Development, ADO.NET Entity Framework — Tags: — dfbaskin @ 10:32 am

A new technology comes along. You read the overviews. You understand what problems the technology seeks to solve. You read the pros and cons of using the technology. You are ready, then, to use the product and bask in the glow of increased productivity.

Then you actually use the product.

Ok, I’m being too cynical.

I fired up Visual Studio 2008 SP1 so that I could have a look at the ADO.NET Entity Framework. I’ve got an existing database that I need to create some business objects for so this will be a good test to see how well this framework fits my needs.

I am very interested in the fact that I can design my business objects according to what makes sense for my domain. Then, with a little mapping magic, I can get these business objects to interact with my database tables, regardless of how the database schema is organized. Sounds great to me!

So after creating a simple model, the validation returns the following:

Error 3023: Problem in Mapping Fragment starting at line 122: Column columnName in table tableName must be mapped: It has no default value and is not nullable.

This is a perfectly understandable error. Your business objects might only use a sub-set of data columns within a table. It therefore makes sense when adding a new record to the table, the framework must know how to handle these unreferenced fields if they don’t already have default or null values.

So the question is, then, how do you tell the framework what to do in these cases? This is where I am a little hazy.

It seems to me that you would specify this in the mapping itself. And, in fact, there is a way to specify a default value for a field. Unfortunately, the documentation says there is a Default attribute that can be used, but according to the SSDL schema, it is actually called DefaultValue.

  <xs:attributeGroup name="TCommonPropertyAttributes">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required"/>
    <xs:attribute name="Type" type="edm:TPropertyType" use="required"/>
    <xs:attribute name="Nullable" type="xs:boolean" use="optional" default="true"/>
    <xs:attribute name="DefaultValue" type="xs:string" use="optional"/>
    <!-- Start Facets -->
    <xs:attribute name="MaxLength" type="edm:TMaxLengthFacet" use="optional"/>
    <xs:attribute name="FixedLength" type="edm:TIsFixedLengthFacet" use="optional"/>
    <xs:attribute name="Precision" type="edm:TPrecisionFacet" use="optional"/>
    <xs:attribute name="Scale" type="edm:TScaleFacet" use="optional"/>
    <xs:attribute name="Unicode" type="edm:TIsUnicodeFacet" use="optional"/>
    <xs:attribute name="Collation" type="edm:TCollationFacet" use="optional"/>
    <!--End Facets -->
  </xs:attributeGroup>

Also, for some reason, you don’t get access to this property when viewing the database table column within the property list. All of the fields are read-only and ‘DefaultValue’ is not displayed. However, you can manually edit the .edmx file to add the default value.

Is this the right technique to use? Setting the default value gets rid of the error, but does it translate into the right SQL instructions? I’ll let you know.

Update: Aug 18th, 2008

Yes, changing the mapping manually as described sets the default values for the column when adding a new record. So for right now, it appears this is one scenario that requires editing the .edmx file directly, rather than using the designer.

August 13, 2008

ADO.NET Entity Framework Released

Visual Studio 2008 Service Pack 1 has been released, and with it the official release of the ADO.NET Entity Framework. This, of course, is Microsoft’s tool that allows developers to automatically build the mapping between business objects and the relational database (and other) models where the object’s data is actually stored.

Controversy has arisen from a petition condemning the framework that was signed by a number of developers. Tim Mallalieu has a good post summarizing the arguments.

I tend to think the petition is over-the-top, especially for a 1.0 solution. Ward Bell provides some temperance.

Here’s a good, succinct post about why you might use the ADO.NET Entity Framework instead of other solutions. This webcast provides a good overview of the features and benefits of the framework.

Blog at WordPress.com.