NHibernate.LINQ with ADO.NET Data Services


Silverlight Logo

Now that my ADO.NET Data Services support has been merged into the trunk of NHibernate.LINQ, I do have some caveats about using NHibernate.LINQ with ADO.NET Data Services.  ADO.NET Data Services is a beta 1 product so there are some bugs and issues that you will either need to avoid or work around.

The biggest issue is around entity identity. ADO.NET Data Services must know how identity is established for objects in order to support the Data Service. It does this in a two step process:

  • First it looks for attributes that describe the 'primary key'.
  • Failing that, it looks for properties on the entity called ID, or ending with "ID".

The second approach is where I expect most of NHibernate projects to fall into since you really don't want to pollute your objects with technology specific information (the attributes). This approach works well except that there is a bug in the Beta 1 version of ADO.NET Data Services.  If the properties are specified in a base class and the keys are specified ending in "ID" (instead of just being called "ID"), then the search for the identifiers fails and Data Services fails to want to serve these objects.  For example:

public class AbstractCategory
{
  public virtual int CategoryID { get; set; }

  public virtual string CategoryName { get; set; }

  public virtual string Description { get; set; }

  public virtual byte[] Picture { get; set; }

  public virtual IList Products { get; set; }
}

public class Category : AbstractCategory
{
}
}

If this is your scenario, I might suggest waiting for later build of ADO.NET Data Services to be released as this is definitely a bug not expected behavior and I have gotten word from Microsoft that it is fixed in the RTM (which isn't available yet).

The next issue is that for collections, ADO.NET Data Services must understand the types that belong in a collection. In this case our above example will not work either in that having the Products in a Category as a simple IList can't tell ADO.NET Data Services what types of objects to deal with.  If we change this to an IList<Products>, it works fine.  If we have to change our entities to work with ADO.NET Data Services, this is what our new Category might look like instead:

public class Category
{
  public virtual int CategoryID { get; set; }

  public virtual string CategoryName { get; set; }

  public virtual string Description { get; set; }

  public virtual byte[] Picture { get; set; }

  public virtual IList<Product> Products { get; set; }
}

With these changes, ADO.NET Data Services work fine.

If you are new to ADO.NET Data Services, this blog entry may help with some debugging issues in using it:

http://wildermuth.com/2008/06/07/Debugging_ADO_NET_Data_Services_with_Fiddler2

Lastly, I want to follow up on a note that Ayende mentioned on his announcement of my examples.  In his blog post, he said:

From a technological perspective, I think this is awesome. However, there are architectural issues with exposing your model in such a fashion. Specifically, with regards to availability and scalability on the operations side, and schema versioning and adaptability on the development side.

I think he's right in that there is a schema version issue here that needs to be addressed but that the availability and scalability problems are ones that would be in the underlying data model itself. Since ADO.NET Data Services are just a convenience around WCF's REST Service Model, we can scale out or up depending on our needs (as well as caching).

What I think is important is to understand the reason behind ADO.NET Data Services.  It is not a model to replace typical Web Service or Message Bus architectures.  Its not all that fast or efficient.  Its purpose is to allow the creation of a simple model to allow communication across the firewall.  What I mean is that it is meant for the AJAX and RIA developers.  Its a way of communicating data to clients that run on the Internet. 

Its important to understand that data you expose with ADO.NET Data Services is not magically more secure...in fact, since its meant for client-side consumption of data, you should not allow data to be exposed by ADO.NET Data Services that is sensitive. Remember, that consuming data in the client is not secure in itself.  If you wouldn't feel safe consuming data in client-side JavaScript, don't expose it via ADO.NET Data Services.




Application Name WilderBlog Environment Name Production
Application Ver 1.1.0.0 Runtime Framework .NETCoreApp,Version=v1.1
App Path D:\home\site\wwwroot Runtime Version .NET Core 4.6.25009.03
Operating System Microsoft Windows 6.2.9200 Runtime Arch X86