Mixing Table Per Type and Table Per Hierarchy Inheritance

Posted by Matt | Filed under , , , , , ,

When working in Silverlight RIA applications, there are some common scenarios that are useful:

  • Table Per Type inheritance – Useful when you have one table that “extends” another table with additional data.  Your main table would be a common “type” and you’d have one (or more) tables which add more data.  More information
  • Table Per Hierarchy inheritance – Useful when you have one table that has many “types” inside it with some data useful depending on the “type”.  Usually, one column in your table would denote the “type” of data, and from there, your application would read additional columns.  These additional columns often would be unused if a row’s “type” was not of a particular value.  More Information
  • Table Per Concrete Type inheritance – Useful when you want to have a “history” table in addition to the “current” data.  More Information

All 3 of these are useful in their own times.  But what if you needed to mix types?

Here is a particular database scenario which I believe to be quite common:

image


In this setup, we have a database representing an online store.  One table lists all the products.  Some products are shirts, other products are shoes.  Two additional tables exist to provide additional data depending on the product type (similar to Table Per Type).  However, we have a discriminator (ProductType) to determine the product type (similar to Table Per Hierarchy).  In our case, if ProductType == 1, then there’s a Shirt record corresponding to the Product record.

For lack of a better name, I’m calling this Table Per Type Hierarchy inheritance.

By default, entity framework would generate the following:

image

 

This would work, however, there are 3 side-effects to this:

  1. Product has a navigation member called “Shirt”.  This means “Product has a Shirt”.  Likewise, “Shirt has a Product” since Shirt has a navigation member called “Product”.  In reality, “Shirt is a Product”.   This is “unnatural”.
  2. If I wanted to query all the Products which are Shirts, then I’d have to query “where ProductType == 1”.
  3. There are no safeguards to ensure that “if ProductType == 1 then a Shirt record exists”.

Instead, we want to setup a conditional hierarchy.  At first, you may think that we can just use Table Per Hierarchy to create a hierarchy between Shirts and Products and Shoes and Products, then add a conditional for Shirt “where ProductType = 1”.  However, this is not the case.  The entity framework user interface does not allow you to select a member from Product as a condition for Shirt.  Maybe this is a bug.  Maybe you can do this by editing the Xml.  To get this to work, you need to add a proxy entity between Product and Shirt.

Step 1.  Start with your default entity framework setup.

image[8]

 


Step 2.  Remove the 2 associations that were generated.  Click each and delete.

image

 


Step 3.  Remove the ProductType member from Product.

Step 4.  Make Product abstract.

image

Step 5.  This step is exactly as is done for normal Table Per Hierarchy inheritance.  Create a new entity and call it “ShirtProduct”.  Derive this new entity from Product.  Map the new entity to the Products table.  In the mapping, add a condition such that ProductType = 1.  But don’t move any properties from Product to ShirtProduct.

Step 6.  This step is just like normal Table Per Type inheritance.  Derive Shirt from ShirtProduct. 

image

Remove ProductId from Shirt since we already have it in Product.  Once we’ve done that, our entity model should look like this:

image

 

 

Step 7.  Repeat steps 5 and 6 for Shoe, but set it’s condition to “ProductType = 2”.  Our model now looks like:

image

The blue rectangle represents the portion using Table Per Hierarchy inheritance.  The red rectangle represents the portion using Table Per Type inheritance.

If we had any products which did not require extra data in secondary tables, we could just use Table Per Hierarchy inheritance.  For example, if we had a third product type called “Pants”, then we could create a new entity called “Pants” (not “PantsProduct”), derive it from Product and set it’s condition to be ProductType = 3.  In this case, the proxy class is the working class.

To access the classes, we do so just like Table Per Type.  The example code shows ‘get’ functions for a DomainContext in a Silverlight RIA appliication:

public IQueryable<Shirt> GetShirts()
{
	return this.ObjectContext.Products.OfType<Shirt>();
}

public IQueryable<Shoe> GetShoes()
{
	return this.ObjectContext.Products.OfType<Shoe>();
}

When I generated my DomainContext, I chose to retrieve and update the ProductTable.  So my DomainContext already had GetProducts() and InsertProduct().  This means:

  1. I can use GetProducts() to get a list of all products, and
  2. I can insert a product of any type by calling InsertProduct()

Actually, for a Silverlight RIA application, you may choose to not call InsertProduct() directly.  Instead, you can use the following code:

Shirt shirt = new Shirt();
shirt.ProductId = Guid.NewGuid();
shirt.Title = "Red Polo";
shirt.Price = new Decimal(11.99);
shirt.Colour = "Red";
shirt.Style = "Polo";

ProductDomainContext context = 
   (ProductDomainContext)domainDataSource1.DomainContext;
context.Products.Add(shirt);
context.SubmitChanges();

 

Notice 2 things:

  1. I am using the normal entity framework model to insert a Shirt into the list of Products.
  2. I am not setting Product.ProductType anywhere.

The entity framework takes care of inserting the correct data into the Shirts table, the correct data into the Products table, and setting ProductType = 1 properly.

Magical!

Included is a sample Silverlight RIA application that demonstrates this.  It includes a list of all products, a list of shirts, and a list of shoes.  It also inserts a new shirt into the database.

TPTHSample.zip (4.58 MB)

I’d like to thank Lingzhi Sun over on the MSDN Forums for help in this matter.

Three Ways to SQL

Posted by Matt | Filed under , , , ,

In the colourful land of .NET, the database gods have bestowed upon us lowly peasants (atleast) 3 ways to access ye olde SQL databases.  Each has their pros and their cons.   Some more so than others.  Below are some of those options.  As a developer, it is up to you to choose which is right for (a) you, and (b) your situation.

1. DataSource, DataTable, DataProvider, and the visual editor

Microsoft used to promote this quite a bit.  It’s the primary means to access SQL databases from some of the out-of-the-box .NET controls (for both ASP.NET and Windows Forms).  Using this method, you drag database objects onto your forms and configure them using the visual SQL editor.  As I understand it, this is very good for RAD (Rapid Application Development) developers.  However, for me, it’s quite slow to use because of the visual editing elements.

2. SQLConnection and SQLCommand classes

This used to be my favourite way to work with SQL databases.  Not being a fan of the DataSource classes, I found it easier to use the SQLConnection and SQLCommand classes directly.  I also felt that I had more control over the commands and the data.  Using this method, I was able to setup my own connections and do my own calls without needing to hide behind a data abstraction.  The only problem with this was that there was alot of repeated code.  Often, I’d just have to copy and paste an existing connection and change a couple of lines here or there.  It was different enough that I couldn’t make a general purpose handler though.  But I had my control.  And that’s how the SQL world was to me until…

3.  LINQ to SQL

In my opinion, this is the database gods’ gift to mankind.  Using LINQ to SQL, I can use a visual editor to define the relationships between my SQL tables (notice that I’m back on the visual editor bandwagon).  Afterwards, I have a strongly-typed set of classes that I can use to access my data.  No more casting data out of the database classes. Instead, it’s already in the proper types.  No longer do I have to create SQL statements and be required to run my program to find out how incorrect the statement is.  LINQ to SQL is done natively in the programming language (C# for me), so incorrect syntax is caught by the compiler.  My latest project to access a database took me 2 hours to complete using LINQ.  If I had been using method #2, I think it would have taken me closer to a day, but it would have worked just as a well in the end.  LINQ let me complete the job faster.

In summary, LINQ to SQL == goodness.  Others are still good, just not as good (for me anyways).

Creating a Twitter Client in C#, Part 4

Posted by Matt | Filed under , , , ,

I wanted to post my “final” twitter client.  I fleshed out most of the API functions and added documentation comments. 

I’ve not tested it fully yet, but for the most part, it should work.  If you find any bugs, please let me know.

You can download it here:  InsiderCoding.Twitter.zip (12.04kb)

Creating a Twitter Client in C#, Part 3

Posted by Matt | Filed under , , , ,

In previous articles, Creating a Twitter Client in C# and Creating a Twitter Client in C#, Part 2, I showed you the basics of creating a Twitter client using C# and WCF.  We also saw problems with the Xml data and so we switched to the Json data format.

Today, we’ll continue and add another method call.  This call is one of the fundamental methods used in a Twitter Client:  Friends Timeline.

The Friends Timeline returns back an array of data.  This adds a bit of extra complication to the method.  The return value is an array of status objects.  For this, we’ll need to create two new data structures:  Status and Statuses.

[DataContract(Name = "status", Namespace = "")]
public class Status
{
  [DataMember(Name = "id")]
  public int Id { get; set; }

  [DataMember(Name = "text")]
  public string Text { get; set; }

  [DataMember(Name = "user")]
  public User User { get; set; }
}

[CollectionDataContract(Name = "statuses", 
  ItemName = "status", Namespace = "")]
public class Statuses : List<Status>
{
}

The Status class is set up very similar to the User class that we created last time.  We have Id and Text fields which are present in the resulting Json data.  Also, we’re including our previous User class since some user data is returned as well.  You could create another class (for example, BasicUser) since not all of the information is included here as was in the VerifyCredentials call.

The Statuses class is a bit different.  Since it’s a list, we need to declare it as a CollectionDataContract instead of just a simple DataContract.  Also, we’re defining the type of items in the collection with the ItemName parameter.

Next, we need to add our new function to the interface.

public interface ITwitterClient
{
  [OperationContract(Name = "FriendsTimeline")]
  [WebGet(UriTemplate = "statuses/friends_timeline.json",
    BodyStyle = WebMessageBodyStyle.Bare,
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json)]
  Statuses FriendsTimeline();
}

And to the client class.

public class TwitterClient
{
  public Statuses FriendsTimeline()
  {
    return base.Channel.FriendsTimeline();
  }
}

Now we can retrieve the timeline from the client.

User user = client.VerifyCredentials();
Statuses statuses = client.FriendsTimeline();

Creating a Twitter Client in C#, Part 2

Posted by Matt | Filed under , , , ,

In my previous article, Creating a Twitter Client in C#, I showed you the basics of creating a Twitter client using C# and WCF.

After doing some investigation, it turns out that for some reason, C# WCF does not want to correctly parse some of the Xml data returned. For example, if we add profile_image_url to the User class

class User
{
  [DataMember(Name = "profile_image_url")]
  public string ProfileImageUrl { get; set; }
}

and then call our VerifyCredentials method, the profile_image_url parameter always ends up null after it’s parsed from the Xml data.

However, if we switch from Xml to Json formatted data, these fields do correctly get parsed.  To do the switch, just change the following in our ITwitterClient interface

[OperationContract]
[WebGet(UriTemplate = "/account/verify_credentials.xml",
  BodyStyle = WebMessageBodyStyle.Bare,
  RequestFormat = WebMessageFormat.Xml,
  ResponseFormat = WebMessageFormat.Xml)]
User VerifyCredentials();

to

[OperationContract]
[WebGet(UriTemplate = "/account/verify_credentials.json",
  BodyStyle = WebMessageBodyStyle.Bare,
  RequestFormat = WebMessageFormat.Json,
  ResponseFormat = WebMessageFormat.Json)]
User VerifyCredentials();

Now it retrieves the data correctly.

From here on, we’ll be using the Json format instead of Xml for the client.

If anyone has any ideas on why it’s failing reading the Xml data, I’d be very interested in hearing them.

Creating a Twitter Client in C#

Posted by Matt | Filed under , , , ,

Twitter seems to be the app-du-jour these days.  Twitter is today’s Facebook.  Everyone seems to be on Twitter these days:  Global News with Leslie Roberts, Ellen DeGeneres, Britney Spears, and even MC Hammer.

If you’re going to create a Twitter client application, there are many wrapper classes already created for Twitter using C# and other languages.  However, if you’re interested in creating your own Twitter client (as I was), it’s very easy using the C# Web Services client model.

1.  Bookmark and refer to the Twitter API

The Twitter API reference can be found here.  Bookmark it and refer to it when adding your function calls.  This will be invaluable as you add methods to your client.

2.  Add a Twitter section to your app.config file

Add the following section to your app.config file. 

<system.serviceModel>
  <bindings>
    <webHttpBinding>
      <binding name="TwitterHttpBinding">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Basic" />
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="WebHttp">
        <webHttp />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <client>
    <endpoint
      address="http://www.twitter.com"
      binding="webHttpBinding"
      bindingConfiguration="TwitterHttpBinding"
      behaviorConfiguration="WebHttp"
      contract="TwitterClient1.ITwitterClient" />
  </client>
</system.serviceModel>

This will define the Web Service client for use with Twitter.  You may need to modify the contract= value to match your application.

3.  Add necessary references

Add references to the following namespaces in your project:

  • System.Runtime.Serialization
  • System.ServiceModel
  • System.ServiceModel.Web

4.  Create a Twitter interface

Create a new interface for your Twitter client.  To start, it can be as simple as a single command:

[ServiceContract]
public interface ITwitterClient
{
  [OperationContract]
  [WebGet(UriTemplate = "/account/verify_credentials.xml",
    BodyStyle = WebMessageBodyStyle.Bare,
    RequestFormat = WebMessageFormat.Xml,
    ResponseFormat = WebMessageFormat.Xml)]
  User VerifyCredentials();
}

Here, we’re defining a call to the verify credentials command, and we’re using the Xml versions of the functions.  The ServiceContract attribute tells the compiler that the interface is for a web service client.  The UriTemplate parameter is the URL to the command relative to twitter.com (defined in the app.config file).  The OperationContract attribute tells the compiler that the function is for a web service function call.  The WebGet attribute tells the compiler that the function uses the standard http Get method for accessing the interface.

You’ll notice the use of a class called “User”.  That will be described in the next section.

5.  Create additional classes

In section 4, we used a class called “User”.  The verify credentials Twitter command returns data like the following:

<user>
  <id>12345</id>
  <name>Matt</name>
  <screen_name>Matt</screen_name>
  <!-- More Data -->
</user>

For this, we can take advantage of C# Xml automatic deserialization.  As I mentioned before, this is one of my favourite features of C#.  In this case, I created a class called “User”:

[DataContract(Name = "user", Namespace = "")]
public class User
{
  [DataMember(Name = "id")]
  public int Id { get; set; }

  [DataMember(Name = "name")]
  public string Name { get; set; }

  [DataMember(Name = "screen_name")]
  public string ScreenName { get; set; }
}

You’ll notice a correspondence between the members of my class and the contents of the Xml response.  C# will automatically deserialize the retrieved data into available classes where possible.

6.  Create your client class

Now you need to create your client class.  For this, we derive a class from ClientBase<> and our Twitter interface and then implement the functions required for the interface.  For each function, we can just call the same function on the channel.

public class TwitterClient : 
  ClientBase<ITwitterClient>, 
  ITwitterClient
{
  #region ITwitterClient Members

  public User VerifyCredentials()
  {
    return base.Channel.VerifyCredentials();
  }

  #endregion
}

The last thing we need to do is setup authentication against Twitter. 

7.  Authenticate your client class

Twitter allows for basic web http authentication.  We’ve already setup the client endpoint for this in our app.config file.  Now, we need to fill in the username and password.  This is easy in a constructor to our client:

public class TwitterClient
{
  public TwitterClient(string sUsername, string sPassword)
  {
    /*this.*/ClientCredentials.UserName.UserName = sUsername;
    /*this.*/ClientCredentials.UserName.Password = sPassword;
  }
}

8.  Use your class

Now you can use the client in your application:

TwitterClient client = new TwitterClient("login", "password");
User user = client.VerifyCredentials();

Now all you need to do is to add the other methods that you require from Twitter.

Binding to Settings in WPF

Posted by Matt | Filed under , , ,

I just wanted to forward on a blog post that I found useful.  I was implementing a textbox whereby a user can edit an application setting.  My old way of thinking was to manually marshal the data from the setting to the control, and back again when the user clicks “Ok”.

However, this is not the “WPF Way”.

Patrick Danino explains a way to hook your text control to application settings using WPF data binding.  This produces much less code than having to marshal the data manually.

Well done Patrick!

Silverlight 3 Beta is Available

Posted by Matt | Filed under , ,

A Beta for Silverlight 3 is now available for download.  Amongst some other changes, it adds support for rich business applications but also “out-of-browser” support.  Very interesting.  I will definitely be wanting to play with this one.

Also, Channel9 has a video discussing some of the significant changes in Silverlight 3.

The Windows Presentation Foundation SDK blog also has an announcement with some additional information.

A Faster Way to Include a Value Converter

Posted by Matt | Filed under , ,

Over at Ask Dr. WPF, they’ve demonstrated a way to use a value converter with less Xaml markup code.  It involves more C# code, but if you’re going to be using the value converter often in the markup, it’s a worthwhile strategy.  If you just use the converter once, then the extra C# code may not be worth the trouble.

Silverlight 3.0 for Business Apps?

Posted by Matt | Filed under , , , ,

Silverlight 2.0 brought the ease of .NET programming to web browser based applications.  No more do you need to fidget with javascript.  Instead, you’re able to develop your application using C#.  I loved this when it was released.  Most of the demos for Silverlight 2 that were created were very graphical and multimedia based.  It seemed that Microsoft wanted to really showcase how slick you can make your Silverlight applications.  That’s great for marketing and gimmicky types of applications, what what about business application developers?  What they really need is enhanced tools and frameworks for their “n-tier” systems.  How can we work with data easily?  How can we make network communication more efficient?

Silverlight 3.0 is going to help with this. 

In this video, Brad Abrams demonstrates some of the new features in Silverlight 3.0 that will help the business application developers get more out of their applications.  It’s a good watch.

Similarly, the very next day, IdeaBlade's Ward Bell demonstrates their own toolkit for helping business application developers create great and efficient Silverlight applications.

I think Silverlight is getting alot more interesting for business developers.