Rants Tagged with “ADO.NET Data services”
1 2 3 > >> (Total Pages: 3/Total Results: 22)
If you're a regular reader of my blog, you'll probably remember my pithy blog post where I stated that "It all depends..." to the question "Which Data Access Should I Use for Silverlight 3?" The reality is that much like the similar question I am confronted with at user groups for the past decade ("What data access should I use in my .NET app?"). The reasons for picking a strategy are wide and varied so I will not try to analyze all possible outcomes, but I think the different strategies need to be explained better.
The three major candidates in Silverlight 3 are Web Services (WCF/ASMX), ADO.NET Data Services and RIA Services. In any situation, any of these will work. But they are suited to different styles and requirements. Here's the abridged differences between the stacks:
- Web Services: Interface-based Data Access
- ADO.NET Data Services: LINQ-based Data Access with change management
- RIA Services: Interface-based Data Access with change management
Let's dive deeper into explaining these differences and why that might matter.
Web Services
Using web services is the tried and true method for communicating across the firewall. This pattern is well known and reliable. In general this requires you specify an interface for the CRUD operations as separate operations on a web service then dutifully call them in your Silverlight code.
Reasons to Use: Any existing investment in web services can be a great reason to use them (whether in code or skillset). Also, web services are often used in cases where a project wants a very close control over the flow from the application to the database.
Reasons to Avoid: With web services you end up having to keep track of the changes yourself and know what services to call with updates. Any need for batching or transactional support gets cumbersome and code-intensive.
ADO.NET Data Services is a simple REST-based facility for data access. It relies on the HTTP stack to help define the interface. GET calls become Reads, POST becomes Updates and so on. It uses ATOM or JSON for its serialization format so it is consumable by a variety of clients.
Underneath its covers it takes this URI based API and converts it into a LINQ call for GETs and to API calls to the provider for inserts, updates and deletes. That means that ADO.NET is a thin layer who's purpose is to translate the URI model to data access code. But its better than that...
The real power of ADO.NET Data Services for Silverlight is the inclusion of the Client Library. This client library allows you to issue LINQ queries defined in the client and executed on the server. While the LINQ syntax is somewhat limited when compared to the server, it fulfills the 80% case and ADO.NET Data Services allows you to add operations to fill in the rest when necessary. In addition, the client library includes a powerful data context class that can monitor changes and issue changes in batches with transactional support.
Exposing your data access with ADO.NET Data Services is about exposing queryable end-points instead of defining an interface. This is what makes is unique. For example, we can query our service using a LINQ Query like so:
// Silverlight Code
// Create the query using LINQ
var qry = (from g in ds.Games
where g.Price < 50m
orderby g.Name
select g) as DataServiceQuery<Game>;
// Execute the Query
// (This part is getting cleaner in ADO.NET Data Services v1.5)
qry.BeginExecute(new AsyncCallback(r =>
{
games2.ItemsSource = qry.EndExecute(r).ToList();
games2.DisplayMemberPath = "Name";
}), null);
Reasons to Use: Want a simple, secure model where the developers can define the queries they need in code instead of changing the interface as the needs change. The ADO.NET Data Services' client library makes the amount of code you write on the client small as it becomes LINQ calls and working with the context class.
Reasons to Avoid: When you want tight control over the interface to your data access and do not want developers issuing LINQ queries directly from the client code.
RIA Services
As the new kid on the block, RIA Services has a lot to offer. RIA Services is based on the idea of creating a data access API on the server and at the same time creating the client code in Silverlight (and other platforms in the future). Its focused on sharing code between the client and the server including validation logic. In addition, while it allows you to create a set interface, it also provides a context object which can monitor changes on the client and batch those changes back to the server. In some ways RIA Services is like a hybrid of Web Services and ADO.NET Data Services.
Because RIA Services is based on a server-side query defined in its interface, on the client we call the query by calling the call on the interface:
// Silverlight Code
// The context object that tracks changes
XBoxGamesContext ctx = new XBoxGamesContext();
// Our RIA Query, really a call to an interface
var qry = ctx.GetGamesByGenreQuery("Shooter");
// Bind the data
theList.ItemsSource = ctx.Load<Game>(qry).AllEntities;
While in ADO.NET Data Services you are issuing LINQ queries, RIA Services also allow you to add LINQ constraints to the query endpoints. For example instead of just creating a query by calling the interface, you can add LINQ expressions to the endpoint like so:
var riaQry = ctx.GetGamesQuery()
.Where(g => g.Price < 50m)
.OrderBy(g => g.Name);
LoadOperation<Game> op =
ctx.Load<Game>(riaQry);
Reasons to Use: RIA Services is a good choice if you expect to develop a straightforward application minimum number of tiers. It works best in Rapid Application development scenarios versus large architected applications. RIA Services does support a mix between the interface based from Web Servics and and LINQ based querying that is supported by ADO.NET Data Services.
Reasons to Avoid: RIA Services leverages a lot of magic code generation to make it work and that is harder to debug than it should be. Integration with large enterprises is possible, its not as easy it as it should be.
"So Which Would You Suggest?"
While I paint this picture of data access in Silverlight with a broad brush, I still get the question to suggest one over the other. The fact remains that there isn't a right/wrong answer here. A lot of it depends on the environment, project and skillset of the developers. So, no...I won't tell you what I suggest because I don't know the requirements and environment you work in. That's why they pay you the big bucks to be a developer, right?

While Niagara is not going to require that you specify your validation attributes using its DSL, there are some benefits I think we can get by loosely coupling the validation. To that end, i've come up with a very first draft of the DSL to define the attributes. I've decided that instead of being very English-like, to mimic the "M" style of language. Here is my take:
// Niagara.Sample.Validation.validation
ValidationInfo
{
Validators
{
// Some validators are built in
// E.g. the System.ComponentModel.DataAnnotations
MyCustomValidator =
"MyCustomValidator, Niagara.Example.Validators, Version 0.1"
}
Types("XBoxGames.Data, Version=1.0.0.0")
{
XBoxGames.Data.Game
{
Name { Required, StringLength(100) },
Price { Range(0,2000) },
Rating
{
Required,
MyCustomValidator("Adult", 1000)
}
},
XBoxGames.Data.Genre
{
Name
{
Required,
StringLength(100)
}
},
XBoxGames.Data.Rating
{
Name
{
Required,
StringLength(100)
}
}
}
}
For any comments, please add them to the codeplex site here instead of commenting on the blog:
http://niagara.codeplex.com/Thread/View.aspx?ThreadId=70371
The goal of Project Niagara is to democratize the validation support. The project wants to help developers add validation support to ADO.NET Data Services as well as Web Services in Silverlight. In addition, it has the goal of allowing multiple ways to supply the validation metadata to the different data access strategies. As it is my opinion that there are scenarios where attributes are not the best idea.
The deliverables for this project will include:
- ValidatingDataSvcUtil: Produce Validating Data Service Proxies.
- ValidatingProxy Library: Supply external metadata for generation of Proxies.
- MValidation: DSL for defining Validation outside of attributes.
- Oslo Integration: to store/retrieve validation out of the Oslo Repository.
- Alignment: RIA Services' and ADO.NET Data Services' Validation Logic
At this point the project is very young (version 0.1) and a lot of the pieces are not ready but I am looking for help! I can't write it all. Please visit the CodePlex site and take a look at what I want to accomplish and send me a message if you want to help out:
http://niagara.codeplex.com
Current State of Niagara
Currently, I have built up some infrastructure to allow the whole project. This inlcudes a first pass at the DSL. The one working pieces is the ValidatingDataServiceUtil which allows you to manually generate (via the command-line) an ADO.NET Data Service proxy that includes support for validation attributes and calling validation during two-way binding.
The current version does not have a release yet, but if you're brave and willing to report bugs, you can get the source and build it yourself.
To use the ValidatingDataServiceUtil, you can call it from the command-line:
NiagaraDataServiceUtil.exe http://localhost:14000/GameService.svc
..\Niagara.Sample.Web\bin\Niagara.Sample.Web.dll
.\GameService.cs
Niagara.Sample.Data /v /b /c:V2
While more complex than the original DataSvcUtil, the arguments are pretty straightforward:
- URI to the ADO.NET Data Service endpoint.
- Path to the assembly that holds the types and metadata (so we can read the metadata with reflection).
- The output file.
- The namespace to use.
- Options to specify what version of the data service library to use, bindability and validation.
This is an alternative to using a service reference. We hope to move this to be a project item instead of a command-line for the project.
NOTE: It requires the ADO.NET Data Services CTP2 to work.
Let me know what you think!
As RIA Services is plodding towards a release, many people are looking at it to help them with validation of data in Silverlight. Using this validation in Silverlight 3 is pretty straightforward but there are some caveats. I want to show you under the covers so you understand what is happening. In this first part of the series, let's look at what it means to use validation from the outside.
How It Works
Back when Dynamic Data was being developed, a set of attributes was created to help tell the Dynamic Data folks about validation and other metadata so they could create smart scaffolds. These include:
- RequiredAttribute
- StringLengthAttribute
- RangeAttribute
- RegularExpressionAttribute
In addition, there were attributes that could tell Dynamic Data about how to name fields and such. This meant that if you were using a POCO class or a DTO, that you could do the annotation like so:
public class GameInfo
{
[Required]
[StringLength(100)]
public string Name { get; set; }
[Range(0d, 1000d)]
public decimal Price { get; set; }
}
When the GameInfo class is generated on the client, that's how the validaiton is happening. On the client we can simply bind to the DataForm to show the validation in action:

While the DataForm will do this in a generic fashion (or even let you define templates), many Silverlight applications would like this validation behavior without using the DataForm. In fact, all the Silverlight 3 controls now support it but only if you know how to bind the elements correctly. If we bind the GameInfo to a StackPanel with some controls, we can get this same validation experience:

This works in two ways. First the controls themselves have support built-in for the validation part of the user control. When you skin a TextBox or other control, part of the ControlTemplate is the validation UI. So you can change what that looks like. The controls themselves react to the validation errors because of the way they are bound. For example, this simple UI looks like this in XAML:
<TextBlock>Name</TextBlock>
<TextBox Text="{Binding Name, Mode=TwoWay,
NotifyOnValidationError=true,
ValidatesOnExceptions=true}" />
<TextBlock>Price</TextBlock>
<TextBox Text="{Binding Price, Mode=TwoWay,
NotifyOnValidationError=true,
ValidatesOnExceptions=true}" />
These three parts of the binding are critical to making this work. The validation is performed when the data is pushed back into the backing data but how does this actually work? The hint is in the "ValidatesOnExceptions".
With a TwoWay binding, when you lose focus on a control, the value is pushed back to the control (including going through any converters you have specified). Normally if an exception is thrown during that process it fails to update the underlying object, but just swallows that error. But if you enable it with these two binding markup extensions, it assumes that any exception thrown during the TwoWay operation is a Validation error. Back in Silverlight 2, you could do this by simply adding validation logic directly in your data classes like so:
public string Name
{
get
{
return this._name;
}
set
{
if ((this._name != value))
{
if (value.Length > 100)
{
throw new ValidationException(
"String cannot be longer than 100 characters");
}
this._name = value;
}
}
}
This is where the Validaiton attributes we mentioned earlier come in. The controls themselves do not make the check for the validation. Instead there are two classes that come into picture. ValidationContext and Validator. These classes can be used to test a property's or an entire object's set of validation attributes. Essentially, the ValidationContext sets up what needs to be validated and the Validator performs the validation like so:
public string Name
{
get
{
return this._name;
}
set
{
if ((this._name != value))
{
var ctx = new ValidationContext(this, null, null);
ctx.MemberName = "Name";
// If fails, throws an excption
Validator.ValidateProperty(value, ctx);
this._name = value;
}
}
}
These classes working together validates the value against whatever ValidationAttributes are on the "Name" property (e.g. Required, StringLength) and throws a ValidationException when it fails. In fact, lets look look at the RIA Services class it generates in Silverlight:
[DataMember()]
[Required()]
[StringLength(100)]
public string Name
{
get
{
return this._name;
}
set
{
if ((this._name != value))
{
this.ValidateProperty("Name", value);
this.OnNameChanging(value);
this.RaiseDataMemberChanging("Name");
this._name = value;
this.RaiseDataMemberChanged("Name");
this.OnNameChanged();
}
}
}
In fact, the first thing that the generated class does is call a base class method called ValidateProperty which does the same thing as our previous example. Understanding how this really works is key to debugging odd scenarios (like a validation exception showing up for a conversion failure).
Trouble with the Code Generation
Most of us are not using POCO classes (yet) for our data containers, but are using ORM's to build our data layers for us. This was a problem for the Dynamic Data folks back a while and came up with the idea of Metadata Types. A metadata type is simply a way of specifying a candiate class. In fact RIA services does this for you (if you ask it nicely) but you can specify these yourself. The key is the MetadataType attribute which is useful to do in the partial class. For example for an Entity Framework type:
[MetadataType(typeof(Game.GameMetadata))]
public partial class Game
{
internal sealed class GameMetadata
{
// Metadata classes are not meant to be instantiated.
private GameMetadata()
{
}
public string Description;
public string Developer;
public EntityState EntityState;
public int GameID;
public Genre TheGenre;
public string ImageUrl;
[Required]
[StringLength(100)]
public string Name;
[Range(0d, 2000d)]
public Nullable Price;
public string Publisher;
public Rating TheRating;
public Nullable<DateTime> ReleaseDate;
}
}
This class is a place that the validation or dynamic data runtimes can look for the attributes. Note, that this example uses a nested type but it could be a completely separate type as well.
NOTE: This works with RIA Services great. But its a hack. To pretend its anything but a hack is deluding yourself. My opinion is that this sort of information that is view specific should probably be loosely coupled instead of tightly in the form of attributes. If we did this on POCO classes, we'd be forced to have the validation attributes exist as a reference in every place we need them.
Just RIA Services?
There are many organizations out there that aren't using RIA Services for their data access (and i'll blog soon about why RIA Services is just a solution, not *the* solution data access). But if you are already using ADO.NET Data Services or Web Services, hooking into the validation logic is difficult. Adding the attributes is difficult in Silverlight since the generated code doesn't have any place to hook up the attributes (and MetadataType isn't supported in Silverlight). In addition, the attributes are only part of the problem as you'd need to build in the ability to do the validation on the set/gets (which is possible with ADO.NET Data Services but impossible with today's Web Service proxies). So today, this is most easily accomplished using RIA services. But I don't believe that in the best interest of developers.
If you've followed this blog, you know that I love the idea of choice (e.g. my LINQ to Hibernate ADO.NET Data Example). So I want to be able to leverage the Validation logic no matter what what data access you're using. I have started a new project called Niagara that I hope will address some of these issues. See my blog post about it here:
http://wildermuth.com/2009/09/28/Introducing_Project_Niagara
If you've never had the chance to visit my sister site (http://www.silverlightdata.com), now's a good time. I've updated my examples there to include my MVVM, Prism and Declarative UI examples (to go with the skinning/switchable Astoria example). Take a look if you're doing Silverlight data-based applications.

I am happy to see that the Data Programming group at Microsoft have been hard at work as usual. They've just released their PHP toolkit for ADO.NET Data Services.
While I had no part in this effort, I was estastic to see they ported my XBox Games example to PHP for the demo of the toolkit. If you're using PHP and don't know much about ADO.NET Data Services, go grab the toolkit and take a look.

I've been running Windows 7 as my primary machine now for a couple of months (first the Beta and now the RC). I love the OS but there have been a couple of frameworks that didn't work right. The one that perplexes me the most is ADO.NET Data Services 1.5 CTP1.
When you are on a Windows 7 box, running the installer will complain about a problem and point you to the readme file.
The problem is that the "%ProgramFiles%/Reference Assemblies\Microsoft\Framework\v3.5" folder on Windows 7 is protected as a part of the operating system. Specifically only "Trusted Installer" has rights to update the files and the ADO.NET Data Services 1.5 installer doesn't have those rights so it doesn't update the crucial assembly. To address this, you have to take over ownership of the System.Data.Services.Design.dll assembly in that folder and give yourself full access to the file. If you're not familiar with how to do this, i'll cover it further down in the blog post.
Once you have ownership of the assembly, re-run the installer (choose Repair if you already installed once with the error). You will get the same error again, but this time it replaced the crucial file.
In order to use the new bits, there are some small hoops to jump through, but Mike Flasko explains these really well in a video on the Astoria Team blog:
http://blogs.msdn.com/astoriateam/archive/2009/03/16/ado-net-data-services-v1-5-ctp1-now-available-for-download.aspx
Changing Ownership/Permissions to the Assembly
For the uninitiated, taking ownership and assigning permissions can be done like so:
Open the "%PROGFILES%/Reference Assemblies\Microsoft\Framework\v3.5" folder and find the assembly:

Next, right-click the assembly and pick Properties to show the property window for the assembly. On the Security tab, click on the "Advanced" button near the bottom:

Next, select the "Owner" tab and click on the "Edit" button:

Next pick a new owner (probably your user name or your machine's Administrator group) and press OK:

Close all the dialogs and return to the Explorer window again (changing owner requries you re-open the property window). Right-click the assembly again and pick "Properties. In the Security Tab, click the "Edit" button to change permissions for you user name (or group):

Lastly, in the Permissions dialog, click the "Full control" checkbox to give you full control of the assembly.

You've now got the full permissions requried.
I had a great time at the SQL Saturday in Atlanta today. I did two talks: Using MSchema and ADO.NET Data Services for DBAs. If you were there, thanks for attending. If you wanted to grab the code and slides, follow the link above!

Here at MIX09, the world got its first view of what Microsoft calls RIA Services. RIA Services is an n-tier solution that supports a variety of scenarios, but in my opinion may be especially important to Silverlight applications.
I've had the priviledge to watch RIA Services during its development over the last few months. Out of this effort comes some of the newest Silverlight Toolkit controls (including ChildWindow, Navigation controls, DataPager, DataForm) as well as the server pieces.
The general idea is that RIA Services will layer over the data access layer to provide additional services including validation as shown in this picture:

Brad Abrams has a great post describing the layer if you haven't taken a look at it yet:
http://blogs.msdn.com/brada/archive/2009/03/19/what-is-net-ria-services.aspx
I am not sure Brad mentions this, but it is very early in the development (e.g. its not a Silverlight 3 feature) and they'd love your feedback.
As some others (Barry Gervin in particular), I have had some concerns that only now I could talk about (though I've shared them with the team for a while now). My two biggest concerns:
- The feature uses quite a bit of Visual Studio magic to build the client-side part of the code as the server-side is changed. This is concerning because is assumes that most applicaitons are all in a single solution file and tightly couples projects together which doesn't work in a number of important scenarios.
- Concerned about inventing a new layer instead of using something established (like ADO.NET Data Services).
I had a great conversation with Brad Abrams at MIX09 today and he gave me the confidence to tell you that he's assured me that these two issues will be address. In particular he assured me that:
- While the Visual Studio magic is likely to remain, we will be able to decouple projects and "Add Service Reference" to a non-solution RIA Service which resolves my concern. I don't mind that the magic is default behavior, as long as decoupling works.
- They are aligning with ADO.NET Data Services to make RIA Services become a thin layer over ADO.NET Data Services to provide the type of metadata that is required to do the RIA Services work to the client.
While neither of these are in the current bits, I've been promised they'll arrive by release. I trust Brad's word on these. I hope when my life calms down a little (updating a lot of classes, writing articles and too much travel) that I can do a proper walkthrough of RIA Services for my readers.
What do you think?

Mike Flasko just posted that the first CTP is now available for the new ADO.NET Data Service 1.5. If you don't remember what the changes are, take a look at my recent post here:
http://wildermuth.com/2009/03/01/ADO_NET_Data_Services_1_5_Coming!
You can get the bits by clicking here.