12
Dec
07

ADO.NET Data Services Part 1: Services

12/30/2007 - Added clarification about the identifier criteria when using an EDM data source

Welcome to the first installment of the multi-part article series on ADO.NET Data Services. Throughout the entire series we are going to follow the story of Phillip, who runs a cell phone resale company, and is looking to ramp up his business. Phillip has an extensive database of cell phones, carriers, and manufacturers. Lots of time and effort has been put into the population and maintenance of his precious data. One day he realizes that all that time he put into his database should be making him more money, so he decides to provide access to his data store to other companies looking to build a web presence but don’t have the resources Phillip has.

“I could write ASMX web services that provide access to my data”, Phillip says, “but I’d really like to expose my data RESTfully in as few lines of code as possible. I could use WCF. That makes creating RESTful services really easy! But once I’ve got the service plumbing in place I still would have to write all the data retreival, paging, filtering, and sorting code myself, which seems like it could get really redundant and painful as the need for more services grows. As much as I love web services, it just seems like there should be a special kind of service that is tailored specifically for data-driven scenarios and would provide me all the data manipulation functionality I needed out of the box, so that I could focus purely on my business logic. Now that I think about it”, said Phillip, “Microsoft developed a new technology they’re calling ADO.NET Data Services that is built on top of WCF and is supposed to address this exact need! I’m going to give that a try!”

So now that Phillip has made up his mind to use ADO.NET Data Services to create his arsenal of cell phone services, we’re going to peer in as he chips away at implementing this new feature into his application. The remainder of the article will be written from Phillip’s perspective (who knows very little about data services) not mine.

[Fog covers the stage]

[We now see Phillip sitting at his computer table]

So let’s see…I’ve already got my database setup the way I want…

astoria1.JPG

And I’ve already created a LINQ To SQL model that I’ve been using in my application…

capture.JPG

It would be really great if I could somehow re-use what I already have. Let me try to add a new ADO.NET Data Service to my project and see what kind of options it gives me.

astoria3.JPG

I see that it’s telling me to do two things:

  1. Specify what my service’s data source is
  2. Configure access rights for my data

astoria4.JPG

What do they mean by data source? I remember hearing that the data service would work with any implementation of IQueryable<T>, which certainly seems flexible enough. In fact, now that I think of it, the Table<T> class (which the DataContext wraps each entity in a LINQ To SQL model) implements IQueryable<T>. I also remember hearing that the ObjectQuery<T> class (which the ObjectContext wraps each entity in an Entity Data Model) implements IQueryable<T> as well, which means that my data service would be able to use the Entity Framework if I were to migrate my model down the road.

It would be really cool if I could just specify my data context as the data source and it be smart enough to pick up on the fact that it contains properties of type Table<T> which are of type IQueryable<T>. Let’s give it a try…

astoria5.JPG

Hit F5 and see what happens:

astoria6.JPG

Wow, I can’t believe that actually worked. Oddly though I don’t see any entities. Oh wait, I almost forgot item #2 from the above TODO list. ADO.NET Data Services are locked down by default, and only expose the data you tell it to, with the access rights you want. Of all the entities in my data model, the only one I want to expose is CellPhone, and I want it to be read-only.

Where am I going to put this access code? According to the generated comments, the static InitializeService method is called when the service is being initialized (go figure), which seems like a perfect place to add policy configuration code. Since Visual Studio generated the InitializeService method for me all I should have to do is add a single line of code within it to setup the access rule I want. Let’s give it a try…

astoria333.JPG

I could have put “*” in the first parameter if I wanted to expose the service’s entire underlying data source, but I only want to grant access to the CellPhone entity. Note also that “CellPhones” is the name of the IQueryable<T> exposed property on my data source (the data context), not the name of the actual entity class. The ResouceContainerRights enumeration has a slew of options, but I’m comfortable with AllRead, which allows all cell phones to be queried, as well as individual ones. I hit F5 again and I get the same results. Now what am I doing wrong?

I do a little reflecting into the ADO.NET Data Services DLL and notice a requirement placed on each object exposed by your data source: each object has to have a property that represents its identifier, that way it can be queried individually and uniquely. On top of that, the identifier property has to match at least one of the following criteria:

  1. Be named “ID”
  2. Be named “[EntityName]ID”
  3. Be marked with the DataWebKey attribute

Well that explains what my problem here is. Not only have I named my identifiers “Id” (note the lowercase “d”) instead of “ID”, but in the case of the CellPhone entity, its identifying property is called “ModelName”, which isn’t satisfying any of the above criteria. I don’t want to rename my property to “ID” or “CellPhoneID” and lose the domain-meaning of “ModelName”, so I’m just going to go with option #3 and apply the DataWebKey attribute to the ModelName property of my CellPhone entity class.

astoria8.JPG

Let’s hit F5 and try again:

astoria9.JPG

Beautiful! We’ve now got a service that is exposing just my CellPhone entity from my LINQ To SQL model, and giving it read-only access. Because I was able to re-use my existing model, the lines of code required to get my service running amounted to only a couple. I had to annotate my CellPhone entity’s identifier property, but that only took 12 characters to type, and it makes sense why the data service needs it. If I wanted to migrate my LINQ To SQL model to use an Entity Data Model (EDM) or even a custom implementation of IQueryable<T>, my service would be able to take full advantage of it regardless, with minor tweaks. All-in-all it took about 5 minutes to stumble to this point. Imagine how quick I could write a data service now that I’m aware of the real-world “gotchas”?

One thing to point out is that the above identifier criteria doesn’t apply if your data service is using an EDM as its data source. This is because the EDM has its identifier property determined by the EntityKeyProperty property of the EdmScalarProperty attribute.

[EdmScalarProperty(EntityKeyProperty=true, IsNullable=false)]

This means that if you’re using an EDM with your data service then your identifier properties can be called whatever you want and they don’t need to be salted with the DataWebKey attribute. If you are using LINQ To SQL or a custom IQueryable<T> implementation, then you will have to abide by the identifier criteria.

So now that this service is up and running, how do I actually get to my cell phone data? How can I request the data for a specific cell phone? How can I query for all cell phones that have Bluetooth capabilities?

We’ll cover all of this and more in part 2 of this series on service addressing.


8 Responses to “ADO.NET Data Services Part 1: Services”


  1. 1 Roger Jennings Dec 19th, 2007 at 3:37 pm
  2. 2 Roger Jennings Dec 21st, 2007 at 10:10 pm

    Sorry, above pingback was to Andy Contrad’s blog.

    Correct pingback was from http://oakleafblog.blogspot.com/2007/12/linq-and-entity-framework-posts-for_18.html (see the “Jonathan Carter Starts 11-Part ADO.NET Data Services Series” topic.)

  3. 3 Henry Cordes Jan 16th, 2008 at 9:25 am

    Like your series on ADO.NET Data Services, although I played with it some, you give me some more insights and get my enthousiastic again.
    Thanks!

  4. 4 Chua Wen Ching May 19th, 2008 at 9:32 am

    Good work for your articles :) I heard of this during Summit, looking at it.

  5. 5 Chua Wen Ching May 21st, 2008 at 7:31 am

    Hi. I read through your materials. Do you have the source code for the articles here? Or did I miss out anywhere? It will great if i could test it out instead of just reading it, in case I miss out some steps.

  1. 1 Elisa Flasko's Blog : ADO.NET Data Services CTP Released! Pingback on Dec 12th, 2007 at 5:04 pm
  2. 2 ADO.NET Data Services Part 1: Services (contd.) at Lost In Tangent Pingback on Dec 12th, 2007 at 6:38 pm
  3. 3 Mike Taulty's Blog : ADO.NET Data Services - Exposing Arbitrary Data (1) Pingback on Jan 3rd, 2008 at 11:35 am

Leave a Reply