Home > English > Getting empty string default constraints to work in WCF RIA Services through a Fluent API

Getting empty string default constraints to work in WCF RIA Services through a Fluent API

This post is based on the excellent post by Nikhil Kothari. You should read his blog post before you continue as all I am going to introduce to how I was able to port his code to .NET 4.0 and get the Fluent API working.

First of all, let’s take a look at my file structure:

Entity Framework/RIA Services file structure

One of the issues that I have with WCF RIA Services is the whole workflow that is involved when anything changes in the data model:

  1. Exclude my partial Domain Service files.

    Fluent RIA Services - Exclude partial files

  2. Delete my Domain Service files.
  3. Open my Entity Framework (.edmx) file in the visual designer.
  4. Delete any of the model objects that have been changed. (I have found that I need to delete since Visual Studio doesn’t really serialize the changes from the database correctly.
  5. From the context menu, click on Update Model from Database…

    Fluent RIA Services - Update Model from Database

  6. Select the model objects that have changed.
  7. Build the project.
  8. Add a Domain Service.
  9. Add the partial keyword “partial” to the DomainService class.

    Fluent RIA Services - partial keyword to DomainService class

  10. Include your custom partial files in the project.

    Fluent RIA Services - Include partial files

  11. Add all of your [Include()] statements back to the .metadata file. (I have another blog post for this that get’s this to work.)
  12. Build your project.

Clearly this is a very intensively workflow and it is very easy to screw things up and your application will stop working as before. The problem I have with WCF RIA Services is that it doesn’t support or enforce default values from the database or check constraints on the client.

The use case that I am trying demonstrate is if you have a column in a table that is set as non-null but has a default value of empty string. I have a client that uses this as a standard in their database model and it becomes painful for us to get this to work. As you can see from the above workflow is that the DomainService is deleted and recreated. I have moved a lot of my custom .metadata logic to my partial file. Let’s take a look at what is required to allow empty string for a Required attribute using a slight port to Nikhil Kothari’s implementation:

public MemberValidationMetadata Required()
{
	return Required(null);
}

public MemberValidationMetadata Required(bool allowEmptyStrings)
{
	AddMetadata(new RequiredAttribute() { AllowEmptyStrings = allowEmptyStrings });
	return this;
}

This code snippet comes from the MemberValidationMetadata.cs file. It basically is an overload from the default Required() method and provides support for passing in a boolean to determine if AllowEmptyStrings is true or false.

public class rv_sbt_SiteBillTypeMetadata : MetadataClass
{
	public rv_sbt_SiteBillTypeMetadata()
	{
		this.Validation(p => p.rv_sbt_BillTypeDefinition).Required(true);
		this.Validation(p => p.rv_sbt_BillTypeDescription).Required(true);
		this.Validation(p => p.rv_sbt_BillTypeLongDescription).Required(true);
		this.Validation(p => p.rv_sbt_BillTypeName).Required(true);
		this.Validation(p => p.rv_sbt_CreatedBy).Required(true);
		this.Validation(p => p.rv_sbt_CustomerValue).Required(true);
		this.Validation(p => p.rv_sbt_ModifiedBy).Required(true);

		this.Projection(p => p.rs_sdf_SiteDocumentFormat).Include();
		this.Projection(p => p.rv_al_AccountingLink).Include();
		this.Projection(p => p.rv_obt_OrganizationBillType).Include();
		this.Projection(p => p.rv_sbtd_SiteBillTypeDetail).Include();
		this.Projection(p => p.rv_sis_SiteInstalledSubsystem).Include();
		this.Projection(p => p.rv_urbt_UserReportBillType).Include();
		this.Projection(p => p.rv_xrf_ReturnFrequency).Include();
	}
};

As you can see, I am using the overload Required method and it allows me to now support the empty string default constraint from the database. It is also possible to do this in the .metadata.cs file that is created when you create a new DomainService but I find that I prefer the Fluent API. The cool thing about this approach is that you can have both the Fluent API as well as what you get from the DomainService .metadata.cs file. The datamodel is rather large and I only add the table objects to the partial file (.metadata.partial.cs) and comment out the same definition in the .metadata.cs file shown below:

Fluent RIA Services - Comment out existing definition

Data access is still a very painful workflow for Silverlight development. I try to use metadata from a database as much as possible and this really is a good candidate for doing some code generation with T4. I do wish that we had the capability to have check contraints executed on the client without needing to write custom code but so far this doesn’t seem to work very well. I would also like to see a better alternative to forcing us to use the designer for the Entity Framework model as the only way to update and modify your model.

Perhaps an ability to code closer to what WebMatrix with Razor. That would be an awesome combination for us Silverlight developers.

Once again, thanks for reading….

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: