Entities
Jammer.NET entities contain all of the mapping metadata in-line with the C# source code. We’ve found this implementation affords benefits that outweigh any incremental gains of keeping the mapping metadata in a separate file. Typically, changes made to a database schema are significant enough to require changes to the C# application source anyway. Let’s face it; how often does a requirement or feature enhancement come along that amounts to changing one column type or name? Most feature enhancements require a significant schema and application modification that necessitate a redeployment of application code even if the enhancement is as innocuous as adding a secondary email address to a web form.
Inline Metadata Mapping using Custom Attributes
Jammer.NET takes advantage of custom attributes. Custom attributes are adorned to the appropriate class members to define class member mappings as well as mappings to database objects and the database itself. The following code sample illustrates how these mappings are declared.
…
[Database("Northwind")]
[Load("usp_Customers_Get")]
[Save("usp_Customers_Insert", "usp_Customers_Update")]
[Delete("usp_Customers_Delete")]
public partial class Customers : EntityBase, IEntityValidateable
{
[Key][FieldMap("CustomerID")] private string _CustomerID;
[FieldMap("CompanyName")] private string _CompanyName;
[FieldMap("ContactName")] private string _ContactName;
[FieldMap("ContactTitle")] private string _ContactTitle;
[FieldMap("Address")] private string _Address;
[FieldMap("City")] private string _City;
[FieldMap("Region")] private string _Region;
[FieldMap("PostalCode")] private string _PostalCode;
[FieldMap("Country")] private string _Country;
[FieldMap("Phone")] private string _Phone;
[FieldMap("Fax")] private string _Fax;
…
The Database attribute defines the name of the connection instance to use which is defined in the <connectionStrings> section of the web or application configuration file. The Load, Save and Delete attributes define mappings to specific CRUD stored procedures which only are executed when base methods of the same names are invoked. The following code sample shows the application configuration file definition.
<connectionStrings>
<add name=“Northwind“ providerName=“System.Data.SqlClient“ connectionString=“server=SERVER;database=DATABASE;uid=USER;pwd=PASSWORD“ />
</connectionStrings>
The Key() Attribute
The key attribute is used to define the primary key column(s) of a given table. The usage of the key attribute is demonstrated in the following code sample.
[Key][FieldMap("CustomerID")] private string _CustomerID;
The FieldMap() Attribute
Creating mappings to columns in a table or columns returned by a stored procedure are defined by the use of the FieldMap() attribute. In the following code sample, the database column “CompanyName” is mapped to a class-level private variable “_CompanyName”. Note: FieldMap() attributes should only be used on class-level private variables.
[FieldMap("CompanyName")] private string _CompanyName;
Use Visual Studio IDE “Go To Definition” Functionality
One of the greatest benefits to using inline attribute-based mapping is the ability to use the Visual Studio IDE’s “Go To Definition” feature to navigate to the mapping definitions. This feature can be used from any tier in the code base as long as the project with the source is included in your solution. It comes in handy when you need to follow execution logic as well.
To use this feature, place the cursor at a method or property call, or variable reference and right-click. Select “Go To Definition” from the context menu and left-click. Visual Studio will open the corresponding source file and auto-scroll to the proper line where the definition is made. The image to the right is a screen capture of the context menu in Visual Studio 2005.
To return to the previous cursor location use the control-minus key stroke combination ([CTRL] + [-]). For more IDE productivity features, you can visit Microsoft’s Visual Studio Developer Center website.