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.