Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Azure

Joining dynamic and infrequently changing data together

3/18/2011 10:11:03 PM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
1. Duplicating data instead of joining

Because the shirt data isn’t static data but is infrequently changing data, you need to find a different way of associating that data with the dynamic shopping cart item. For this example, you can duplicate the shirt data within the shopping cart item, as shown here:

public class ShoppingCartItem : TableServiceEntity
{
public string ShirtName { get; set; }
public string ShirtDescription { get; set; }
public int Price { get; set; }
public Material Material { get; set; }
public SizeType Size { get; set; }
}

The preceding code stores a complete copy of the selected shirt as part of the shopping cart item’s entity.

Note

This approach will mean that we won’t need to perform a join with the Shirts table, but it does mean that our table will be much larger than a traditional relational table, meaning higher storage costs.


Now that you have your shopping cart item, you need to correctly display your StrongShoppingCartItem object. The following code shows how you could modify the earlier query to do this.

select new StrongShoppingCartItem
{
SelectedShirt = new Shirt {PartitionKey="Shirts",
RowKey=shoppingCartItem.ShirtName,
Description=shoppingCartItem.ShirtDescription,
Price=shoppingCartItem.Price},
Material = material,
Size = sizeType
};

As you can see from the preceding code, you can project the duplicate data into the StrongShoppingCartItem object by instantiating a new Shirt object with the data from the ShoppingCartItem.

Data synchronization

Apart from it taking up more space, another issue with duplicating data is data synchronization.

Although the shirt data is infrequently changed, when a change does occur (such as the price), all items that are present in a customer’s shopping basket won’t be automatically updated with the new price. If your business model allows you to have stale data, this is obviously not a problem. But if your pesky customers want the correct price to be reflected in the shopping basket, you’ll need some method of synchronizing the master table to all the duplicates.

A simple method of keeping the data synchronized is to publish a message to a queue, stating that an item has changed. Then you can have a worker role pick up that message and update all items in the table with the correct data.


2. Client-side joining of uncached data

If data synchronization is a big concern and your dynamic data is a very small set of data, you could take the hit of performing a client-side join. To do that, you’d need to modify the ShoppingCartItem to support the join:

public class ShoppingCartItem : TableServiceEntity
{
public Shirt Shirt {get;set;}
public Material Material { get; set; }
public SizeType Size { get; set; }
}

In the preceding code, the duplicate shirt properties have been replaced with a reference to the shirt.

Now that the entity stores a reference, you need to modify your query to join the data together. The following code shows how you could do this:

var materials = (IEnumerable<Material>)Cache["materials"];
var sizeTypes = (IEnumerable<SizeType>)Cache["sizeTypes"];

var shoppingCartItemContext = new ShoppingCartItemContext ();
var shoppingCartItems =
shoppingCartItemContext.ShoppingCartItem.ToList();

var shirtsContext = new ShirtContext();

var q = from shoppingCartItem in shoppingCartItems
join sizeType in sizeTypes
on shoppingCartItem.Size.RowKey equals sizeType.RowKey
join material in materials
on shoppingCartItem.Material.RowKey equals material.RowKey
select new ShoppingCartItem
{
SelectedShirt = (from shirt in shirtsContext.ShirtTable
where shirt.PartitionKey=="Shirts" &&
shirt.RowKey ==
shoppingCartItem
.SelectedShirt.RowKey
select shirt).First(),
Material = material,
Size = sizeType
};

The key thing to note about the preceding example is that the shirt query isn’t cached, and it will invoke a call to the Table service for each item returned. The following extract shows where this is performed:
SelectedShirt = (from shirt in shirtsContext.ShirtTable
where shirt.PartitionKey=="Shirts" &&
shirt.RowKey == shoppingCartItem.SelectedShirt.RowKey
select shirt).First(),

Because the data returned from the shopping cart is small, this is a pretty useful technique. If you were dealing with a much larger set of shopping cart data (such as hundreds of items), this would start to perform badly.

Tip

If you’re working with infrequently changing data (such as the shirt data), you may wish to consider using SQLite to host a local cached version of your data. This would allow you to perform SQL queries on local cached data without calling out to the Table service or SQL Azure.


Not having the ability to join data across tables does present challenges, but not always impossible ones. For the most part, you can use different techniques to get around those limitations. But in some circumstances it’s going to be impossible to use the Table service. If you have lots of dynamic data and need to perform live queries across various table joins, you’re not going to be able to represent that easily in the Table service. In these instances, SQL Azure is the most appropriate choice. Similarly, if you need to perform transactions across various tables, SQL Azure is again the right choice.

Lucene.NET

If you’re storing your data in SQL Azure or the Table service and you need to perform text searches, you can export your data out of these databases and perform searches with Lucene.NET: http://lucene.apache.org/lucene.net/.


Other -----------------
- Enterprise Service Bus with BizTalk Server and Windows Azure : Mapping the Microsoft Platform to the Enterprise Service Bus Pattern
- Enterprise Service Bus with BizTalk Server and Windows Azure : Governance Considerations
- Enterprise Service Bus with BizTalk Server and Windows Azure : Cloud-Enabling the ESB with Windows Azure
- Working with the Table service REST API : Querying data (part 3) - Filtering data with LINQ & Selecting data using the LINQ syntax
- Working with the Table service REST API : Querying data (part 2) - Querying with LINQ & Filtering data with the REST API
- Working with the Table service REST API : Querying data (part 1) - Retrieving all entities in a table using the REST API
- Working with the Table service REST API - Batching data
- Modifying entities with the REST API is CRUD (part 3) - Updating entities
- Modifying entities with the REST API is CRUD (part 2) - Deleting entities
- Modifying entities with the REST API is CRUD (part 1) - Inserting entities
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server